U
    \|                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZ G dd dZG dd deZG dd	 d	eZ	G d
d deZ
G dd deZG dd deZG dd deZG dd deZG dd deZG dd dZG dd dZdS )    NUFWError)debugc                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	
UFWCommandz"Generic class for parser commands.c                 C   s,   || _ g | _|| jkr"| j| || _d S N)commandtypesappendtype)selfr
   r    r   ,/usr/lib/python3/dist-packages/ufw/parser.py__init__.   s
    
zUFWCommand.__init__c                 C   s&   t |dk rt t|d  }|S )N   r   )len
ValueErrorUFWParserResponselowerr   argvrr   r   r   parse5   s    zUFWCommand.parsec                 C   s   t dd S )Nz!UFWCommand.help: need to overrider   )r   argsr   r   r   help=   s    zUFWCommand.helpN)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   ,   s   r   c                   @   s0   e Zd ZdZdd Zdd Zdd ZeeZdS )	UFWCommandRulez#Class for parsing ufw rule commandsc                 C   s   d}t | || d S )Nruler   r   r   r   r
   r   r   r   r   C   s    zUFWCommandRule.__init__c               
   C   s  d}d}d}d}d}d}d}d}	d}
d}t |dkrR|d  dkrR||d  t |dkr`|d  dkrt |dkrd}||d  d }zt|d }W n tk
r   |d }Y nX |d k	rtd	| }|S n~|d  d
kr<t |dk rt |d }	|	dks|	dkr.td|	 }t||d= |d= n|d  dkrXd}	|d= |d }|dkr|dkr|dkr|dkrt t |}|dk rt d}|dkr|d  dks|d  dkr|d  }|dkr:|d dkr:|d  dks |d  dkr:|d  }|d= t |}d}|dkr|	ddksh|	ddkrtd}|d  dkr|d  dkrt||dk s|d  dkrt||d= t |}d}d}|r|dkr|d  dks
|d  dkrd}n2|dkrB|d  dks>|d  dkrBd}|dkrf||  }
||= t |}d|krtd}t|d|krtd}t|d}d|kr|
d}|t |d krtd }t|||d  }d!|krtd"}t|||d = ||= t |}|dk s&|d#kr,t |}|
dkrF|d$|
 7 }tjj|dd|tj|d%}|rr||_n2|	dkrz||	 W n tk
r    Y nX |dkrtj|d r
ztj|d  W n4 tk
r   d&}|d |_||d d' Y nX |jdk
rztj|d \}}W n, tk
rZ } zt|W 5 d }~X Y nX td(|sd)|ks~d*|krtd+}t||}z|| ||d' d&}W n& tk
r   td,}t|Y nX n|d d dkrtd-}t|nd.|kr>d/|kr>d|kr>d|kr>td0}t|nd1d.d/d2d3ddg}|	d/dks|	d.dks|	d1dks|	d2dks|	ddks|	ddks|	d3dks|	d3dkr|	d1dkrtd4}t|d}d}|D ]X}|d dkr6|| |kr6td5||  }t||d1kr|d |k rz|||d   W n tk
r|    Y nX ntd6}t|n|dks|dkr,|d |k rzB|dkr|d||d   n|dkr|d||d   W n tk
r    Y nX ntd7| }t|n |d.kr|d |k rzL||d   }|dkrjd8}d}ntj|d9rd:}nd;}|| W n tk
r    Y nX d<}ntd=}t|n|d/k	rZ|d |k 	rHzL||d   }|dk	rd8}d}ntj|d9	rd:}nd;}|| W n tk
	r@    Y nX d'}ntd>}t|n|d2k	sn|d3k
rL|d |k 
r<|dk	rtd?| }t|||d  }|d3k	r|d<k	r||_n||_nFtd(|
sd)|k	sd*|k	rtd+}t||d<k
r|}n|}z||| W n tk

r8    Y nX ntd@}t||d7 }q|dk
rr|dk
rrd&}nN|dk
r|dk
r||k
rtdA}t|n|dk
r|}n|dk
r|}|dk
s|dkr$d}|dkrztj|}W n& tk
r   tdB}t|Y nX |dkr|dks8|dkrrztj|}W n& tk
rn   tdB}t|Y nX nnztj|}W n& tk
r   tdB}t|Y nX |dks||kr|}n|dkrntdC}t||jdkr|| n,|dkr$|j|kr$tdD|j }t||r`|jtjj krV|d&krVt!dE|j  d;}|"| t|}| j#|j$dF< ||j$d< ||j$dG< |S )HN anyFr   r   deleter   Tz	delete-%dinsert   0z-1z#Cannot insert rule at position '%s'Zprependallowdenyrejectlimit   inoutonzInvalid interface clause   logzlog-allzOption 'log' not allowed herez!Option 'log-all' not allowed herecommentz*Option 'comment' missing required argument'zComment may not contain "'"   _)	directionr3   Zbothdstz^\d([0-9,:]*\d+)*$,:zPort ranges must be numericzBad portzWrong number of argumentsfromtozNeed 'to' or 'from' clauseprotoportappzImproper rule syntaxzInvalid token '%s'zInvalid 'proto' clausezInvalid '%s' clause	0.0.0.0/06Zv6Zv4srczInvalid 'from' clausezInvalid 'to' clausezNeed 'from' or 'to' with '%s'zInvalid 'port' clausez%Mixed IP versions for 'from' and 'to'zCould not find protocolzProtocol mismatch (from/to)z,Protocol mismatch with specified protocol %sz*Adjusting iptype to 'v4' for protocol '%s'r
   Ziptype)%r   r   removeint	Exceptionr   r   r6   r   countindexufwcommonZUFWRuleutilZ
hex_encodeZset_positionZapplicationsZvalid_profile_nameZget_services_protodappZset_portZparse_port_protorematchZset_protocolset_interfaceZvalid_addressZset_srcZset_dstsappprotocolZipv4_only_protocolsr   Zverifyr
   data) r   r   actionr   r
   Z	from_typeZto_typeZfrom_serviceZ
to_serviceZ
insert_poslogtyperC   Zrule_numr   err_msgnargsZrule_directionZhas_interfaceZlog_idxr3   Zcomment_idxZrule_actionr>   r=   ekeysilocargZfaddrZsaddrtmpr   r   r   r   G   sj   
**$"





































zUFWCommandRule.parsec                 C   s  | j }| jdks| jdkr| jdks2| jdkr| jdkr| jdkr| jdkr| jdkr| jdkr| jdkr|d| j 7 }| j	dkr|d| j	 7 }| j
dkrd| j
kr|d| j
 7 }q|d| j
 7 }n&|d| j 7 }| jdkr|d	| j 7 }| jdkr|d
|   7 }n| jdkr2|d| j 7 }| jdkrN|d| j 7 }n| jdkrh|d| j 7 }| j	dkr|d| j	 7 }dD ]}|dkr| j}| j}| j}d}n| j}| j}| j
}d}|dks|dkrd}|dks|dks|dkr|d||f 7 }|dkr8d|kr*|d| 7 }n|d| 7 }n|dkr|d| 7 }qd|krd|kr| jdkr| jdkr|d7 }| jdkr| j
dkr| jdkr|d| j 7 }| jdkr|d
|   7 }|S )zGet command string for ruler@   z::/0r#   r"   r/   z %s z '%s'z/%sz comment '%s'z	 in on %sz
 out on %s)rB   r8   rB   r;   r<   z %s %sz	 app '%s'z app %sz port %sz to z from z to anyz	 proto %s)rR   r8   rB   ZsportrO   Zinterface_inZinterface_outZdportr7   rS   rK   rP   r3   Zget_comment)r   resrX   rY   r>   r?   dirr   r   r   get_command  s    








$zUFWCommandRule.get_commandN)r   r   r   r   r   r   r_   staticmethodr   r   r   r   r   A   s      Mr   c                   @   s    e Zd ZdZdd Zdd ZdS )UFWCommandRouteRulez)Class for parsing ufw route rule commandsc                 C   s   t | | d| _d S )Nroute)r   r   r
   )r   r   r   r   r   r     s    zUFWCommandRouteRule.__init__c           	      C   s~  |d dkst d|krl|d}d}t||krlz$t||d   td}t|W n tk
rj   Y nX d }d }d }d|}d|krd	|krd
}|d|d
krd}|||d  }|d|| |||d d   }nFt	d|s,t	d|s,d|ksd|kr,td}t|n|}d|d< t
| |}d|jkrzd|jd _|rz|rz|jd || |S )Nr   rb   r$   r"   r   z9'route delete NUM' unsupported. Use 'delete NUM' instead.r\   z in on z out on r/   r.   r-   r1   z (in|out) on z app (in|out) z in z out z'Invalid interface clause for route ruler   T)AssertionErrorrG   r   rD   r6   r   r   joinrL   searchr   r   rQ   forwardrN   )	r   r   idxrT   Z	rule_argvZ	interfacestripsr   r   r   r   r     sL    

*

zUFWCommandRouteRule.parseNr   r   r   r   r   r   r   r   r   r   ra     s   ra   c                   @   s    e Zd ZdZdd Zdd ZdS )UFWCommandAppz*Class for parsing ufw application commandsc                 C   s   d}t | || d S )Nr?   r    r!   r   r   r   r   Z  s    zUFWCommandApp.__init__c                 C   sP  d}d}d}|d dkrt  |d= t|}|d  }|dksH|dkr|dkrr|d d	krrd
}|d	 t|}|dk rt  t|d d}|r|d7 }|dkr|dkrt  |dkr.|dk rt  |d  dkrd}nL|d  dkrd}n6|d  dkrd}n|d  dkr(d}nt  t|}| j|jd< ||jd< |S )zParse applications command.r"   Fr   r?   infoupdater1   r   z	--add-newTr-   z[']z	-with-newlistdefaultr)   default-allowr*   default-denyr+   default-rejectskipzdefault-skipr
   name)	r   r   r   rC   strrh   r   r
   rQ   )r   r   rt   rR   ZaddnewrU   r   r   r   r   r   ^  sH    


zUFWCommandApp.parseNrj   r   r   r   r   rk   X  s   rk   c                   @   s    e Zd ZdZdd Zdd ZdS )UFWCommandBasicz$Class for parsing ufw basic commandsc                 C   s   d}t | || d S )NZbasicr    r!   r   r   r   r     s    zUFWCommandBasic.__init__c                 C   s   t |dkrt t| |S )Nr   )r   r   r   r   )r   r   r   r   r   r     s    zUFWCommandBasic.parseNrj   r   r   r   r   rv     s   rv   c                   @   s    e Zd ZdZdd Zdd ZdS )UFWCommandDefaultz&Class for parsing ufw default commandsc                 C   s   d}t | || d S )Nro   r    r!   r   r   r   r     s    zUFWCommandDefault.__init__c                 C   sP  t |dk rt d}d}t |dkr|d  dkr|d  dkr|d  dkr|d  dkr|d  dkr|d  dkrt |d  d	rd}nJ|d  d
rd}n2|d  dks|d  dkrd}n|d  }|d  dkrd}n6|d  dkrd}n|d  dkr6d}nt |d| 7 }t|S )Nr-   r"   ZincominginputZroutedrf   outputZoutgoingr.   r/   r   r*   rq   r)   rp   r+   rr   z-%s)r   r   r   
startswithr   )r   r   rR   r7   r   r   r   r     sB     zUFWCommandDefault.parseNrj   r   r   r   r   rw     s   rw   c                   @   s    e Zd ZdZdd Zdd ZdS )UFWCommandLoggingz&Class for parsing ufw logging commandsc                 C   s   d}t | || d S )NZloggingr    r!   r   r   r   r     s    zUFWCommandLogging.__init__c                 C   s   d}t |dk rt n|d  dkr.d}n|d  dks~|d  dks~|d  dks~|d  d	ks~|d  d
krd}|d  dkr|d|d   7 }nt t|S )Nr"   r-   r   Zoffzlogging-offr0   ZlowZmediumZhighZfullz
logging-onr6   r   r   r   r   r   r   rR   r   r   r   r     s"     zUFWCommandLogging.parseNrj   r   r   r   r   r{     s   r{   c                   @   s    e Zd ZdZdd Zdd ZdS )UFWCommandStatusz%Class for parsing ufw status commandsc                 C   s   d}t | || d S )Nstatusr    r!   r   r   r   r     s    zUFWCommandStatus.__init__c                 C   sf   t | |}t|dkr d|_nBt|dkrb|d  dkrDd|_n|d  dkr\d|_nt |S )Nr   r   verbosezstatus-verboseZnumberedzstatus-numbered)r   r   r   rR   r   r   r   r   r   r   r     s    zUFWCommandStatus.parseNrj   r   r   r   r   r~     s   r~   c                   @   s    e Zd ZdZdd Zdd ZdS )UFWCommandShowz#Class for parsing ufw show commandsc                 C   s   d}t | || d S )NZshowr    r!   r   r   r   r     s    zUFWCommandShow.__init__c                 C   s   d}t |dkrt n|d  dkr.d}n|d  dkrDd}n|d  dkrZd}nt|d  d	krpd
}n^|d  dkrd}nH|d  dkrd}n2|d  dkrd}n|d  dkrd}nt t|S )Nr"   r   rawzshow-rawzbefore-ruleszshow-beforez
user-rulesz	show-userzafter-rulesz
show-afterzlogging-ruleszshow-loggingbuiltinszshow-builtinsZ	listeningzshow-listeningZaddedz
show-addedr|   r}   r   r   r   r     s*    zUFWCommandShow.parseNrj   r   r   r   r   r     s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )r   zClass for ufw parser responsec                 C   s    |  | _d| _d| _i | _d S )NF)r   rR   dryrunforcerQ   )r   rR   r   r   r   r     s    
zUFWParserResponse.__init__c                 C   sP   d| j  }t| j }|  |D ]}|d|| j| f 7 }q$|d7 }t|S )Nzaction='%s'z,%s='%s'
)rR   rn   rQ   rW   sortrepr)r   ri   rW   rX   r   r   r   __str__!  s    
zUFWParserResponse.__str__N)r   r   r   r   r   r   r   r   r   r   r     s   r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )	UFWParserzClass for ufw parserc                 C   s
   i | _ d S r   )commands)r   r   r   r   r   .  s    zUFWParser.__init__c                 C   sD   |  t| j krt |  t| j|  kr<t |  S )z=Return command if it is allowed, otherwise raise an exception)r   rn   r   rW   r   )r   r
   cmdr   r   r   allowed_command1  s
    zUFWParser.allowed_commandc           
      C   sz  d}t |dkr2|d  dkr2d}||d  d}t |dkrt|d  dksb|d  dkrtd}||d  d}d}|d  }t |dkr|t| j kr|d  t| j|  kr|}|d  }np|}t| j D ]N}|| j| krt| j| | tr,t| j| | d	d
kr,q|} q8q|dkrFd
}| 	||}| j| | }|
|}	||	_||	_|	S )z(Parse command. Returns a UFWParserActionFr   z	--dry-runTz--forcez-fr"   r   r
   r   )r   r   rC   rn   r   rW   
isinstancer   getattrr   r   r   r   )
r   r   r   r   r   r
   r[   rX   rR   Zresponser   r   r   parse_command;  sF    

zUFWParser.parse_commandc                 C   sz   |j dks|j dkr d|j }n
d|j  }|j| jkrBi | j|j< || j|j krftd| }t||| j|j |< dS )z"Register a command with the parserNr"   z%szCommand '%s' already exists)r   r
   r   r6   r   )r   ckeyrT   r   r   r   register_commandi  s    
zUFWParser.register_commandN)r   r   r   r   r   r   r   r   r   r   r   r   r   ,  s
   
.r   )rL   Zufw.utilrH   Zufw.applicationsZ
ufw.commonr   r   r   r   ra   rk   rv   rw   r{   r~   r   r   r   r   r   r   r   <module>%   s$      YA;. 