<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css"
        integrity="sha512-SzlrxWUlpfuzQ+pcUCosxcglQRNAq/DZjVsC0lE40xsADsfeQoEypE+enwcOiGjk/bSuGGKHEyjSoQ1zVisanQ=="
        crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
</html>
3
Yj=V                @   s   d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	m
Z
mZmZmZmZ d dlmZmZmZmZmZmZmZmZmZmZmZ d dlmZ d dlmZ d dlm Z  d dl!m"Z" d d	l#m$Z$ G d
d de%Z&dS )    N)log)
portStrcheckIPnMaskcheckIP6nMaskcheckProtocolenable_ip_forwardingcheck_single_addressportInPortRangeget_nf_conntrack_short_namecoalescePortRangebreakPortRange)	Rich_RuleRich_AcceptRich_Service	Rich_PortRich_ProtocolRich_MasqueradeRich_ForwardPortRich_SourcePortRich_IcmpBlockRich_IcmpType	Rich_Mark)FirewallTransaction)errors)FirewallError)LastUpdatedOrderedDict)SOURCE_IPSET_TYPESc               @   s  e Z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dZdd Zdd Zdd Zdd d!Zdd"d#Zdd$d%Zd&d' Zd(d) Zd*d+ Zd,d- Zdd0d1Zd2d3 Zdd4d5Zd6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Z dd@dAZ!dBdC Z"ddDdEZ#dFdG Z$dHdI Z%dJdK Z&dLdM Z'dNdO Z(dPdQ Z)dRdS Z*ddTdUZ+dVdW Z,ddXdYZ-dZd[ Z.d\d] Z/d^d_ Z0d`da Z1dbdc Z2ddddeZ3dfdg Z4ddhdiZ5djdk Z6dldm Z7dndo Z8dpdq Z9drds Z:dtdu Z;dvdw Z<ddxdyZ=dzd{ Z>dd|d}Z?d~d Z@dd ZAdd ZBdd ZCdd ZDdddZEdd ZFdddZGdd ZHdd ZIdd ZJdd ZKdddZLdd ZMdddZNdd ZOdd ZPdd ZQdd ZRdddZSdd ZTdddZUdd ZVdd ZWdddZXd ddZYd!ddZZdd Z[d"ddZ\dd Z]d#ddZ^dd Z_dd Z`dd Zad$ddÄZbddń Zcd%ddǄZdddɄ Zedd˄ Zfdd̈́ Zgddτ Zhd&ddфZiddӄ ZjddՄ Zkd'ddׄZlddل Zmddۄ Zndd݄ Zodd߄ Zpdd Zqdd Zrdd Zsdd Ztdd Zud(ddZvd)ddZwdd Zxdd Zydd Zzdd Z{d*ddZ|dd Z}dd Z~dd Zdd Zd d Zdd Zdd Zdd Zd+d	d
ZdS (,  FirewallPolicyc             C   s   || _ i | _i | _d S )N)_fw_chains	_policies)selffw r#   /usr/lib/python3.6/fw_policy.py__init__   s    zFirewallPolicy.__init__c             C   s   d| j | j| jf S )Nz
%s(%r, %r))	__class__r   r    )r!   r#   r#   r$   __repr__   s    zFirewallPolicy.__repr__c             C   s   | j j  | jj  d S )N)r   clearr    )r!   r#   r#   r$   cleanup   s    
zFirewallPolicy.cleanupc             C   s
   t | jS )N)r   r   )r!   r#   r#   r$   new_transaction$   s    zFirewallPolicy.new_transactionc             C   s   t | jj S )N)sortedr    keys)r!   r#   r#   r$   get_policies)   s    zFirewallPolicy.get_policiesc             C   s8   g }x*| j  D ]}| j|}|js|j| qW t|S )N)r-   
get_policyderived_from_zoneappendr+   )r!   Zpoliciespp_objr#   r#   r$   "get_policies_not_derived_from_zone,   s    
z1FirewallPolicy.get_policies_not_derived_from_zonec             C   s~   g }xt| j  D ]h}| j|}t|d t| jjj tddgB @ rt|d t| jjj tddgB @ r|j| qW |S )Ningress_zonesHOSTANYegress_zones)r3   get_settingssetr   zoneZget_active_zonesr0   )r!   Zactive_policiespolicysettingsr#   r#   r$   )get_active_policies_not_derived_from_zone4   s    
((z8FirewallPolicy.get_active_policies_not_derived_from_zonec             C   s   | j j|}| j| S )N)r   check_policyr    )r!   r;   r1   r#   r#   r$   r.   >   s    zFirewallPolicy.get_policyc             C   s,   dd dD |_ || j|j< | j|j d S )Nc             S   s   i | ]}t  |qS r#   )r   ).0xr#   r#   r$   
<dictcomp>C   s   z-FirewallPolicy.add_policy.<locals>.<dictcomp>servicesports
masqueradeforward_portssource_portsicmp_blocksrules	protocolsicmp_block_inversionr4   r7   )rB   rC   rD   rE   rF   rG   rH   rI   rJ   r4   r7   )r<   r    namecopy_permanent_to_runtime)r!   objr#   r#   r$   
add_policyB   s         
zFirewallPolicy.add_policyc             C   s0   | j | }|jr| j| |jj  | j |= d S )N)r    appliedunapply_policy_settingsr<   r(   )r!   r;   rM   r#   r#   r$   remove_policyN   s
    


zFirewallPolicy.remove_policyc             C   s  | j | }|jrd S x|jD ]}| j||dd qW x|jD ]}| j||dd q<W x|jD ]}| j|| q\W x|jD ]}| j	|f|  qxW x|j
D ]}| j|| qW xf|jD ]\}y| j|f|  W q tk
r } z$|jtjgkrtj| n|W Y d d }~X qX qW x|jD ]}| j|| qW xj|jD ]`}y| j|f|  W nD tk
r } z&|jtjgkrtj| n|W Y d d }~X nX q:W x|jD ]}| j|| qW |jr| j| d S )NF)allow_apply)r    rO   r4   add_ingress_zoner7   add_egress_zonerG   add_icmp_blockrE   add_forward_portrB   add_servicerC   add_portr   coder   ALREADY_ENABLEDr   warningrI   add_protocolrF   add_source_portrH   add_rulerD   add_masquerade)r!   r;   rM   argserrorr#   r#   r$   rL   U   sB    
z(FirewallPolicy.copy_permanent_to_runtimeNc             C   sN   xH| j  D ]<}| j| }|jr q
|| j kr
tjd| | j||d q
W d S )NzApplying policy '%s')use_transaction)r-   r    r/   r=   r   Zdebug1apply_policy_settings)r!   rb   r;   r2   r#   r#   r$   apply_policies|   s    
zFirewallPolicy.apply_policiesc             C   s   | j | }||_d S )N)r    rO   )r!   r;   rO   rM   r#   r#   r$   set_policy_applied   s    
z!FirewallPolicy.set_policy_appliedc             C   s   t j  ||d}|S )N)Zdatesendertimeout)time)r!   rg   rf   retr#   r#   r$   Z__gen_settings   s    zFirewallPolicy.__gen_settingsc             C   s   | j |jS )N)r.   r<   )r!   r;   r#   r#   r$   r8      s    zFirewallPolicy.get_settingsc             C   sj  | j j|}| j| }|r |js.| r2|j r2d S |r<d|_|d krN| j }n|}|rx8|jsh| j|n| j|D ]\}}| j|d||| qrW | j	|}	|js| j
||| xV|	D ]L}
xD|	|
 D ]6}|
dkr| j|||| q|
dkrqq|
dkr| j|||f|  q|
dkr0| j|||| q|
dkrV| j|||d |d | q|
d	krr| j|||| q|
d
kr| j|||d |d | q|
dkr| j||| q|
dkr| j||t|d| q|
dkrqq|
dkrqqtjd||
| qW qW |sRx<|js"| j|n| j|D ]\}}| j|d||| q,W d|_|d krf|j| d S )NTrG   rJ   rE   rB   rC   r      rI   rF   rD   rH   )rule_strr4   r7   z5Policy '%s': Unknown setting '%s:%s', unable to applyF)r   r>   r    rO   r*   r/   %_get_table_chains_for_policy_dispatch#_get_table_chains_for_zone_dispatchgen_chain_rulesr8   _ingress_egress_zones_icmp_block_forward_port_service_port	_protocol_source_port_masquerade_FirewallPolicy__ruler   r   r[   execute)r!   enabler;   rb   _policyrM   transactiontablechainr<   keyr`   r#   r#   r$   _policy_settings   sj    













zFirewallPolicy._policy_settingsc             C   s   | j d||d d S )NT)rb   )r   )r!   r;   rb   r#   r#   r$   rc      s    z$FirewallPolicy.apply_policy_settingsc             C   s   | j d||d d S )NF)rb   )r   )r!   r;   rb   r#   r#   r$   rP      s    z&FirewallPolicy.unapply_policy_settingsc             C   sr   | j |j }| j|| j|| j|| j|| j|| j|| j|| j	|| j
|| j|d
}| jj||S )zH
        :return: exported config updated with runtime settings
        )
rB   rC   rG   rD   rE   
rich_rulesrI   rF   r4   r7   )r.   Zexport_config_dictlist_services
list_portslist_icmp_blocksquery_masqueradelist_forward_ports
list_ruleslist_protocolslist_source_portslist_ingress_zoneslist_egress_zonesr   Z'combine_runtime_with_permanent_settings)r!   r;   Z	permanentZruntimer#   r#   r$   get_config_with_settings_dict   s    z,FirewallPolicy.get_config_with_settings_dictc                s  ddl m  d
 fdd	} fdd}jjfjjfjjfjj	fj
jf||fjjfjjfjjfjjfd
}j|}jj||\}}	xt|	D ]l}
t|	|
 trxV|	|
 D ]8}t|tr||
 d |f|  q||
 d || qW q||
 d | qW x|D ]}
t||
 trxn||
 D ]J}t|trv||
 d |f|d|d	 n||
 d ||d|d	 qFW n||
 d |d|d	 q(W d S )Nr   )r   c                s   j |  |dd|d d S )N)rk   r   )rg   rf   )r^   )r;   rk   rg   rf   )r   r!   r#   r$   add_rule_wrapper   s    zFFirewallPolicy.set_config_with_settings_dict.<locals>.add_rule_wrapperc                s   j |  |d d S )N)rk   )remove_rule)r;   rk   )r   r!   r#   r$   remove_rule_wrapper   s    zIFirewallPolicy.set_config_with_settings_dict.<locals>.remove_rule_wrapper)
rB   rC   rG   rD   rE   r   rI   rF   r4   r7   rj   )rg   rf   )r   N)firewall.core.richr   rW   remove_servicerX   remove_portrU   remove_icmp_blockr_   remove_masqueraderV   remove_forward_portr\   remove_protocolr]   remove_source_portrS   remove_ingress_zonerT   remove_egress_zoner   r   Zget_added_and_removed_settings
isinstancelisttuple)r!   r;   r<   rf   r   r   Zsetting_to_fnZold_settingsZadd_settingsZremove_settingsr~   r`   r#   )r   r!   r$   set_config_with_settings_dict   s:    











  z,FirewallPolicy.set_config_with_settings_dictc             C   s&   |st tj|dkr"| jj| d S )Nr5   r6   )r5   r6   )r   r   INVALID_ZONEr   
check_zone)r!   r:   r#   r#   r$   check_ingress_zone  s    
z!FirewallPolicy.check_ingress_zonec             C   s   | j | |S )N)r   )r!   r:   r#   r#   r$   Z__ingress_zone_id"  s    
z FirewallPolicy.__ingress_zone_idr   Tc             C   s  | j j|}| j j| | j j  | j| }| j|}	|	|jd krXttj	d||f d|jd ksd|jd ks|dkr|jd rttj
d|dkrd|jd krttj
d|d kr| j }
n|}
|rJ|jr| jd||
 | j||	|| |
j| j||	 |js:|| j krH| j||
d	 |
j| j|d n| jd
||
 n | j||	|| |
j| j||	 |d kr~|
jd
 d S )Nr4   z'%s' already in '%s'r6   r5   zI'ingress-zones' may only contain one of: many regular zones, ANY, or HOSTr7   zF'HOST' can only appear in either ingress or egress zones, but not bothF)rb   T)r6   r5   )r   r>   check_timeoutcheck_panicr     _FirewallPolicy__ingress_zone_idr<   r   r   rZ   r   r*   rO   ro   &_FirewallPolicy__register_ingress_zoneadd_fail(_FirewallPolicy__unregister_ingress_zoner=   rc   re   rx   )r!   r;   r:   rg   rf   rb   rR   rz   _objzone_idr{   r#   r#   r$   rS   &  s<    




zFirewallPolicy.add_ingress_zonec             C   s   | j |||jd |< d S )Nr4   )_FirewallPolicy__gen_settingsr<   )r!   r   r   rg   rf   r#   r#   r$   Z__register_ingress_zoneS  s    z&FirewallPolicy.__register_ingress_zonec             C   s   | j j|}| j j  | j| }| j|}||jd krLttjd||f |d kr^| j	 }n|}|j
rt|jd dkr| j|| n| jd|| | j|| |j| j||d d  || j kr| jd|| n|j| j|| |d kr|jd |S )Nr4   z'%s' not in '%s'rj   FT)r   r>   r   r    r   r<   r   r   NOT_ENABLEDr*   rO   lenrP   ro   r   r   r   r=   add_postrx   )r!   r;   r:   rb   rz   r   r   r{   r#   r#   r$   r   V  s,    




z"FirewallPolicy.remove_ingress_zonec             C   s   ||j d kr|j d |= d S )Nr4   )r<   )r!   r   r   r#   r#   r$   Z__unregister_ingress_zoney  s    z(FirewallPolicy.__unregister_ingress_zonec             C   s   | j || j|d kS )Nr4   )r   r8   )r!   r;   r:   r#   r#   r$   query_ingress_zone}  s    z!FirewallPolicy.query_ingress_zonec             C   s   t | j|d j S )Nr4   )r   r8   r,   )r!   r;   r#   r#   r$   r     s    z!FirewallPolicy.list_ingress_zonesc             C   s&   |st tj|dkr"| jj| d S )Nr5   r6   )r5   r6   )r   r   r   r   r   )r!   r:   r#   r#   r$   check_egress_zone  s    
z FirewallPolicy.check_egress_zonec             C   s   | j | |S )N)r   )r!   r:   r#   r#   r$   Z__egress_zone_id  s    
zFirewallPolicy.__egress_zone_idc             C   s  | j j|}| j j| | j j  | j| }| j|}	|	|jd krXttj	d||f d|jd ksd|jd ks|dkr|jd rttj
d|dkrd|jd krttj
d|d kr| j }
n|}
|rJ|jr| jd||
 | j||	|| |
j| j||	 |js:|| j krH| j||
d	 |
j| j|d n| jd
||
 n | j||	|| |
j| j||	 |d kr~|
jd
 d S )Nr7   z'%s' already in '%s'r6   r5   zH'egress-zones' may only contain one of: many regular zones, ANY, or HOSTr4   zF'HOST' can only appear in either ingress or egress zones, but not bothF)rb   T)r6   r5   )r   r>   r   r   r    _FirewallPolicy__egress_zone_idr<   r   r   rZ   r   r*   rO   ro   %_FirewallPolicy__register_egress_zoner   '_FirewallPolicy__unregister_egress_zoner=   rc   re   rx   )r!   r;   r:   rg   rf   rb   rR   rz   r   r   r{   r#   r#   r$   rT     s<    




zFirewallPolicy.add_egress_zonec             C   s   | j |||jd |< d S )Nr7   )r   r<   )r!   r   r   rg   rf   r#   r#   r$   Z__register_egress_zone  s    z%FirewallPolicy.__register_egress_zonec             C   s   | j j|}| j j  | j| }| j|}||jd krLttjd||f |d kr^| j	 }n|}|j
rt|jd dkr| j|| n| jd|| | j|| |j| j||d d  || j kr| jd|| n|j| j|| |d kr|jd |S )Nr7   z'%s' not in '%s'rj   FT)r   r>   r   r    r   r<   r   r   r   r*   rO   r   rP   ro   r   r   r   r=   r   rx   )r!   r;   r:   rb   rz   r   r   r{   r#   r#   r$   r     s,    




z!FirewallPolicy.remove_egress_zonec             C   s   ||j d kr|j d |= d S )Nr7   )r<   )r!   r   r   r#   r#   r$   Z__unregister_egress_zone  s    z'FirewallPolicy.__unregister_egress_zonec             C   s   | j || j|d kS )Nr7   )r   r8   )r!   r;   r:   r#   r#   r$   query_egress_zone  s    z FirewallPolicy.query_egress_zonec             C   s   t | j|d j S )Nr7   )r   r8   r,   )r!   r;   r#   r#   r$   r     s    z FirewallPolicy.list_egress_zonesc             C   s   |j   d S )N)Zcheck)r!   ruler#   r#   r$   
check_rule  s    zFirewallPolicy.check_rulec             C   s   | j | t|S )N)r   str)r!   r   r#   r#   r$   Z	__rule_id  s    
zFirewallPolicy.__rule_idc             C   sx   |sd S |j r,t|j rdS t|j rtdS nHt|dr@|jr@dS t|drt|jrt| j|j | j|j | j|jS d S )Nipv4ipv6mac ipset)	Zaddrr   r   hasattrr   r   _check_ipset_type_for_source_check_ipset_applied_ipset_family)r!   sourcer#   r#   r$   _rule_source_ipv  s    

zFirewallPolicy._rule_source_ipvc             C   s   | j |||| d S )N)_rule_prepare)r!   ry   r;   r   r{   r#   r#   r$   Z__rule  s    zFirewallPolicy.__rulec             C   sL  | j j|}| j j| | j j  | j| }| j|}||jd krh|jrP|jn|}	tt	j
d||	f |js|jrt|jtrd|jd krtt	jdd|jd krtt	jdx6|jd D ](}
|
dkrq| j jj|
rtt	jd	qW |jrt|jtrd|jd kr,|jjrtt	jd
nb|jd r|jjsNtt	jdx>|jd D ]0}
|
dkrlqZ| j jj|
rZtt	jdqZW |jrt|jtrx>|jd D ]0}
|
dkrq| j jj|
rtt	jdqW |d kr| j }n|}|jr| jd||| | j|||| |j| j|| |d krH|jd |S )NrH   z'%s' already in '%s'r5   r7   z.'masquerade' is invalid for egress zone 'HOST'r4   z/'masquerade' is invalid for ingress zone 'HOST'r6   zR'masquerade' cannot be used in a policy if an ingress zone has assigned interfaceszAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zonezS'forward-port' cannot be used in a policy if an egress zone has assigned interfaceszR'mark' action cannot be used in a policy if an egress zone has assigned interfacesT)r6   r5   )r   r>   r   r   r    _FirewallPolicy__rule_idr<   r/   r   r   rZ   elementr   r   r   r:   list_interfacesr   
to_addressINVALID_FORWARDactionr   r*   rO   rw   _FirewallPolicy__register_ruler    _FirewallPolicy__unregister_rulerx   )r!   r;   r   rg   rf   rb   rz   r   rule_id_namer:   r{   r#   r#   r$   r^   
  s`    










zFirewallPolicy.add_rulec             C   s   | j |||jd |< d S )NrH   )r   r<   )r!   r   r   rg   rf   r#   r#   r$   Z__register_ruleE  s    zFirewallPolicy.__register_rulec       	      C   s   | j j|}| j j  | j| }| j|}||jd kr\|jrD|jn|}ttj	d||f |d krn| j
 }n|}|jr| jd||| |j| j|| |d kr|jd |S )NrH   z'%s' not in '%s'FT)r   r>   r   r    r   r<   r/   r   r   r   r*   rO   rw   r   r   rx   )	r!   r;   r   rb   rz   r   r   r   r{   r#   r#   r$   r   I  s"    




zFirewallPolicy.remove_rulec             C   s   ||j d kr|j d |= d S )NrH   )r<   )r!   r   r   r#   r#   r$   Z__unregister_ruled  s    z FirewallPolicy.__unregister_rulec             C   s   | j || j|d kS )NrH   )r   r8   )r!   r;   r   r#   r#   r$   
query_ruleh  s    zFirewallPolicy.query_rulec             C   s   t | j|d j S )NrH   )r   r8   r,   )r!   r;   r#   r#   r$   r   k  s    zFirewallPolicy.list_rulesc             C   s   | j j| d S )N)r   check_service)r!   servicer#   r#   r$   r   p  s    zFirewallPolicy.check_servicec             C   s   | j | |S )N)r   )r!   r   r#   r#   r$   Z__service_ids  s    
zFirewallPolicy.__service_idc             C   s   | j j|}| j j| | j j  | j| }| j|}||jd krh|jrP|jn|}	tt	j
d||	f |d krz| j }
n|}
|jr| jd|||
 | j|||| |
j| j|| |d kr|
jd |S )NrB   z'%s' already in '%s'T)r   r>   r   r   r    _FirewallPolicy__service_idr<   r/   r   r   rZ   r*   rO   rr   !_FirewallPolicy__register_servicer   #_FirewallPolicy__unregister_servicerx   )r!   r;   r   rg   rf   rb   rz   r   
service_idr   r{   r#   r#   r$   rW   w  s&    




zFirewallPolicy.add_servicec             C   s   | j |||jd |< d S )NrB   )r   r<   )r!   r   r   rg   rf   r#   r#   r$   Z__register_service  s    z!FirewallPolicy.__register_servicec       	      C   s   | j j|}| j j  | j| }| j|}||jd kr\|jrD|jn|}ttj	d||f |d krn| j
 }n|}|jr| jd||| |j| j|| |d kr|jd |S )NrB   z'%s' not in '%s'FT)r   r>   r   r    r   r<   r/   r   r   r   r*   rO   rr   r   r   rx   )	r!   r;   r   rb   rz   r   r   r   r{   r#   r#   r$   r     s"    




zFirewallPolicy.remove_servicec             C   s   ||j d kr|j d |= d S )NrB   )r<   )r!   r   r   r#   r#   r$   Z__unregister_service  s    z#FirewallPolicy.__unregister_servicec             C   s   | j || j|d kS )NrB   )r   r8   )r!   r;   r   r#   r#   r$   query_service  s    zFirewallPolicy.query_servicec             C   s   | j |d j S )NrB   )r8   r,   )r!   r;   r#   r#   r$   r     s    zFirewallPolicy.list_servicesc             C   sT   g }xJ|D ]B}y| j jj|}W n  tk
r@   ttj|Y nX |j| q
W |S )N)r   helper
get_helperr   r   INVALID_HELPERr0   )r!   helpers_helpersr   _helperr#   r#   r$   get_helpers_for_service_helpers  s    
z.FirewallPolicy.get_helpers_for_service_helpersc             C   s   g }x|D ]}y| j jj|}W n  tk
r@   ttj|Y nX t|jdk rt|j	}y| j jj|}|j
| W q tk
r   |rtjd|  w
Y qX q
|j
| q
W |S )Nrj   zHelper '%s' is not available)r   r   r   r   r   r   r   rC   r
   moduler0   r   r[   )r!   modulesry   r   r   r   _module_short_namer   r#   r#   r$   get_helpers_for_service_modules  s"    


z.FirewallPolicy.get_helpers_for_service_modulesc             C   s   | j j| | j j| d S )N)r   
check_portcheck_tcpudp)r!   portprotocolr#   r#   r$   r     s    zFirewallPolicy.check_portc             C   s   | j || t|d|fS )N-)r   r   )r!   r   r   r#   r#   r$   Z	__port_id  s    zFirewallPolicy.__port_idc                s  | j j|}| j j| | j j  | j| }tt fdd|jd }	x@|	D ]8}
t||
d rN|j	rl|j	n|}t
tjd| |f qNW t|dd |	D \}}|d kr| j }n|}|jrx$|D ]}| jd|t|d	 | qW x$|D ]}| jd
|t|d	 | qW x:|D ]2}| j| }
| j||
|| |j| j||
 qW x*|D ]"}| j| }
|j| j||
 qNW |d kr|jd |S )Nc                s   | d  kS )Nrj   r#   )r@   )r   r#   r$   <lambda>  s    z)FirewallPolicy.add_port.<locals>.<lambda>rC   r   z'%s:%s' already in '%s'c             S   s   g | ]\}}|qS r#   r#   )r?   rs   rt   r#   r#   r$   
<listcomp>  s    z+FirewallPolicy.add_port.<locals>.<listcomp>Tr   F)r   r>   r   r   r    r   filterr<   r	   r/   r   r   rZ   r   r*   rO   rs   r   _FirewallPolicy__port_id_FirewallPolicy__register_portr    _FirewallPolicy__unregister_portr   rx   )r!   r;   r   r   rg   rf   rb   rz   r   existing_port_idsport_idr   added_rangesremoved_rangesr{   ranger#   )r   r$   rX     s:    









zFirewallPolicy.add_portc             C   s   | j |||jd |< d S )NrC   )r   r<   )r!   r   r   rg   rf   r#   r#   r$   Z__register_port  s    zFirewallPolicy.__register_portc                s  | j j|}| j j  | j| }tt fdd|jd }xB|D ]}t||d rBP qBW |jrf|jn|}	t	t
jd| |	f t|dd |D \}
}|d kr| j }n|}|jrx$|
D ]}| jd|t|d	 | qW x$|D ]}| jd
|t|d	 | qW x:|
D ]2}| j| }| j||dd  |j| j|| qW x*|D ]"}| j| }|j| j|| qDW |d kr~|jd |S )Nc                s   | d  kS )Nrj   r#   )r@   )r   r#   r$   r     s    z,FirewallPolicy.remove_port.<locals>.<lambda>rC   r   z'%s:%s' not in '%s'c             S   s   g | ]\}}|qS r#   r#   )r?   rs   rt   r#   r#   r$   r   #  s    z.FirewallPolicy.remove_port.<locals>.<listcomp>Tr   F)r   r>   r   r    r   r   r<   r	   r/   r   r   r   r   r*   rO   rs   r   r   r   r   r   r   rx   )r!   r;   r   r   rb   rz   r   r   r   r   r   r   r{   r   r#   )r   r$   r     s:    









zFirewallPolicy.remove_portc             C   s   ||j d kr|j d |= d S )NrC   )r<   )r!   r   r   r#   r#   r$   Z__unregister_port=  s    z FirewallPolicy.__unregister_portc             C   s6   x0| j |d D ]\}}t||r||krdS qW dS )NrC   TF)r8   r	   )r!   r;   r   r   rs   rt   r#   r#   r$   
query_portA  s    zFirewallPolicy.query_portc             C   s   t | j|d j S )NrC   )r   r8   r,   )r!   r;   r#   r#   r$   r   H  s    zFirewallPolicy.list_portsc             C   s   t |sttj|d S )N)r   r   r   ZINVALID_PROTOCOL)r!   r   r#   r#   r$   check_protocolM  s    zFirewallPolicy.check_protocolc             C   s   | j | |S )N)r   )r!   r   r#   r#   r$   Z__protocol_idQ  s    
zFirewallPolicy.__protocol_idc             C   s   | j j|}| j j| | j j  | j| }| j|}||jd krh|jrP|jn|}	tt	j
d||	f |d krz| j }
n|}
|jr| jd|||
 | j|||| |
j| j|| |d kr|
jd |S )NrI   z'%s' already in '%s'T)r   r>   r   r   r    _FirewallPolicy__protocol_idr<   r/   r   r   rZ   r*   rO   rt   "_FirewallPolicy__register_protocolr   $_FirewallPolicy__unregister_protocolrx   )r!   r;   r   rg   rf   rb   rz   r   protocol_idr   r{   r#   r#   r$   r\   U  s&    




zFirewallPolicy.add_protocolc             C   s   | j |||jd |< d S )NrI   )r   r<   )r!   r   r   rg   rf   r#   r#   r$   Z__register_protocolr  s    z"FirewallPolicy.__register_protocolc       	      C   s   | j j|}| j j  | j| }| j|}||jd kr\|jrD|jn|}ttj	d||f |d krn| j
 }n|}|jr| jd||| |j| j|| |d kr|jd |S )NrI   z'%s' not in '%s'FT)r   r>   r   r    r   r<   r/   r   r   r   r*   rO   rt   r   r   rx   )	r!   r;   r   rb   rz   r   r   r   r{   r#   r#   r$   r   v  s$    





zFirewallPolicy.remove_protocolc             C   s   ||j d kr|j d |= d S )NrI   )r<   )r!   r   r   r#   r#   r$   Z__unregister_protocol  s    z$FirewallPolicy.__unregister_protocolc             C   s   | j || j|d kS )NrI   )r   r8   )r!   r;   r   r#   r#   r$   query_protocol  s    zFirewallPolicy.query_protocolc             C   s   t | j|d j S )NrI   )r   r8   r,   )r!   r;   r#   r#   r$   r     s    zFirewallPolicy.list_protocolsc             C   s   | j || t|d|fS )Nr   )r   r   )r!   r   r   r#   r#   r$   Z__source_port_id  s    zFirewallPolicy.__source_port_idc                s  | j j|}| j j| | j j  | j| }tt fdd|jd }	x@|	D ]8}
t||
d rN|j	rl|j	n|}t
tjd| |f qNW t|dd |	D \}}|d kr| j }n|}|jrx$|D ]}| jd|t|d	 | qW x$|D ]}| jd
|t|d	 | qW x:|D ]2}| j| }
| j||
|| |j| j||
 qW x*|D ]"}| j| }
|j| j||
 qNW |d kr|jd |S )Nc                s   | d  kS )Nrj   r#   )r@   )r   r#   r$   r     s    z0FirewallPolicy.add_source_port.<locals>.<lambda>rF   r   z'%s:%s' already in '%s'c             S   s   g | ]\}}|qS r#   r#   )r?   rs   rt   r#   r#   r$   r     s    z2FirewallPolicy.add_source_port.<locals>.<listcomp>Tr   F)r   r>   r   r   r    r   r   r<   r	   r/   r   r   rZ   r   r*   rO   ru   r   _FirewallPolicy__source_port_id%_FirewallPolicy__register_source_portr   '_FirewallPolicy__unregister_source_portr   rx   )r!   r;   r   r   rg   rf   rb   rz   r   r   r   r   r   r   r{   r   r#   )r   r$   r]     s:    









zFirewallPolicy.add_source_portc             C   s   | j |||jd |< d S )NrF   )r   r<   )r!   r   r   rg   rf   r#   r#   r$   Z__register_source_port  s    z%FirewallPolicy.__register_source_portc                s  | j j|}| j j  | j| }tt fdd|jd }xB|D ]}t||d rBP qBW |jrf|jn|}	t	t
jd| |	f t|dd |D \}
}|d kr| j }n|}|jrx$|
D ]}| jd|t|d	 | qW x$|D ]}| jd
|t|d	 | qW x:|
D ]2}| j| }| j||dd  |j| j|| qW x*|D ]"}| j| }|j| j|| qDW |d kr~|jd |S )Nc                s   | d  kS )Nrj   r#   )r@   )r   r#   r$   r     s    z3FirewallPolicy.remove_source_port.<locals>.<lambda>rF   r   z'%s:%s' not in '%s'c             S   s   g | ]\}}|qS r#   r#   )r?   rs   rt   r#   r#   r$   r     s    z5FirewallPolicy.remove_source_port.<locals>.<listcomp>Tr   F)r   r>   r   r    r   r   r<   r	   r/   r   r   r   r   r*   rO   ru   r   r   r   r   r   r   rx   )r!   r;   r   r   rb   rz   r   r   r   r   r   r   r{   r   r#   )r   r$   r     s:    









z!FirewallPolicy.remove_source_portc             C   s   ||j d kr|j d |= d S )NrF   )r<   )r!   r   r   r#   r#   r$   Z__unregister_source_port  s    z'FirewallPolicy.__unregister_source_portc             C   s6   x0| j |d D ]\}}t||r||krdS qW dS )NrF   TF)r8   r	   )r!   r;   r   r   rs   rt   r#   r#   r$   query_source_port  s    z FirewallPolicy.query_source_portc             C   s   t | j|d j S )NrF   )r   r8   r,   )r!   r;   r#   r#   r$   r     s    z FirewallPolicy.list_source_portsc             C   s   dS )NTr#   )r!   r#   r#   r$   Z__masquerade_id  s    zFirewallPolicy.__masquerade_idc             C   s8  | j j|}| j j| | j j  | j| }| j }||jd krb|jrN|jn|}tt	j
d| |jsd|jd krtt	jdd|jd krtt	jdx6|jd D ](}	|	dkrq| j jj|	rtt	jd	qW |d kr| j }
n|}
|jr | jd
||
 | j|||| |
j| j|| |d kr4|
jd
 |S )NrD   z"masquerade already enabled in '%s'r5   r7   z.'masquerade' is invalid for egress zone 'HOST'r4   z/'masquerade' is invalid for ingress zone 'HOST'r6   zR'masquerade' cannot be used in a policy if an ingress zone has assigned interfacesT)r   r>   r   r   r    _FirewallPolicy__masquerade_idr<   r/   r   r   rZ   r   r:   r   r*   rO   rv   $_FirewallPolicy__register_masquerader   &_FirewallPolicy__unregister_masqueraderx   )r!   r;   rg   rf   rb   rz   r   masquerade_idr   r:   r{   r#   r#   r$   r_   
  s:    





zFirewallPolicy.add_masqueradec             C   s   | j |||jd |< d S )NrD   )r   r<   )r!   r   r   rg   rf   r#   r#   r$   Z__register_masquerade2  s    z$FirewallPolicy.__register_masqueradec             C   s   | j j|}| j j  | j| }| j }||jd krV|jrB|jn|}ttj	d| |d krh| j
 }n|}|jr| jd|| |j| j|| |d kr|jd |S )NrD   zmasquerade not enabled in '%s'FT)r   r>   r   r    r   r<   r/   r   r   r   r*   rO   rv   r   r   rx   )r!   r;   rb   rz   r   r   r   r{   r#   r#   r$   r   6  s"    




z FirewallPolicy.remove_masqueradec             C   s   ||j d kr|j d |= d S )NrD   )r<   )r!   r   r   r#   r#   r$   Z__unregister_masqueradeP  s    z&FirewallPolicy.__unregister_masqueradec             C   s   | j  | j|d kS )NrD   )r   r8   )r!   r;   r#   r#   r$   r   T  s    zFirewallPolicy.query_masqueradec             C   s^   | j j| | j j| |r(| j j| |rBt||sBttj|| rZ| rZttjdd S )Nz.port-forwarding is missing to-port AND to-addr)r   r   r   r   r   r   ZINVALID_ADDRr   )r!   ipvr   r   toporttoaddrr#   r#   r$   check_forward_portY  s    
z!FirewallPolicy.check_forward_portc             C   sL   t d|r| jd|||| n| jd|||| t|d|t|dt|fS )Nr   r   r   )r   r   r   r   )r!   r   r   r   r   r#   r#   r$   Z__forward_port_idf  s
    

z FirewallPolicy.__forward_port_idc	             C   sZ  | j j|}	| j j| | j j  | j|	 }
| j||||}||
jd krt|
jrV|
jn|	}tt	j
d|||||f |
jsd|
jd kr|rtt	jdnR|
jd r|stt	jdx6|
jd D ](}|dkrq| j jj|rtt	jdqW |d kr | j }n|}|
jr"| jd	|	||||| | j|
||| |j| j|
| |d krV|jd	 |	S )
NrE   z'%s:%s:%s:%s' already in '%s'r5   r7   zAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zoner6   zS'forward-port' cannot be used in a policy if an egress zone has assigned interfacesT)r   r>   r   r   r     _FirewallPolicy__forward_port_idr<   r/   r   r   rZ   r   r:   r   r   r*   rO   rq   &_FirewallPolicy__register_forward_portr   (_FirewallPolicy__unregister_forward_portrx   )r!   r;   r   r   r   r   rg   rf   rb   rz   r   
forward_idr   r:   r{   r#   r#   r$   rV   n  sB    






zFirewallPolicy.add_forward_portc             C   s   | j |||jd |< d S )NrE   )r   r<   )r!   r   r  rg   rf   r#   r#   r$   Z__register_forward_port  s    z&FirewallPolicy.__register_forward_portc             C   s   | j j|}| j j  | j| }| j||||}	|	|jd krh|jrJ|jn|}
ttj	d|||||
f |d krz| j
 }n|}|jr| jd|||||| |j| j||	 |d kr|jd |S )NrE   z'%s:%s:%s:%s' not in '%s'FT)r   r>   r   r    r  r<   r/   r   r   r   r*   rO   rq   r   r  rx   )r!   r;   r   r   r   r   rb   rz   r   r  r   r{   r#   r#   r$   r     s&    



z"FirewallPolicy.remove_forward_portc             C   s   ||j d kr|j d |= d S )NrE   )r<   )r!   r   r  r#   r#   r$   Z__unregister_forward_port  s    z(FirewallPolicy.__unregister_forward_portc             C   s"   | j ||||}|| j|d kS )NrE   )r  r8   )r!   r;   r   r   r   r   r  r#   r#   r$   query_forward_port  s    z!FirewallPolicy.query_forward_portc             C   s   t | j|d j S )NrE   )r   r8   r,   )r!   r;   r#   r#   r$   r     s    z!FirewallPolicy.list_forward_portsc             C   s   | j j| d S )N)r   Zcheck_icmptype)r!   icmpr#   r#   r$   check_icmp_block  s    zFirewallPolicy.check_icmp_blockc             C   s   | j | |S )N)r  )r!   r  r#   r#   r$   Z__icmp_block_id  s    
zFirewallPolicy.__icmp_block_idc             C   s   | j j|}| j j| | j j  | j| }| j|}||jd krh|jrP|jn|}	tt	j
d||	f |d krz| j }
n|}
|jr| jd|||
 | j|||| |
j| j|| |d kr|
jd |S )NrG   z'%s' already in '%s'T)r   r>   r   r   r    _FirewallPolicy__icmp_block_idr<   r/   r   r   rZ   r*   rO   rp   $_FirewallPolicy__register_icmp_blockr   &_FirewallPolicy__unregister_icmp_blockrx   )r!   r;   r  rg   rf   rb   rz   r   icmp_idr   r{   r#   r#   r$   rU     s&    




zFirewallPolicy.add_icmp_blockc             C   s   | j |||jd |< d S )NrG   )r   r<   )r!   r   r  rg   rf   r#   r#   r$   Z__register_icmp_block  s    z$FirewallPolicy.__register_icmp_blockc       	      C   s   | j j|}| j j  | j| }| j|}||jd kr\|jrD|jn|}ttj	d||f |d krn| j
 }n|}|jr| jd||| |j| j|| |d kr|jd |S )NrG   z'%s' not in '%s'FT)r   r>   r   r    r  r<   r/   r   r   r   r*   rO   rp   r   r
  rx   )	r!   r;   r  rb   rz   r   r  r   r{   r#   r#   r$   r     s"    




z FirewallPolicy.remove_icmp_blockc             C   s   ||j d kr|j d |= d S )NrG   )r<   )r!   r   r  r#   r#   r$   Z__unregister_icmp_block  s    z&FirewallPolicy.__unregister_icmp_blockc             C   s   | j || j|d kS )NrG   )r  r8   )r!   r;   r  r#   r#   r$   query_icmp_block  s    zFirewallPolicy.query_icmp_blockc             C   s   | j |d j S )NrG   )r8   r,   )r!   r;   r#   r#   r$   r     s    zFirewallPolicy.list_icmp_blocksc             C   s   dS )NTr#   )r!   r#   r#   r$   Z__icmp_block_inversion_id  s    z(FirewallPolicy.__icmp_block_inversion_idc       
      C   s  | j j|}| j j  | j| }| j }||jd krV|jrB|jn|}ttj	d| |d krh| j
 }n|}|jrx&| j|d D ]}	| jd||	| qW | jd|| | j||| |j| j||| |jrx&| j|d D ]}	| jd||	| qW | jd|| |d kr|jd |S )NrJ   z,icmp-block-inversion already enabled in '%s'rG   FT)r   r>   r   r    (_FirewallPolicy__icmp_block_inversion_idr<   r/   r   r   rZ   r*   rO   r8   rp   _icmp_block_inversion._FirewallPolicy__register_icmp_block_inversionr   *_FirewallPolicy__undo_icmp_block_inversionrx   )
r!   r;   rf   rb   rz   r   icmp_block_inversion_idr   r{   r`   r#   r#   r$   add_icmp_block_inversion  s6    





z'FirewallPolicy.add_icmp_block_inversionc             C   s   | j d||jd |< d S )Nr   rJ   )r   r<   )r!   r   r  rf   r#   r#   r$   Z__register_icmp_block_inversionE  s    z.FirewallPolicy.__register_icmp_block_inversionc             C   s   | j  }|jr6x&| j|d D ]}| jd||| qW ||jd krP|jd |= |jr~x&| j|d D ]}| jd||| qfW |jd d S )NrG   FrJ   T)r*   rO   r8   rp   r<   rx   )r!   rz   r   r  r{   r`   r#   r#   r$   Z__undo_icmp_block_inversionJ  s    z*FirewallPolicy.__undo_icmp_block_inversionc       	      C   s  | j j|}| j j  | j| }| j }||jd krV|jrB|jn|}ttj	d| |d krh| j
 }n|}|jrx&| j|d D ]}| jd||| qW | jd|| | j|| |j| j||d  |jrx&| j|d D ]}| jd||| qW | jd|| |d kr|jd |S )NrJ   z(icmp-block-inversion not enabled in '%s'rG   FT)r   r>   r   r    r  r<   r/   r   r   r   r*   rO   r8   rp   r  0_FirewallPolicy__unregister_icmp_block_inversionr   r  rx   )	r!   r;   rb   rz   r   r  r   r{   r`   r#   r#   r$   remove_icmp_block_inversion\  s6    






z*FirewallPolicy.remove_icmp_block_inversionc             C   s   ||j d kr|j d |= d S )NrJ   )r<   )r!   r   r  r#   r#   r$   Z!__unregister_icmp_block_inversion  s    z0FirewallPolicy.__unregister_icmp_block_inversionc             C   s   | j  | j|d kS )NrJ   )r  r8   )r!   r;   r#   r#   r$   query_icmp_block_inversion  s    z)FirewallPolicy.query_icmp_block_inversionc       
      C   s   | j jj|}|jr*| j jj|j d }n|}|rT|| jkrt||f| j| krtd S n || jksp||f| j| krtd S x@| j j D ]2}|jr||j	 kr|j
||||}	|j||	 qW | j||||fg |j| j|| ||fg d S )Nr   )r   r;   r.   r/   r:   Z_zone_policiesr   enabled_backendspolicies_supportedZget_available_tablesZbuild_policy_chain_rules	add_rules_register_chainsr   )
r!   r;   creater|   r}   r{   rM   Ztracking_policybackendrH   r#   r#   r$   rn     s$    

zFirewallPolicy.gen_chain_rulesc             C   sb   x\|D ]T\}}|r,| j j|g j||f q| j | j||f t| j | dkr| j |= qW d S )Nr   )r   
setdefaultr0   remover   )r!   r;   r  Ztablesr|   r}   r#   r#   r$   r    s    zFirewallPolicy._register_chainsc             C   s$   | j jj|dkrd S | j jj|S )Nzhash:mac)r   r   get_typeZ
get_family)r!   rK   r#   r#   r$   r     s    zFirewallPolicy._ipset_familyc             C   s   | j jj|S )N)r   r   r  )r!   rK   r#   r#   r$   Z__ipset_type  s    zFirewallPolicy.__ipset_typec             C   s   dj |g| jjj| S )N,)joinr   r   Zget_dimension)r!   rK   flagr#   r#   r$   _ipset_match_flags  s    z!FirewallPolicy._ipset_match_flagsc             C   s   | j jj|S )N)r   r   Zcheck_applied)r!   rK   r#   r#   r$   r     s    z#FirewallPolicy._check_ipset_appliedc             C   s*   | j |}|tkr&ttjd||f d S )Nz.ipset '%s' with type '%s' not usable as source)_FirewallPolicy__ipset_typer   r   r   ZINVALID_IPSET)r!   rK   Z_typer#   r#   r$   r     s    
z+FirewallPolicy._check_ipset_type_for_sourcec                s  t |jtkrjjj|jj}|d kr2|jjg}xR|jD ]H}||krHq:j| |j	| t
j|}||j_j|||||d q:W g }	|jr|jg}	nH|jrt|jtst|jtrjjj|jj  jr fdddD }	j|j}
|
r&|jr |j|
kr&ttjd|
|jf n|
g}	|	s4ddg}	fdd|	D }	|	|_x2tfdd|	D D ]}t |jtkrjjj|jj}g }t|jd	kr|jrttjd
xB|	D ].}||jkr|j|r|j	|j|  qW n
|j	d  x~|D ]}t |jtkrj|j |}|j!|j"7 }t#t|dd d}g }x|D ]}|j$}t%|}|j&dd}|j	| |jdkr|j|j rqTt|j'dk r|j	| n:x8|j'D ].\}}|j(||||||j|}|j)|| qW qTW |j*| x4|j'D ]*\}}|j+||||||}|j)|| q
W x.|j,D ]$}|j-|||||}|j)|| q@W x4|j.D ]*\}}|j/||||||}|j)|| qpW qW qft |jt0kr|jj1}|jj2}j3|| |j+||||d |}|j)|| qft |jt4kr<|jj5}j6| |j-|||d |}|j)|| qft |jt7kr|rzx&|	D ]}|j|rX|j8t9| qXW |j:|||}|j)|| qft |jt;kr4|jj1}|jj2}|jj<}|jj=}xD|	D ]<}|j|rj>||||| |r|r|j8t9| qW |j?|||||||}|j)|| qft |jt@kr|jj1}|jj2}j3|| |j/||||d |}|j)|| nt |jtkst |jtkr>jjj|jj |jr jr|j jkrttjAd|j|jjf t |jtkr |jr t |jtkr ttjd|jB|| |}|j)|| n>|jd krf|jC|||}|j)|| nttjdt |j qfW d S )N)included_servicesc                s   g | ]}| j kr|qS r#   )destination)r?   r   )ictr#   r$   r     s    z0FirewallPolicy._rule_prepare.<locals>.<listcomp>r   r   z;Source address family '%s' conflicts with rule family '%s'.c                s   g | ]} j j|r|qS r#   )r   is_ipv_enabled)r?   r   )r!   r#   r$   r     s    c                s   g | ]} j j|qS r#   )r   get_backend_by_ipv)r?   r@   )r!   r#   r$   r     s    r   z"Destination conflict with service.c             S   s   | j S )N)rK   )r@   r#   r#   r$   r     s    z.FirewallPolicy._rule_prepare.<locals>.<lambda>)r~   	conntracknatr   rj   z3rich rule family '%s' conflicts with icmp type '%s'z'IcmpBlock not usable with accept actionzUnknown element %s)r   r   )Dtyper   r   r   r   get_servicerK   includesr   r0   copydeepcopyr   familyr   r   r   configget_icmptyper%  r   r   r   r   ZINVALID_RULEipvsr9   r   is_ipv_supportedr   r   r   r   r   r   r+   r   r
   replacerC   build_policy_helper_ports_rulesr  Zadd_modulesbuild_policy_ports_rulesrI   build_policy_protocol_rulesrF   build_policy_source_ports_rulesr   r   r   r   r   valuer   r   r   r   build_policy_masquerade_rulesr   Zto_portr   r   build_policy_forward_port_rulesr   ZINVALID_ICMPTYPEbuild_policy_icmp_block_rulesZ*build_policy_rich_source_destination_rules)r!   ry   r;   r   r{   r$  svcincludeZ_ruler3  Z
source_ipvr  Zdestinationsr   r%  r   r   r   r   r   
nat_moduler   protorH   r   r   r   r#   )r&  r!   r$   r     s   




 









zFirewallPolicy._rule_preparec             C   sb  | j jj|}| j|j|}|| j|j7 }tt|dd d}|d krN|g}x@|j	D ]6}||krdqV| j
| |j| | j|||||d qVW g }	xndD ]f}
| j j|
sq| j j|
}t|jdkr|
|jkr|	j||j|
 f q|d f|	kr|	j|d f qW xV|	D ]L\}}x|D ]}|j}t|}|jjdd	}|j| |jd
krf|j|j rfqt|jdk r|j| n:x8|jD ].\}}|j||||||j|}|j|| qW qW x2|jD ](\}}|j|||||}|j|| qW x,|jD ]"}|j||||}|j|| qW x2|jD ](\}}|j|||||}|j|| q,W qW d S )Nc             S   s   | j S )N)rK   )r@   r#   r#   r$   r     s    z)FirewallPolicy._service.<locals>.<lambda>)r~   )r$  r   r   r   r)  r*  r   rj   )r   r   ) r   r   r,  r   r   r   r   r+   r9   r-  r   r0   rr   r'  r(  r   r%  r   r
   r5  Z
add_moduler0  r4  rC   r6  rK   r  r7  rI   r8  rF   r9  )r!   ry   r;   r   r{   r$  r>  r   r?  Zbackends_ipvr   r  r%  r   r   r   r@  r   rA  rH   r   r#   r#   r$   rr     sb    






zFirewallPolicy._servicec             C   s<   x6| j j D ](}|jsq|j||||}|j|| qW d S )N)r   r  r  r7  r  )r!   ry   r;   r   r   r{   r  rH   r#   r#   r$   rs     s    
zFirewallPolicy._portc             C   s:   x4| j j D ]&}|jsq|j|||}|j|| qW d S )N)r   r  r  r8  r  )r!   ry   r;   r   r{   r  rH   r#   r#   r$   rt     s
    zFirewallPolicy._protocolc             C   s<   x6| j j D ](}|jsq|j||||}|j|| qW d S )N)r   r  r  r9  r  )r!   ry   r;   r   r   r{   r  rH   r#   r#   r$   ru     s
    zFirewallPolicy._source_portc             C   s8   d}|j t| | jj|}|j||}|j|| d S )Nr   )r   r   r   r(  r;  r  )r!   ry   r;   r{   r   r  rH   r#   r#   r$   rv     s
    zFirewallPolicy._masqueradec             C   sX   t d|rd}nd}|r(|r(|jt| | jj|}	|	j||||||}
|j|	|
 d S )Nr   r   )r   r   r   r   r(  r<  r  )r!   ry   r;   r{   r   r   r   r   r   r  rH   r#   r#   r$   rq     s    

zFirewallPolicy._forward_portc       
      C   s   | j jj|}xl| j j D ]^}|js&qd}|jrXx&dD ]}||jkr6|j|s6d}P q6W |r^q|j|||}	|j||	 qW d S )NFr   r   T)r   r   )	r   r1  r2  r  r  r%  r4  r=  r  )
r!   ry   r;   r  r{   r&  r  Zskip_backendr   rH   r#   r#   r$   rp     s    


zFirewallPolicy._icmp_blockc             C   sh   | j | j}|dkrd S | j| r0|dkr0d S x2| jj D ]$}|jsHq<|j||}|j|| q<W d S )NDROP
%%REJECT%%REJECTZACCEPT)rB  rC  rD  )r    targetr  r   r  r  Z'build_policy_icmp_block_inversion_rulesr  )r!   ry   r;   r{   rE  r  rH   r#   r#   r$   r    s    z$FirewallPolicy._icmp_block_inversionc       	      C   s   x|D ]}| j | qW x|D ]}| j| qW d|ks@d|krXt|dkrXttjdd|kshd|krt|dkrttjd|s|r| r| rd|krd|krttjd| |s|r| r| rd|krd|krttjd| d S )Nr6   r5   rj   zI'ingress-zones' may only contain one of: many regular zones, ANY, or HOSTzH'egress-zones' may only contain one of: many regular zones, ANY, or HOSTzpolicy "%s" has no ingresszpolicy "%s" has no egress)r   r   r   r   r   r   )	r!   r;   r4   r7   ingress_interfacesegress_interfacesingress_sourcesegress_sourcesr:   r#   r#   r$   check_ingress_egress"  s$    

z#FirewallPolicy.check_ingress_egressc
       
      C   s   |dkr&|dkr|rt tjd| n|dkrtd|krFt tjd| d|kr^t tjd| |rt tjd| n||d	krd|krt tjd| d|krt tjd| nB|d
krd|krt tjd| n |dkrd|krt tjd| d S )N
PREROUTINGrawzFpolicy "%s" egress-zones may not include a zone with added interfaces.POSTROUTINGr5   z/policy "%s" ingress-zones may not include HOST.z.policy "%s" egress-zones may not include HOST.zGpolicy "%s" ingress-zones may not include a zone with added interfaces.FORWARDINPUTz0policy "%s" egress-zones must include only HOST.OUTPUTz1policy "%s" ingress-zones must include only HOST.)r   r   r   )
r!   r;   r|   r}   r4   r7   rF  rG  rH  rI  r#   r#   r$   check_ingress_egress_chain<  s,    z)FirewallPolicy.check_ingress_egress_chainc             C   s$   | j  }| j||| |jd d S )NT)r*   ro   rx   )r!   ry   r;   r{   r#   r#   r$   !_ingress_egress_zones_transactionY  s    z0FirewallPolicy._ingress_egress_zones_transactionc             C   sL  | j | }|jd }|jd }t }t }t }	t }
xB|D ]:}|dkrJq<|t| jjj|O }|	t| jjj|O }	q<W xB|D ]:}|dkrq|t| jjj|O }|
t| jjj|O }
qW | j||||||	|
 xr| jj D ]d}|j	sqxV| j
|D ]H\}}| j||||||||	|
	 |j|||||||	|
}|j||  qW qW d S )Nr4   r7   r6   r5   )r6   r5   )r6   r5   )r    r<   r9   r   r:   r   Zlist_sourcesrJ  r  r  rl   rQ  Z!build_policy_ingress_egress_rulesr  )r!   ry   r;   r{   rM   r4   r7   rF  rG  rH  rI  r:   r  r|   r}   rH   r#   r#   r$   ro   ^  s@    






z$FirewallPolicy._ingress_egress_zonesc             C   s6  | j | }d|jd krFd|jd krFdddg}| jjsB|jd |S d|jd krpdg}| jjsl|jd |S d|jd krdgS d|jd kod|jd k rddddg}| jj s|jd |S d|jd kr.dddg}| jj s|jd x4|jd D ]}| jjj|d r P q W |jd  |S d|jd krd!d"g}| jjsZ|jd# x>|jd D ]}| jjj|d rfP qfW |jd$ |jd% |S d&g}| jjs|jd' x4|jd D ]}| jjj|d rP qW |jd( x>|jd D ]}| jjj|d rP qW |jd) |jd* |S dS )+z:Create a list of (table, chain) needed for policy dispatchr6   r4   r5   r7   r   rO  r*  rK  manglerL  rP  rN  rM  Z
interfacesN)r   rO  )r*  rK  )rS  rK  )rL  rK  )r   rO  )rL  rK  )r   rP  )r   rN  )r*  rK  )r*  rM  )rS  rK  )rL  rK  )r   rN  )r*  rK  )rS  rK  )rL  rK  )r*  rM  )r   rN  )r*  rM  )rL  rK  )r*  rK  )rS  rK  )r   rN  )rL  rK  )r*  rM  )r*  rK  )rS  rK  )r    r<   r   nftables_enabledr0   r:   r8   )r!   r;   rM   tcr:   r#   r#   r$   rl     sj    
















z4FirewallPolicy._get_table_chains_for_policy_dispatchc             C   sr   | j | }d|jd kr4dg}| jjs0|jd |S d|jd krLdddgS d|jd krbddgS td| S dS )z8Create a list of (table, chain) needed for zone dispatchr5   r7   r   rO  rL  rK  r6   
FORWARD_INr*  rS  r4   FORWARD_OUTrM  zInvalid policy: %sN)r   rO  )rL  rK  )r   rV  )r*  rK  )rS  rK  )r   rW  )r*  rM  )r    r<   r   rT  r0   r   )r!   r;   rM   rU  r#   r#   r$   rm     s    

z2FirewallPolicy._get_table_chains_for_zone_dispatchFc             C   s  | j jj|}|jr|j}n|| }d|jd krl|dkrBd| S |dkrRd| S |jsh|dkrhd| S nJd|jd	 kr|js|dkrd
| S n"d|jd k r|dkr|jrd| S d| S n0|dkr|rd| S d| S n|dkrd| S nd|jd	 krh|dkr*|jr d| S d| S n<|dkrL|rBd| S d| S n|dkr|jsd| S nN|js|dkrd| S |dkr|rd| S d| S n|dkrd| S td|||f S )Nr5   r7   r   ZIN_rL  ZPRE_rS  r*  r4   ZOUT_r6   ZFWDI_ZFWD_ZPOST_ZFWDO_z.Can't convert policy to chain name: %s, %s, %s)rS  r*  )rS  rL  )rS  rL  )rS  rL  )r   r;   r.   r/   r<   r   )r!   r;   r|   Zpolicy_prefixZisSNATrM   suffixr#   r#   r$   policy_base_chain_name  sb    













z%FirewallPolicy.policy_base_chain_name)N)N)N)N)r   NNT)N)r   NNT)N)r   NN)N)r   NN)N)r   NN)N)r   NN)N)r   NN)N)r   NN)N)NN)NN)NNr   NN)NNN)NN)r   NN)N)NN)N)N)N)NN)F)__name__
__module____qualname__r%   r'   r)   r*   r-   r3   r=   r.   rN   rQ   rL   rd   re   r   r8   r   rc   rP   r   r   r   r   rS   r   r   r   r   r   r   r   rT   r   r   r   r   r   r   r   r   rw   r^   r   r   r   r   r   r   r   rW   r   r   r   r   r   r   r   r   r   rX   r   r   r   r   r   r   r   r\   r   r   r   r   r   r   r]   r   r   r   r   r   r   r_   r   r   r   r   r   r  rV   r  r   r  r  r   r  r  rU   r	  r   r
  r  r   r  r  r  r  r  r  r  rn   r  r   r#  r"  r   r   r   rr   rs   rt   ru   rv   rq   rp   r  rJ  rQ  rR  ro   rl   rm   rY  r#   r#   r#   r$   r      s$  
'	?. ,# ,# : 
 '(  '( '  +    )) @@		(Pr   )'rh   r.  Zfirewall.core.loggerr   Zfirewall.functionsr   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zfirewall.core.fw_transactionr   Zfirewallr   Zfirewall.errorsr   Zfirewall.fw_typesr   Zfirewall.core.baser   objectr   r#   r#   r#   r$   <module>   s   04