o
    Fa                     @   sz   d Z ddlZddlZddlZddlmZ ddlZddlmZm	Z	m
Z
 ddlmZ ddlZdd Zdd	 ZG d
d dZdS )z'frontend.py: frontend interface for ufw    N)UFWError)errorwarnmsg)UFWBackendIptablesc              
   C   s  t j }dD ]}|t j| qdD ]}|t j| qdD ]}|t j| q#dD ]}|t j| q1dD ]}|t j| q?dD ]}|t j	| qMg d}|D ]}|t j
| |t j| q_t| dkrd	}| |  d
krd}| |  dkr| |  dkr| |  |v r| |d t| dk sd
| v rt| dk rtd z|| d	d }W |S  ty } ztd|j  W Y d}~|S d}~w ty   tddd  w )zEParse command. Returns tuple for action, rule, ip_version and dryrun.)enabledisablehelpz--helpversionz	--versionreloadreset)listinfodefaultupdate)onofflowmediumhighfull)allowdenyreject)Nverbosenumbered)rawzbefore-rulesz
user-ruleszafter-ruleszlogging-rulesbuiltins	listeningadded)r   limitr   r   insertdeleteprepend      	--dry-runr   routerule   znot enough argsNz%szInvalid syntaxF)do_exit)ufwparser	UFWParserregister_commandUFWCommandBasicUFWCommandAppUFWCommandLoggingUFWCommandDefaultUFWCommandStatusUFWCommandShowUFWCommandRuleUFWCommandRouteRulelenlowerr!   r   parse_commandr   value	Exception)argvpirule_commandsidxpre rC   ./usr/lib/python3/dist-packages/ufw/frontend.pyr9      sL   
 r9   c                  C   s   t di dtjjddddddddd	d
ddddddddddddddddddddddi d d!d"d#d$d%d&d'd(d(d)d)d*d*d+d,d-d.d/d0d1d2d3d3d4d5d6d7d8d9d:d;d<d=d>d?i } | S )@zPrint help messagea+  
Usage: %(progname)s %(command)s

%(commands)s:
 %(enable)-31s enables the firewall
 %(disable)-31s disables the firewall
 %(default)-31s set default policy
 %(logging)-31s set logging to %(level)s
 %(allow)-31s add allow %(rule)s
 %(deny)-31s add deny %(rule)s
 %(reject)-31s add reject %(rule)s
 %(limit)-31s add limit %(rule)s
 %(delete)-31s delete %(urule)s
 %(insert)-31s insert %(urule)s at %(number)s
 %(prepend)-31s prepend %(urule)s
 %(route)-31s add route %(urule)s
 %(route-delete)-31s delete route %(urule)s
 %(route-insert)-31s insert route %(urule)s at %(number)s
 %(reload)-31s reload firewall
 %(reset)-31s reset firewall
 %(status)-31s show firewall status
 %(statusnum)-31s show firewall status as numbered list of %(rules)s
 %(statusverbose)-31s show verbose firewall status
 %(show)-31s show firewall report
 %(version)-31s display version information

%(appcommands)s:
 %(applist)-31s list application profiles
 %(appinfo)-31s show information on %(profile)s
 %(appupdate)-31s update %(profile)s
 %(appdefault)-31s set default application policy
prognamecommandCOMMANDcommandsCommandsr   r   r   zdefault ARGloggingzlogging LEVELlevelLEVELr   z
allow ARGSr(   r   z	deny ARGSr   zreject ARGSr    z
limit ARGSr"   zdelete RULE|NUMuruleRULEr!   zinsert NUM RULEr#   zprepend RULEr'   z
route RULEzroute-deletezroute delete RULE|NUMzroute-insertzroute insert NUM RULEnumberNUMr   r   status	statusnumzstatus numberedrulesRULESstatusverbosezstatus verboseshowzshow ARGr
   appcommandszApplication profile commandsapplistzapp listappinfozapp info PROFILEprofilePROFILE	appupdatezapp update PROFILE
appdefaultzapp default ARG)_r+   commonprogramName)help_msgrC   rC   rD   get_command_help[   s   	
 !"Crb   c                   @   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dZ	dd Z
dd Zdd Zd/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S )0UFWFrontendUIiptablesNc                 C   s\   |dkrz
t |||d| _W n ty    w td| td| _td| _td| _d S )Nre   )rootdirdatadirzUnsupported backend type '%s'nyyes)r   backendr;   r   r^   norj   yes_full)selfdryrunbackend_typerf   rg   rC   rC   rD   __init__   s   

zUFWFrontend.__init__c              
   C   s|  d}d}|rd}d}|r| j  r|s| j  rd}|rBz| j | j jd d| W n tyA } zt|j W Y d}~nd}~ww d}|rz| j   W n tyd } z|rZ|j}W Y d}~nd}~ww |dkrz| j | j jd dd W n ty } zt|j W Y d}~nd}~ww t| td	}|S z| j 	  W n ty } zt|j W Y d}~nd}~ww td
}|S )zlToggles ENABLED state in <config_dir>/ufw/ufw.conf and starts or
           stops running firewall.
         rl   rj   FTconfENABLEDNz0Firewall is active and enabled on system startupz/Firewall stopped and disabled on system startup)
rk   
is_enabledset_defaultfilesr   r   r:   start_firewallr^   stop_firewall)rn   enabledres
config_strchangedrB   	error_strrC   rC   rD   set_enabled   sb   	zUFWFrontend.set_enabledc              
   C   sn   d}z| j ||}| j  r| j   | j   W |S W |S  ty6 } zt|j W Y d}~|S d}~ww )zSets default policy of firewallrr   N)rk   set_default_policyru   ry   rx   r   r   r:   )rn   policy	directionr{   rB   rC   rC   rD   r      s   

zUFWFrontend.set_default_policyc              
   C   H   d}z	| j |}W |S  ty# } zt|j W Y d}~|S d}~ww )zSets log level of firewallrr   N)rk   set_loglevelr   r   r:   )rn   rK   r{   rB   rC   rC   rD   r         zUFWFrontend.set_loglevelFc              
   C   sF   z
| j ||}W |S  ty" } zt|j W Y d}~|S d}~ww )zShows status of firewallN)rk   
get_statusr   r   r:   )rn   r   
show_countoutrB   rC   rC   rD   r     s   zUFWFrontend.get_statusr   c              
   C   sD   z	| j |}W |S  ty! } zt|j W Y d}~|S d}~ww )zShows raw output of firewallN)rk   get_running_rawr   r   r:   )rn   
rules_typer   rB   rC   rC   rD   get_show_raw  s   zUFWFrontend.get_show_rawc                 C   s  d}zt j| j }W n ty   td}t|w | j }t	|
 }|  |D ]}| j s:|dv r:q.|d| 7 }t	|| 
 }|  |D ]}|| | D ]}	|	d }
|
ds|
dsd}|d| 7 }|
d	ksv|
d
kr|d7 }d|	d  }
n|d|
 7 }t j|
}|dtj|	d  7 }t jjd|dd ||
ddd}||d |dkr|d| |  | j|}t|dkr|d7 }|D ]}|dkr|d t|k r|d|t jj||d  f 7 }q|d7 }qVqNq.| j st jd |S )zMShows listening services and incoming rules that might affect
           themrr   zCould not get listening status)tcp6udp6z%s:
laddrz127.z::1z  %s z0.0.0.0z::z* z%s/0z%s z(%s)exer   Nr)   inF)actionprotocoldportdstr   forward6r   
r%   z   [%2d] %s
z)Skipping tcp6 and udp6 (IPv6 is disabled))r+   utilparse_netstat_outputrk   use_ipv6r;   r^   r   	get_rulesr   keyssort
startswithget_if_from_ipospathbasenamer_   UFWRuleset_v6endswithset_interface	normalizeget_matchingr7   r,   r5   get_commanddebug)rn   r{   derr_msgrS   	protocolsprotoportsportitemaddrifnamer(   matchingr>   rC   rC   rD   get_show_listening  sv   



/zUFWFrontend.get_show_listeningc                 C   s   | j  }td}t|dkr|td S g }| j  D ]&}|jr+dtjj| }ntjj	|}||v r7q|
| |d| 7 }q|S )z!Shows added rules to the firewallz9Added user rules (see 'ufw status' for running firewall):r   z
(None)route %sz
ufw %s)rk   r   r^   r7   r   r+   r,   r6   r   r5   append)rn   rS   r   r   rrstrrC   rC   rD   get_show_added\  s    

zUFWFrontend.get_show_addedc                 C   s  d}d}d}g }|j dkr|jdkr|| ng }z|jr|dkr*| j|d}nF|dkr6| j|d}n:|dkrf| j|d}| j|d}|D ]}	|D ]}
|
j}d|
_|	|
sc||
_||
 qNqJn
td| }t	|t
|dkr| jjstd	}|dkr|}|W S |dkr|d
 }|W S |dkr|d | d
 }|W S |D ]}| }|j|_||j ||j || qn| j|}|jdkr|  W n ty    w d}d}td}| jd}| jd}t|D ]\}}|}|j|| kr|t|jd 7 }t	|z| j r|dkrT|jdkr4|dkr,|dkr,dnd}|| n|j|krG|t|jd 7 }t	||d | j|}n{|dkr|jdkrs|dkrk|dkrkdnd}|| n(|j|kr||j|  n|jdkr|j|kr|t|jd 7 }t	||d | j|}n'|dkr|j}|d |dkr|dkr|dkrdnd}|| n$|js||kr| j|| | d}|dkr|| n|d | j|}|js|dkr| jd}||d  |d |dkr,|dkr$|dkr$dnd}|| n*|jsV|jdkrV|j|krV| j|jd}|dkrQ|||  n|d |dkr_|d7 }|jsv|j|krv|dkrv||j|  || j|7 }nPtd| }t	||jdkr|dkr|dkrdnd}|| |dks|dkr|d | j|}n|dkrtd}t	|td| }t	|W n t	y } z|j}d}W Y d}~ nd}~ww |jrtd}t | q|s||7 }|S t
|dkrt!| |S d}t"t#|d }|  |D ]9}|dkrV|| rV||  }d|_z	| || W q tyU   d}td|$  }t | Y qw q|td7 }|rk|td7 }t	||td7 }t	|)zUpdates firewall with rulerr   v4Fv6TbothzInvalid IP version '%s'r   z"Could not delete non-existent rulez (v6)r   zInvalid position ''r%   zIPv6 support not enabledNz Rule changed after normalizationzCould not back out rule '%s'z"
Error applying application rules.z# Some rules could not be unapplied.z( Attempted rules successfully unapplied.)%dappsappr   removerk   get_app_rules_from_systemr   matchr^   r   r7   ro   dup_rule
set_actionr   set_logtypelogtypeget_app_rules_from_templatepositionreverser;   get_rules_count	enumeratestrr   set_positionr   set_rulefind_other_positionr:   updatedwarningsr   r   r   rangeformat_rule)rn   r(   
ip_versionr{   r   tmprS   tmprules	tmprules6xri   prev6r   count	set_errorpos_err_msgnum_v4num_v6r>   beginuser_posr=   rB   warn_msg
undo_errorindexesjbackout_rulerC   rC   rD   r   y  sj  






















zUFWFrontend.set_rulec                 C   sP  zt |}W n ty   td| }t|w | j }|dks'|t|kr1td| }t|| j|}|sCtd| }t|d|_d}|j	rMd}d}|s|j
r^dtjj| }	ntjj|}	td|	| j| jd	 }
t|
tjd
d tj   }|dkr|| j kr|| j krd
}d}|r| ||}|S td}|S )zDelete rulezCould not find rule '%s'r   zCould not find rule '%d'Tr   r   r   z=Deleting:
 %(rule)s
Proceed with operation (%(yes)s|%(no)s)? )r(   rj   rl   Foutputnewlineri   rr   Aborted)intr;   r^   r   rk   r   r7   get_rule_by_numberr   r   r   r+   r,   r6   r   r5   rj   rl   r   sysstdoutstdinreadliner8   striprm   r   )rn   rO   forcerh   r   rS   r(   r   proceedr   promptansr{   rC   rC   rD   delete_ruleE  sT   
zUFWFrontend.delete_rulec           	   
   C   sH  d}| dr"|d}t|dkr| |d }|S | d}|S |dkr-| d}|S | drQtd	}|d
}t|dkrEt|| |d |d }|S |dkr\| |}|S |dkrf|  }|S |dkrq| d}|S | dr|d
d }|dkr| 	 }|S |dkr| 
 }|S | |}|S |dkr| dd}|S |dkr| d}|S |dkr| d}|S |dkr| j r| d | d td}|S td}|S | dr| |d
d |}|S |dks|dks|dks|dkr|jdkrGz| j|j}||jkr||_||d  W n, tyF } z|js,t|j tj|js<td!}t|W Y d"}~nd"}~ww |jdkrz| j|j}||jkrd||_||d  W n, ty } z|jswt|j tj|jstd!}t|W Y d"}~nd"}~ww | ||}|S td#| }t|)$zPerform action on rule. action, rule and ip_version are usually
           based on return values from parse_command().
        rr   z
logging-onr^   r%   r   zlogging-offr   zdefault-zUnsupported default policy-r)   r$   r   rQ   zstatus-verboseTrV   r   r   zstatus-numberedFr   r   r   Firewall reloadedz&Firewall not enabled (skipping reload)zdelete-r   r   r   r    r   Invalid profile nameNUnsupported action '%s')r   splitr7   r   r^   r   r   r   r   r   r   r   r   rk   ru   r   r   find_application_nameset_portr   r   r:   r+   applicationsvalid_profile_namer   r   )	rn   r   r(   r   r   r{   r   r   rB   rC   rC   rD   	do_actionv  s   

L
J
H

B
@>
<
86
42
0
.


)'
%


zUFWFrontend.do_actionc              
   C   r   )z+Sets default application policy of firewallrr   N)rk   set_default_application_policyr   r   r:   )rn   r   r{   rB   rC   rC   rD   r    r   z*UFWFrontend.set_default_application_policyc                 C   s:   t | jj }|  td}|D ]}|d| 7 }q|S )z*Display list of known application profileszAvailable applications:
  %s)r   rk   profilesr   r   r^   )rn   namesr   rh   rC   rC   rD   get_application_list  s   z UFWFrontend.get_application_listc                 C   s  g }|dkrt | jj }|  ntj|s!td}t	||
| d}|D ]}|| jjvs8| jj| sBtd| }t	|tj|| jj| sUtd}t	||td| 7 }|tdtj| jj|  7 }|tdtj| jj|  7 }tj| jj| }t|d	ksd
|d v r|td7 }n|td7 }|D ]}|d| 7 }q||t|d	  kr|d7 }q*tj|S )zDisplay information on profileallr   rr   zCould not find profile '%s'zInvalid profilezProfile: %s
z
Title: %s
zDescription: %s

r%   ,r   zPorts:zPort:r  z

--

)r   rk   r  r   r   r+   r   r   r^   r   r   verify_profile	get_titleget_description	get_portsr7   r   	wrap_text)rn   pnamer  r   r   namer   r=   rC   rC   rD   get_application_info  sN   





z UFWFrontend.get_application_infoc           	      C   s  d}d}d}z| j jrtj rd}W n ty   d}Y nw |dkrMt| j j }|	  |D ]}| j 
|\}}|rK|dkrE|d7 }||7 }|}q1n| j 
|\}}|dkr]|d7 }|r| j  r|r~z| j   W n tyu    w |td7 }|S |td7 }|S )Refresh application profilerr   TFr  r   r   zSkipped reloading firewall)rk   	do_checksr+   r   	under_sshr;   r   r  r   r   update_app_ruleru   _reload_user_rulesr^   )	rn   rZ   r   allow_reloadtrigger_reloadr  r=   r   foundrC   rC   rD   application_update  sH   zUFWFrontend.application_updatec                 C   s
  d}d}|dkrt d}t|| jjd }|dkr&tjd||f  |S |dkr-d}n|d	kr4d
}n|dkr;d}n
t d| }t|dg}| jjrQ|d |||g7 }zt	|}W n t
ye    w d|jv r{| |j|jd |jd }|S | |jdd}|S )r  rr   r  z%Cannot specify 'all' with '--add-new'default_application_policyskipz'Policy is '%s', not adding profile '%s'acceptr   dropr   r   zUnknown policy '%s'r+   r&   r(   iptype)r^   r   rk   defaultsr+   r   r   ro   r   r9   r;   datar  r   )rn   rZ   r   r   r   r   argsrA   rC   rC   rD   application_add8  sF   

zUFWFrontend.application_addc                 C   s   d}|dkr|  d}|S |dkr|  d}|S |dkr#|  d}|S |dkr.|  d	}|S |d
kr8|  }|S |dkrC| |}|S |dksK|dkrm| |}d}|dkr[| |}|dkrg|dkrg|d7 }|| }|S td| }t|)zzPerform action on profile. action and profile are usually based on
           return values from parse_command().
        rr   zdefault-allowr   zdefault-denyr   zdefault-rejectr   zdefault-skipr  r   r   r   zupdate-with-newr   r   )r  r  r  r  r"  r^   r   )rn   r   rZ   r{   str1str2r   rC   rC   rD   do_application_actionb  s<   






z!UFWFrontend.do_application_actionc                 C   sr   d}| j jr7tj r7td| j| jd }t|t	j
dd t	j   }|dkr7|| jkr7|| jkr7d}|S )z6If running under ssh, prompt the user for confirmationTzWCommand may disrupt existing ssh connections. Proceed with operation (%(yes)s|%(no)s)? rj   rl   Fr   ri   )rk   r  r+   r   r  r^   rj   rl   r   r   r   r   r   r8   r   rm   )rn   r   r   r   rC   rC   rD   continue_under_ssh  s   zUFWFrontend.continue_under_sshc                 C   s   d}t d| j| jd }| jjr!tj r!t d| j| jd }| jjrP|sPttj	|t
jdd t
j   }|dkrP|| jkrP|| jkrPt d}|S | j r\|| d7 }| j }|S )	zReset the firewallrr   zTResetting all rules to installed defaults. Proceed with operation (%(yes)s|%(no)s)? r&  zResetting all rules to installed defaults. This may disrupt existing ssh connections. Proceed with operation (%(yes)s|%(no)s)? Fr   ri   r   )r^   rj   rl   rk   r  r+   r   r  r   r  r   r   r   r   r8   r   rm   ru   r   r   )rn   r   r{   r   r   rC   rC   rD   r     s$   

zUFWFrontend.reset)re   NN)FF)r   )F)__name__
__module____qualname____doc__rq   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r"  r%  r'  r   rC   rC   rC   rD   rc      s0    
6


		H 
M
1V
	.+* rc   )r+  r   r   r   
ufw.commonr   ufw.utilr+   r   r   r   ufw.backend_iptablesr   
ufw.parserr9   rb   rc   rC   rC   rC   rD   <module>   s    >H