U
    \l                     @   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| qFdD ]}|t j| qbdD ]}|t j| q~dD ]}|t j	| qddd	d
dddg}|D ](}|t j
| |t j| qt| dkr\d}| |  dkrd}| |  dkr\| |  dkr\| |  |kr\| |d t| dk sd| krt| dk rtd z|| dd }W nT tk
r } ztd|j  W 5 d}~X Y n$ tk
r   tddd  Y nX |S )zEParse command. Returns tuple for action, rule, ip_version and dryrun.)enabledisablehelpz--helpversionz	--versionreloadreset)listinfodefaultupdate)onoffZlowZmediumZhighZfull)allowdenyreject)NverboseZnumbered)rawzbefore-rulesz
user-ruleszafter-ruleszlogging-rulesbuiltins	listeningaddedr   limitr   r   insertdeleteprepend      	--dry-runr   routerule   znot enough argsNz%szInvalid syntaxF)Zdo_exit)ufwparserZ	UFWParserZregister_commandZUFWCommandBasicZUFWCommandAppZUFWCommandLoggingZUFWCommandDefaultZUFWCommandStatusZUFWCommandShowUFWCommandRuleUFWCommandRouteRulelenlowerr   r   parse_commandr   value	Exception)argvpiZrule_commandsidxpre r4   ./usr/lib/python3/dist-packages/ufw/frontend.pyr+      sN    
&r+   c               &   C   s\   t 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!d"d#d$# } | 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
 %(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
ZCOMMANDZCommandsr   r   zdefault ARGzlogging LEVELZLEVELz
allow ARGSr#   z	deny ARGSzreject ARGSz
limit ARGSzdelete RULE|NUMZRULEzinsert NUM RULEzprepend RULEz
route RULEzroute delete RULE|NUMzroute insert NUM RULEZNUMr   r   statuszstatus numberedZRULESzstatus verbosezshow ARGr
   zApplication profile commandszapp listzapp info PROFILEZPROFILEzapp update PROFILEzapp default ARG)#ZprognameZcommandZcommandsr   r   r   Zlogginglevelr   r#   r   r   r   r   Zuruler   r   r"   zroute-deletezroute-insertnumberr   r   r6   Z	statusnumrulesZstatusverboseshowr
   ZappcommandsZapplistZappinfoprofileZ	appupdateZ
appdefault)_r%   commonZprogramName)Zhelp_msgr4   r4   r5   get_command_help[   sN    Br>   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d0ddZdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd1d*d+ZdS )2UFWFrontendZUIiptablesNc                 C   sd   |dkr6zt |||d| _W qB tk
r2    Y qBX ntd| td| _td| _td| _d S )Nr@   )rootdirdatadirzUnsupported backend type '%s'nyyes)r   backendr-   r   r<   norE   yes_full)selfdryrunZbackend_typerA   rB   r4   r4   r5   __init__   s    


zUFWFrontend.__init__c              
   C   sz  d}d}|rd}d}|r"| j  r0|s4| j  r4d}|rz| j | j jd d| W n, tk
r } zt|j W 5 d}~X Y nX d}|r0z| j   W n, tk
r } z|r|j}W 5 d}~X Y nX |dkr&z| j | j jd dd W n. tk
r } zt|j W 5 d}~X Y nX t| td	}nFz| j 	  W n. tk
rl } zt|j W 5 d}~X Y nX td
}|S )zlToggles ENABLED state in <config_dir>/ufw/ufw.conf and starts or
           stops running firewall.
         rG   rE   FTconfZENABLEDNz0Firewall is active and enabled on system startupz/Firewall stopped and disabled on system startup)
rF   
is_enabledZset_defaultfilesr   r   r,   start_firewallr<   stop_firewall)rI   enabledresZ
config_strZchangedr3   Z	error_strr4   r4   r5   set_enabled   sT     
 
zUFWFrontend.set_enabledc              
   C   sf   d}z0| j ||}| j  r2| j   | j   W n, tk
r` } zt|j W 5 d}~X Y nX |S )zSets default policy of firewallrL   N)rF   set_default_policyrN   rQ   rP   r   r   r,   )rI   policy	directionrS   r3   r4   r4   r5   rU      s    

zUFWFrontend.set_default_policyc              
   C   sF   d}z| j |}W n, tk
r@ } zt|j W 5 d}~X Y nX |S )zSets log level of firewallrL   N)rF   set_loglevelr   r   r,   )rI   r7   rS   r3   r4   r4   r5   rX      s    zUFWFrontend.set_loglevelFc              
   C   sD   z| j ||}W n, tk
r> } zt|j W 5 d}~X Y nX |S )zShows status of firewallN)rF   
get_statusr   r   r,   )rI   r   Z
show_countoutr3   r4   r4   r5   rY     s
    zUFWFrontend.get_statusr   c              
   C   sB   z| j |}W n, tk
r< } zt|j W 5 d}~X Y nX |S )zShows raw output of firewallN)rF   Zget_running_rawr   r   r,   )rI   Z
rules_typerZ   r3   r4   r4   r5   get_show_raw
  s
    zUFWFrontend.get_show_rawc                 C   s$  d}zt j| j }W n$ tk
r>   td}t|Y nX | j }t	|
 }|  |D ]}| j s||dkr|qb|d| 7 }t	|| 
 }|  |D ]^}|| | D ]J}	|	d }
|
ds|
dsd}|d| 7 }|
d	ks|
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}|dkr|d t|k r|d|t jj||d  f 7 }q|d7 }qqqb| j s t jd |S )zMShows listening services and incoming rules that might affect
           themrL   zCould not get listening status)Ztcp6Zudp6z%s:
Zladdrz127.z::1z  %s z0.0.0.0z::z* z%s/0z%s z(%s)exer   Nr$   inF)actionZprotocolZdportdstrW   forward6r   
r    z   [%2d] %s
z)Skipping tcp6 and udp6 (IPv6 is disabled))r%   utilZparse_netstat_outputrF   use_ipv6r-   r<   r   	get_rulesr   keyssort
startswithZget_if_from_ipospathbasenamer=   ZUFWRuleset_v6endswithZset_interfaceZ	normalizeZget_matchingr)   r&   r'   get_commanddebug)rI   rS   derr_msgr9   Z	protocolsprotoportsZportitemZaddrZifnamer#   Zmatchingr0   r4   r4   r5   get_show_listening  sl    






zUFWFrontend.get_show_listeningc                 C   s   | j  }td}t|dkr*|td S g }| j  D ]L}|jrVdtjj| }ntjj	|}||krnq8|
| |d| 7 }q8|S )z!Shows added rules to the firewallz9Added user rules (see 'ufw status' for running firewall):r   z
(None)route %sz
ufw %s)rF   re   r<   r)   r`   r%   r&   r(   rn   r'   append)rI   r9   rZ   r   rrstrr4   r4   r5   get_show_added[  s     

zUFWFrontend.get_show_addedc                 C   s  d}d}d}g }|j dkr2|jdkr2|| ng }zt|jr|dkrZ| j|d}n|dkrr| j|d}nt|dkr| j|d}| j|d}|D ]4}	|D ]*}
|
j}d|
_|	|
s||
_||
 qqntd| }t	|t
|dkrJ| jjsJtd	}|dkr|}n.|dkr*|d
 }n|dkrD|d | d
 }|W S |D ]8}| }|j|_||j ||j || qNn | j|}|jdkr|  W n tk
r    Y nX d}d}td}| jd}| jd}t|D ]\}}|}|j|| kr.|t|jd 7 }t	|z| j r(|dkr|jdkr||dkrl|dkrldnd}|| n&|j|kr|t|jd 7 }t	||d | j|}q|dkrd|jdkr|dkr|dkrdnd}|| nP|j|kr||j|  n2|jdkrJ|j|krJ|t|jd 7 }t	||d | j|}q|dkr|j}|d |dkr|dkr|dkrdnd}|| nH|js||kr| j|| | d}|dkr|| n
|d | j|}|js0|dkr0| jd}||d  |d |dkrl|dkr\|dkr\dnd}|| nT|js|jdkr|j|kr| j|jd}|dkr|||  n
|d |dkr|d7 }|js |j|kr |dkr ||j|  || j|7 }ntd| }t	|n|jdkrZ|dkrL|dkrLdnd}|| |dksn|dkr|d | j|}n0|dkrtd}t	|ntd| }t	|W n: t	k
r } z|j}d}W Y 
 qW 5 d}~X Y nX |jrtd}t | q|s"||7 }nt
|dkr:t!| nd}t"t#|d }|  |D ]p}|dkrZ|| rZ||  }d|_z| || W n2 tk
r   d}td|$  }t | Y nX qZ|td7 }|r|td7 }n|td7 }t	||S )zUpdates firewall with rulerL   v4Fv6TZbothzInvalid IP version '%s'r   z"Could not delete non-existent rulez (v6)rb   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sapprw   removerF   Zget_app_rules_from_systemr|   matchr<   r   r)   rJ   Zdup_ruleZ
set_actionr^   Zset_logtypeZlogtypeZget_app_rules_from_templateZpositionreverser-   Zget_rules_count	enumeratestrrd   Zset_positionrl   set_ruleZfind_other_positionr,   updatedwarningsr   r   r   rangeZformat_rule)rI   r#   
ip_versionrS   rq   tmpr9   ZtmprulesZ	tmprules6xrD   Zprev6rx   countZ	set_errorZpos_err_msgZnum_v4Znum_v6r0   ZbeginZuser_posr/   r3   Zwarn_msgZ
undo_errorZindexesjZbackout_ruler4   r4   r5   r   x  sX       












 














zUFWFrontend.set_rulec                 C   s^  zt |}W n( tk
r4   td| }t|Y nX | j }|dksT|t|krhtd| }t|| j|}|std| }t|d|_d}|j	rd}d}|s:|j
rd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r:d
}d}|rR| ||}ntd}|S )zDelete rulezCould not find rule '%s'r   zCould not find rule '%d'Tr{   r|   rv   z=Deleting:
 %(rule)s
Proceed with operation (%(yes)s|%(no)s)? )r#   rE   rG   FoutputnewlinerD   rL   Aborted)intr-   r<   r   rF   re   r)   Zget_rule_by_numberr   r|   r`   r%   r&   r(   rn   r'   rE   rG   r   sysstdoutstdinreadliner*   striprH   r   )rI   r8   forcerC   rq   r9   r#   r   proceedry   promptansrS   r4   r4   r5   delete_ruleD  sR    
zUFWFrontend.delete_rulec           	   
   C   sV  d}| drB|d}t|dkr4| |d }n
| d}n|dkrX| d}n| drtd	}|d
}t|dkrt|| |d |d }n|dkr| |}n|dkr|  }n|dkr| d}nr| dr0|d
d }|dkr| 	 }n|dkr"| 
 }n
| |}n"|dkrJ| dd}n|dkrb| d}n|dkrz| d}n|dkr| j r| d | d td}ntd}n| dr| |d
d |}nr|dks|dks|dks|dkr>|jdkrz0| j|j}||jkrB||_||d  W nV tk
r } z6|jsjt|j tj|jstd!}t|W 5 d"}~X Y nX |jdkr0z0| j|j}||jkr||_||d  W nV tk
r. } z6|jst|j tj|jstd!}t|W 5 d"}~X Y nX | ||}ntd#| }t||S )$zPerform action on rule. action, rule and ip_version are usually
           based on return values from parse_command().
        rL   z
logging-onr<   r    r   zlogging-offr   zdefault-zUnsupported default policy-r$   r   r   r6   zstatus-verboseTr:   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')rh   splitr)   rX   r<   r   rU   r   rY   ru   rz   r[   rT   rF   rN   r   r   Zfind_application_nameZset_portr   r   r,   r%   applicationsvalid_profile_namer   r   )	rI   r^   r#   r   r   rS   r   rq   r3   r4   r4   r5   	do_actionu  s    
















zUFWFrontend.do_actionc              
   C   sF   d}z| j |}W n, tk
r@ } zt|j W 5 d}~X Y nX |S )z+Sets default application policy of firewallrL   N)rF   set_default_application_policyr   r   r,   )rI   rV   rS   r3   r4   r4   r5   r     s    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   rF   profilesrf   rg   r<   )rI   namesry   rC   r4   r4   r5   get_application_list  s    z UFWFrontend.get_application_listc                 C   s  g }|dkr&t | jj }|  n&tj|sBtd}t	||
| d}|D ]$}|| jjksr| jj| std| }t	|tj|| jj| st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s,d
|d kr:|td7 }n|td7 }|D ]}|d| 7 }qJ||t|d	  krT|d7 }qTtj|S )zDisplay information on profileallr   rL   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   rF   r   rf   rg   r%   r   r   r<   r   rw   Zverify_profileZ	get_titleZget_descriptionZ	get_portsr)   rc   	wrap_text)rI   Zpnamer   rq   ry   namers   r/   r4   r4   r5   get_application_info  sL    







z UFWFrontend.get_application_infoc           	      C   s  d}d}d}z| j jr$tj r$d}W n tk
r>   d}Y nX |dkrt| j j }|	  |D ]4}| j 
|\}}|rd|dkr|d7 }||7 }|}qdn | j 
|\}}|dkr|d7 }|r| j  r|rz| j   W n tk
r    Y nX |td7 }n|td7 }|S )Refresh application profilerL   TFr   rb   r   zSkipped reloading firewall)rF   	do_checksr%   rc   	under_sshr-   r   r   rf   rg   Zupdate_app_rulerN   Z_reload_user_rulesr<   )	rI   r;   ry   Zallow_reloadZtrigger_reloadr   r/   r   foundr4   r4   r5   application_update  s<    
zUFWFrontend.application_updatec                 C   s  d}d}|dkr t d}t|| jjd }|dkrLtjd||f  |S |dkrZd}n0|d	krhd
}n"|dkrvd}nt d| }t|dg}| jjr|d |||g7 }zt	|}W n t
k
r    Y nX d|jkr| |j|jd |jd }n| |jdd}|S )r   rL   r   z%Cannot specify 'all' with '--add-new'Zdefault_application_policyskipz'Policy is '%s', not adding profile '%s'Zacceptr   Zdropr   r   zUnknown policy '%s'r%   r!   r#   Ziptype)r<   r   rF   defaultsr%   rc   ro   rJ   rw   r+   r-   datar   r^   )rI   r;   ry   rV   rq   r   argsr2   r4   r4   r5   application_add7  sB    

zUFWFrontend.application_addc                 C   s   d}|dkr|  d}n|dkr,|  d}n|dkr@|  d}n|dkrT|  d	}n|d
krf|  }nz|dkrz| |}nf|dks|dkr| |}d}|dkr| |}|dkr|dkr|d7 }|| }ntd| }t||S )zzPerform action on profile. action and profile are usually based on
           return values from parse_command().
        rL   zdefault-allowr   zdefault-denyr   zdefault-rejectr   zdefault-skipr   r   r   r   zupdate-with-newrb   r   )r   r   r   r   r   r<   r   )rI   r^   r;   rS   Zstr1Zstr2rq   r4   r4   r5   do_application_actiona  s0    



z!UFWFrontend.do_application_actionc                 C   sr   d}| j jrntj rntd| j| jd }t|t	j
dd t	j   }|dkrn|| jkrn|| jkrnd}|S )z6If running under ssh, prompt the user for confirmationTzWCommand may disrupt existing ssh connections. Proceed with operation (%(yes)s|%(no)s)? rE   rG   Fr   rD   )rF   r   r%   rc   r   r<   rE   rG   r   r   r   r   r   r*   r   rH   )rI   r   r   r   r4   r4   r5   continue_under_ssh  s    zUFWFrontend.continue_under_sshc                 C   s   d}t d| j| jd }| jjrBtj rBt d| j| jd }| jjr|sttj	|t
jdd t
j   }|dkr|| jkr|| jkrt d}|S | j r|| d7 }| j }|S )	zReset the firewallrL   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   rD   r   )r<   rE   rG   rF   r   r%   rc   r   r   r   r   r   r   r   r*   r   rH   rN   rT   r   )rI   r   rS   r   r   r4   r4   r5   r     s$    

zUFWFrontend.reset)r@   NN)FF)r   )F)F)F)__name__
__module____qualname____doc__rK   rT   rU   rX   rY   r[   ru   rz   r   r   r   r   r   r   r   r   r   r   r   r4   r4   r4   r5   r?      s0       
6

	
	H M
1
V
	.+* r?   )r   ri   r   r   Z
ufw.commonr   Zufw.utilr%   r   r   r   Zufw.backend_iptablesr   Z
ufw.parserr+   r>   r?   r4   r4   r4   r5   <module>   s   >G