3
\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j }xd0D ]}|jt jj| qW xd1D ]}|jt jj| q0W xd2D ]}|jt jj| qPW xd3D ]}|jt jj| qpW xd4D ]}|jt jj| qW xd5D ]}|jt jj	| qW dd!ddd"d#d$g}x2|D ]*}|jt jj
| |jt jj|  qW t| d%krzd&}| | j d'kr8d%}| | j dkrz| | j d(krz| | j |krz| j|d) t| d%k sd'| krt| d*k rtd+ y|j| d&d }W nT tk
r } ztd,|j  W Y dd}~X n$ tk
r   td-d.d/  Y nX |S )6zEParse command. Returns tuple for action, rule, ip_version and dryrun.enabledisablehelp--helpversion	--versionreloadresetlistinfodefaultupdateonofflowmediumhighfullallowdenyrejectNverbosenumberedrawbefore-rules
user-rulesafter-ruleslogging-rulesbuiltins	listeningaddedlimitinsertdeleteprepend      z	--dry-runrouterule   znot enough argsz%szInvalid syntaxF)Zdo_exit)r   r   r	   r
   r   r   r   r   )r   r   r   r   )r   r   r   r   r   r   )r   r   r   )Nr   r   )r   r   r    r!   r"   r#   r$   r%   )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 r>   ./usr/lib/python3/dist-packages/ufw/frontend.pyr5      sL    





&r5   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   r@   Z	statusnumrulesZstatusverboseshowr   ZappcommandsZapplistZappinfoprofileZ	appupdateZ
appdefault)_r/   commonZprogramName)Zhelp_msgr>   r>   r?   get_command_help[   sJ    rH   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r6yt |||d| _W qB tk
r2    Y qBX ntd| td| _td| _td| _d S )NrJ   )rootdirdatadirzUnsupported backend type '%s'nyyes)r   backendr7   r   rF   norO   yes_full)selfdryrunZbackend_typerK   rL   r>   r>   r?   __init__   s    


zUFWFrontend.__init__c          ,   C   s~  d}d}|rd}d}|r$| j j  s4| r8| j j r8d}|ry| j j| j jd d| W n, tk
r } zt|j W Y dd}~X nX d}|r4y| j j  W n, tk
r } z|r|j}W Y dd}~X nX |dkr*y| j j| j jd dd W n. tk
r  } zt|j W Y dd}~X nX t| td	}nFy| j j	  W n. tk
rp } zt|j W Y dd}~X nX td
}|S )zlToggles ENABLED state in <config_dir>/ufw/ufw.conf and starts or
           stops running firewall.
         rQ   rO   FTconfZENABLEDNz0Firewall is active and enabled on system startupz/Firewall stopped and disabled on system startup)
rP   
is_enabledZset_defaultfilesr   r   r6   start_firewallrF   stop_firewall)rS   enabledresZ
config_strZchangedr=   Z	error_strr>   r>   r?   set_enabled   sF    

zUFWFrontend.set_enabledc             C   sf   d}y0| j j||}| j j r2| j j  | j j  W n, tk
r` } zt|j W Y dd}~X nX |S )zSets default policy of firewallrV   N)rP   set_default_policyrX   r[   rZ   r   r   r6   )rS   policy	directionr]   r=   r>   r>   r?   r_      s    

zUFWFrontend.set_default_policyc             C   sF   d}y| j j|}W n, tk
r@ } zt|j W Y dd}~X nX |S )zSets log level of firewallrV   N)rP   set_loglevelr   r   r6   )rS   rA   r]   r=   r>   r>   r?   rb      s    zUFWFrontend.set_loglevelFc             C   sD   y| j j||}W n, tk
r> } zt|j W Y dd}~X nX |S )zShows status of firewallN)rP   
get_statusr   r   r6   )rS   r   Z
show_countoutr=   r>   r>   r?   rc     s
    zUFWFrontend.get_statusr   c             C   sB   y| j j|}W n, tk
r< } zt|j W Y dd}~X nX |S )zShows raw output of firewallN)rP   Zget_running_rawr   r   r6   )rS   Z
rules_typerd   r=   r>   r>   r?   get_show_raw
  s
    zUFWFrontend.get_show_rawc             C   sB  d}yt jj| jj }W n$ tk
r>   td}t|Y nX | jj }t	|j
 }|j  x|D ]}| jj  r|dkrqf|d| 7 }t	|| j
 }|j  xx|D ]n}xf|| | D ]T}	|	d }
|
jd o|
jd rd}|d	| 7 }|
d
ks|
dkr$|d7 }d|	d  }
n|d|
 7 }t jj|
}|dtjj|	d  7 }t jjd|dd ||
ddd}|j|jd |dkr|jd| |j  | jj|}t|dkr|d7 }xL|D ]D}|dkr|d t|k r|d|t jjj||d  f 7 }qW |d7 }qW qW qfW | jj s>t jjd |S )zMShows listening services and incoming rules that might affect
           themrV   zCould not get listening statustcp6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dstra   forward6r   
r+   z   [%2d] %s
z)Skipping tcp6 and udp6 (IPv6 is disabled))rf   rg   )r/   utilZparse_netstat_outputrP   use_ipv6r7   rF   r   	get_rulesr   keyssort
startswithZget_if_from_ipospathbasenamerG   ZUFWRuleset_v6endswithZset_interfaceZ	normalizeZget_matchingr3   r0   r1   get_commanddebug)rS   r]   derr_msgrC   Z	protocolsprotoportsZportitemZaddrZifnamer-   Zmatchingr:   r>   r>   r?   get_show_listening  sd    



zUFWFrontend.get_show_listeningc             C   s   | j j }td}t|dkr*|td S g }xZ| j j D ]L}|jrXdtjjj| }ntjj	j|}||krpq:|j
| |d| 7 }q:W |S )z!Shows added rules to the firewallz9Added user rules (see 'ufw status' for running firewall):r   z
(None)zroute %sz
ufw %s)rP   rq   rF   r3   rl   r/   r0   r2   rz   r1   append)rS   rC   rd   r%   rrstrr>   r>   r?   get_show_added[  s    

zUFWFrontend.get_show_addedc             C   s  d}d}d}g }|j dkr2|jdkr2|j| ng }y|jr|dkrZ| jj|d}n|dkrr| jj|d}n||dkr| jj|d}| jj|d}xV|D ]8}	x2|D ]*}
|
j}d|
_|	j|
s||
_|j|
 qW qW ntd| }t	|t
|dkrR| jj rRtd	}|dkr |}n.|dkr4|d
 }n|dkrN|d | d
 }|S xb|D ]8}|j }|j|_|j|j |j|j |j| qXW n | jj|}|jdkr|j  W n tk
r    Y nX d}d}td}| jjd}| jjd}x$t|D ]\}}|}|j|| kr>|t|jd 7 }t	|y| jj r@|dkr|jdkr|dkr||dkr|dnd}|j| n&|j|kr|t|jd 7 }t	||jd | jj|}q|dkrt|jdkr
|dkr|dkrdnd}|j| nP|j|kr(|j|j|  n2|jdkrZ|j|krZ|t|jd 7 }t	||jd | jj|}q|dkr*|j}|jd |dkr|dkr|dkrdnd}|j| nJ|j r
||kr
| jj|| | d}|dkr |j| n
|jd | jj|}|j rD|dkrD| jjd}|j|d  |jd |dkr|dkrp|dkrpdnd}|j| nV|j r|jdkr|j|kr| jj|jd}|dkr|j||  n
|jd |dkr|d7 }|j r|j|kr|dkr|j|j|  || jj|7 }ntd| }t	|n|jdkrr|dkrd|dkrddnd}|j| |dks|dkr|jd | jj|}n0|dkrtd}t	|ntd| }t	|W n0 t	k
r  } z|j}d}P W Y dd}~X nX |jrtd}tj | qW |s2||7 }nt
|dkrJt!| nd}t"t#|d }|j  xx|D ]p}|dkrl|| rl|| j }d|_y| j|| W n2 tk
r   d}td|j$  }t | Y nX qlW |td7 }|r |td7 }n|td7 }t	||S )zUpdates firewall with rulerV   v4Fv6TZbothzInvalid IP version '%s'r   z"Could not delete non-existent rulez (v6)rn   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.r   r   r   r   r   )%dappsappr   removerP   Zget_app_rules_from_systemr   matchrF   r   r3   rT   Zdup_ruleZ
set_actionrj   Zset_logtypeZlogtypeZget_app_rules_from_templateZpositionreverser7   Zget_rules_count	enumeratestrrp   Zset_positionrx   set_ruleZfind_other_positionr6   updatedwarningsr   r   r   rangeZformat_rule)rS   r-   
ip_versionr]   r}   tmprC   ZtmprulesZ	tmprules6xrN   Zprev6r   countZ	set_errorZpos_err_msgZnum_v4Znum_v6r:   ZbeginZuser_posr9   r=   Zwarn_msgZ
undo_errorZindexesjZbackout_ruler>   r>   r?   r   x  s<   


































zUFWFrontend.set_rulec             C   s^  yt |}W n( tk
r4   td| }t|Y nX | jj }|dksT|t|krhtd| }t|| jj|}|std| }t|d|_d}|j	rd}d}|s:|j
rdtjjj| }	ntjjj|}	td|	| j| jd	 }
t|
tjd
d tjj j j }|dkr:|| jj kr:|| jj kr:d
}d}|rR| j||}ntd}|S )zDelete rulezCould not find rule '%s'r   zCould not find rule '%d'Tr   r   zroute %sz=Deleting:
 %(rule)s
Proceed with operation (%(yes)s|%(no)s)? )r-   rO   rQ   F)outputnewlinerN   rV   Aborted)intr7   rF   r   rP   rq   r3   Zget_rule_by_numberr   r   rl   r/   r0   r2   rz   r1   rO   rQ   r   sysstdoutstdinreadliner4   striprR   r   )rS   rB   forcerM   r}   rC   r-   r   proceedr   promptansr]   r>   r>   r?   delete_ruleD  sJ    
zUFWFrontend.delete_rulec       	      C   sV  d}|j drB|jd}t|dkr4| j|d }n
| jd}n|dkrX| jd}n|j drtd	}|jd
}t|dkrt|| j|d |d }n|dkr| j|}n|dkr| j }n|dkr| jd}nr|j dr0|jd
d }|dkr| j	 }n|dkr"| j
 }n
| j|}n"|dkrJ| jdd}n|dkrb| jd}n|dkrz| jd}n|dkr| jj r| jd | jd td}ntd}n|j dr| j|jd
d |}nr|dks|dks|dks|dkr>|jdkry0| jj|j}||jkrB||_|j|d  W nV tk
r } z8|jsjt|j tjj|jstd!}t|W Y d"d"}~X nX |jdkr0y0| jj|j}||jkr||_|j|d  W nV tk
r. } z8|jst|j tjj|jstd!}t|W Y d"d"}~X nX | j||}ntd#| }t||S )$zPerform action on rule. action, rule and ip_version are usually
           based on return values from parse_command().
        rV   z
logging-onrF   r+   r   zlogging-offr   zdefault-zUnsupported default policy-r.   r*   r   r@   zstatus-verboseTrD   r$   r%   zstatus-numberedFr   r   r   zFirewall reloadedz&Firewall not enabled (skipping reload)zdelete-r   r   r   r&   rk   zInvalid profile nameNzUnsupported action '%s')rt   splitr3   rb   rF   r   r_   r   rc   r   r   re   r^   rP   rX   r   r   Zfind_application_nameZset_portr   r   r6   r/   applicationsvalid_profile_namer   r   )	rS   rj   r-   r   r   r]   r   r}   r=   r>   r>   r?   	do_actionu  s    

















zUFWFrontend.do_actionc             C   sF   d}y| j j|}W n, tk
r@ } zt|j W Y dd}~X nX |S )z+Sets default application policy of firewallrV   N)rP   set_default_application_policyr   r   r6   )rS   r`   r]   r=   r>   r>   r?   r     s    z*UFWFrontend.set_default_application_policyc             C   s>   t | jjj }|j  td}x|D ]}|d| 7 }q&W |S )z*Display list of known application profileszAvailable applications:z
  %s)r   rP   profilesrr   rs   rF   )rS   namesr   rM   r>   r>   r?   get_application_list  s    
z UFWFrontend.get_application_listc             C   s  g }|dkr&t | jjj }|j  n&tjj|sBtd}t	||j
| d}x4|D ]*}|| jjksx| jj|  rtd| }t	|tjj|| jj| std}t	||td| 7 }|tdtjj| jj|  7 }|tdtjj| jj|  7 }tjj| jj| }t|d	ks2d
|d kr@|td7 }n|td7 }x|D ]}|d| 7 }qRW ||t|d	  krX|d7 }qXW tjj|S )zDisplay information on profileallzInvalid profile namerV   zCould not find profile '%s'zInvalid profilezProfile: %s
z
Title: %s
zDescription: %s

r+   ,r   zPorts:zPort:z
  %sz

--

)r   rP   r   rr   rs   r/   r   r   rF   r   r   Zverify_profileZ	get_titleZget_descriptionZ	get_portsr3   ro   	wrap_text)rS   Zpnamer   r}   r   namer   r9   r>   r>   r?   get_application_info  sB    


z UFWFrontend.get_application_infoc       	      C   s  d}d}d}y| j jr$tjj r$d}W n tk
r>   d}Y nX |dkrt| j jj }|j	  x^|D ]4}| j j
|\}}|rf|dkr|d7 }||7 }|}qfW n | j j
|\}}|dkr|d7 }|o| j j r|r
y| j j  W n tk
r    Y nX |td7 }n|td7 }|S )zRefresh application profilerV   TFr   rn   zFirewall reloadedzSkipped reloading firewall)rP   	do_checksr/   ro   	under_sshr7   r   r   rr   rs   Zupdate_app_rulerX   Z_reload_user_rulesrF   )	rS   rE   r   Zallow_reloadZtrigger_reloadr   r9   r   foundr>   r>   r?   application_update  s<    


zUFWFrontend.application_updatec             C   s  d}d}|dkr t d}t|| jjd }|dkrLtjjd||f  |S |dkrZd}n0|d	krhd
}n"|dkrvd}nt d| }t|dg}| jjr|jd |||g7 }yt	|}W n t
k
r    Y nX d|jkr| j|j|jd |jd }n| j|jdd}|S )zRefresh application profilerV   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/   z	--dry-runr-   Ziptype)rF   r   rP   Zdefaultsr/   ro   r{   rT   r   r5   r7   datar   rj   )rS   rE   r   r`   r}   r   argsr<   r>   r>   r?   application_add7  s>    

zUFWFrontend.application_addc             C   s   d}|dkr| j d}n|dkr,| j d}n|dkr@| j d}n|dkrT| j d	}n|d
krf| j }nz|dkrz| j|}nf|dks|dkr| j|}d}|dkr| j|}|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().
        rV   zdefault-allowr   zdefault-denyr   zdefault-rejectr   zdefault-skipr   r   r   r   zupdate-with-newrn   zUnsupported action '%s')r   r   r   r   r   rF   r   )rS   rj   rE   r]   Zstr1Zstr2r}   r>   r>   r?   do_application_actiona  s0    



z!UFWFrontend.do_application_actionc             C   sr   d}| j jrntjj rntd| j| jd }t|t	j
dd t	jj j 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)? )rO   rQ   F)r   r   rN   )rP   r   r/   ro   r   rF   rO   rQ   r   r   r   r   r   r4   r   rR   )rS   r   r   r   r>   r>   r?   continue_under_ssh  s    zUFWFrontend.continue_under_sshc             C   s   d}t d| j| jd }| jjrBtjj rBt d| j| jd }| jjr| rttjj	|t
jdd t
jj j j }|dkr|| jkr|| jkrt d}|S | jj r|| jd7 }| jj }|S )	zReset the firewallrV   zTResetting all rules to installed defaults. Proceed with operation (%(yes)s|%(no)s)? )rO   rQ   zResetting all rules to installed defaults. This may disrupt existing ssh connections. Proceed with operation (%(yes)s|%(no)s)? F)r   r   rN   r   )rF   rO   rQ   rP   r   r/   ro   r   r   r   r   r   r   r   r4   r   rR   rX   r^   r   )rS   r   r]   r   r   r>   r>   r?   r     s     

zUFWFrontend.reset)rJ   NN)FF)r   )F)F)F)__name__
__module____qualname____doc__rU   r^   r_   rb   rc   re   r   r   r   r   r   r   r   r   r   r   r   r   r   r>   r>   r>   r?   rI      s,    
6

	
	H M
1
V
	.+* rI   )r   ru   r   r   Z
ufw.commonr   Zufw.utilr/   r   r   r   Zufw.backend_iptablesr   Z
ufw.parserr5   rH   rI   r>   r>   r>   r?   <module>   s   >G