
    #fd$                     "   d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlZddlmZ ddlmZmZ dZdZg dZg dZd	d
gZd Zd Zd Zd Zd Zd;dZd Z d Z!d Z"d Z#d<dZ$d Z%d Z&d Z'd<dZ(d Z)ej*        dfdZ+d Z,d Z-d  Z.d! Z/ e	j0                    fd"Z1 e	j0                    fd#Z2d$ Z3d% Z4d& Z5d' Z6d( Z7d) Z8d* Z9d+ Z:d=d,Z;d>d-Z<d. Z=d?d/Z>d0 Z?d1 Z@d2 ZAd3 ZBd4 ZCd5 ZDd6 ZEd7 ZFd@d9ZGd: ZHdS )Az"util.py: utility functions for ufw    )print_functionN)reduce)mkstempmktempF)tcpudpipv6espahigmpgrevrrp)r	   r
   r   r   r   r   r	   r   c                 
   d}	 t          j        |            n# t          $ r  w xY w	 t          j        | d           d}n# t          $ r Y nw xY w	 t          j        | d           |dk    rd}nd}n# t          $ r Y nw xY w|S )z8Get the protocol for a specified port from /etc/services r   r   any)socketgetservbyname	Exception)portprotos     */usr/lib/python3/dist-packages/ufw/util.pyget_services_protor   .   s    ET""""   T5)))   T5)))E>>EEE    Ls+    %A 
AA A3 3
B ?B c                 P   d}d}|                      d          }t          |          dk    r|d         }d}nlt          |          dk    r;|d         }|d         }|t          v r!t          d|z            }t	          |          nt          d          }t	          |          ||fS )	zParse port or port and protocolr   /   r   r      zInvalid port with protocol '%s'zBad port)splitlenportless_protocols_
ValueError)p_strr   r   tmperr_msgs        r   parse_port_protor%   H   s    DE
++c

C
3xx1}}1v	SQ1vA&&&9EABBGW%%% ' J--!!!%=    c                    t           j        st          d           dS t          |           dk    st	          j        d|           sdS |                     d          }	 t          j        t           j        |d                    n# t          $ r Y dS w xY wt          |          dk    rdS t          |          dk    rt          |d         d	          sdS d	S )
zVerifies if valid IPv6 addressz"python does not have IPv6 support.F+   z^[a-fA-F0-9:\./]+$r   r   r   r   T)r   has_ipv6warnr   rematchr   	inet_ptonAF_INET6r   _valid_cidr_netmaskaddrnets     r   valid_address6r3   \   s    ? 1222u 4yy2~~RX&;TBB~u
**S//C#a&1111   uu 3xx!||u	SQ"3q6400 	54s   %B 
BBc                    t          |           dk    st          j        d|           sdS |                     d          }	 t	          j        t          j        |d                    t          |d         d          sdS n# t          $ r Y dS w xY wt          |          dk    rdS t          |          dk    rt          |d         d          sdS dS )	zVerifies if valid IPv4 address   z^[0-9\./]+$Fr   r   r   r   T)
r   r+   r,   r   r   r-   AF_INET_valid_dotted_quadsr   valid_netmaskr0   s     r   valid_address4r9   v   s     4yy2~~RXnd;;~u
**S//CQ000"3q6511 	5	   uu 3xx!||u	SQSVU++ 	54s   ;A? ?
BBc                 B    t          | |          pt          | |          S )z(Verifies if valid cidr or dotted netmask)r/   r7   )nmv6s     r   r8   r8      s"    r2&&E*=b"*E*EEr&   r   c                     |dk    rt          |           S |dk    rt          |           S |dk    rt          |           pt          |           S t          )zValidate IP addresses64r   )r3   r9   r!   )r1   versions     r   valid_addressrA      s\    #~~d###	Cd###	E		d##;~d';';;
r&   c                 0   g }d}d}t           j        }|rd}t           j        }d| v rE|                     d          }|r|d         dk    r|d= n3|s|d         dk    s|d         dk    r|d= n|                    |            |sTt          |          d	k    rAt          |d         |          r+	 t          |d         |          |d<   n# t          $ r Y nw xY w|d
         }t          j	        |t          j
        ||                    }||d
         k    rd}t          |          d	k    rA|d|d         z   z  }|s1t          |          }||k    rd|d|d}t          |           |}d}t          ||          sd|z  }t          |           t          ||fS )zConvert address to standard form. Use no netmask for IP addresses. If
       netmask is specified and not all 1's, for IPv4 use cidr if possible,
       otherwise dotted netmask and for IPv6, use cidr.
    Fr?   r>   r   r   12832z255.255.255.255r   r   TzUsing 'z' for address ''zInvalid address '%s')r   r6   r.   r   appendr   r7   _dotted_netmask_to_cidrr   	inet_ntopr-   _address4_to_networkdebugrA   r!   )	origr<   r2   changedr@   s_typer1   networkdbg_msgs	            r   normalize_addressrP      s   
 CGG^F	 !
d{{jjoo 	#a&E//A 	Q43q65F+F+FA

4 #c((a--$7A$C$C-	,SVR88CFF 	 	 	D	 q6D FF$4VT$B$BCCDs1v~~
3xx1}}c!f 	*400G$;B77DDDIgw'' (D1g'?s   -C 
CCc                 "    t          | d          S )z"Opens the specified file read-onlyr)open)fns    r   open_file_readrU      s    C==r&   c                     t          |           }	 t                      \  }}n## t          $ r |                                  w xY w|| ||dS )z=Opens the specified file read-only and a tempfile read-write.)rK   orignamer#   tmpname)rU   r   r   close)rT   rK   r#   rX   s       r   
open_filesrZ      sb    "D gg   

 r#'KKKs	   #  Ac                    |dk    rdS | st          t          j        d          t          r>| t          j                                        k    rt                              |           dS d}t          j        d         dk    r$t          j        | t          |d                    }nt          j        | |          }|dk    rt          t          j        d          dS )	z~Write to the file descriptor and error out of 0 bytes written. Intended
       to be used with open_files() and close_files().r   NzNot a valid file descriptorr      asciiz"Could not write to file descriptor)OSErrorerrnoENOENT
msg_outputsysstdoutfilenowriteversion_infoosbytesEIO)fdoutrcs      r   write_to_filern      s     byy Cel$ABBB  bCJ--////	B
aXb%W--..Xb#	Qwwei!EFFF wr&   Tc                 *   | d                                           t          j         | d                    |rBt          j        | d         | d                    t          j        | d         | d                    t          j        | d                    dS )zuCloses the specified files (as returned by open_files), and update
       original file with the temporary file.
    rK   r#   rW   rX   N)rY   rh   shutilcopystatcopyunlink)fnsupdates     r   close_filesrv     s     KHSZ 5JY888C	NC
O444Ic)nr&   c                 ,   t          |            	 t          j        | t          j        t          j        d          }n(# t
          $ r}dt          |          gcY d}~S d}~ww xY w|                                d         }|j        t          |          gS )z!Try to execute the given command.T)rd   stderruniversal_newlines   Nr   )	rJ   
subprocessPopenPIPESTDOUTr_   strcommunicate
returncode)commandspexrl   s       r   cmdr     s    	'NNNgjo%/%6157 7 7    SWW~ ..

1
CM3s88$$s   ,> 
A#AA#A#c                 ,   	 t          j        | t           j                  }t          j        ||j                  }n(# t          $ r}dt          |          gcY d}~S d}~ww xY w|                                d         }|j        t          |          gS )z#Try to pipe command1 into command2.)rd   )stdinrz   Nr   )r{   r|   r}   rd   r_   r   r   r   )command1command2sp1sp2r   rl   s         r   cmd_piper   $  s    x
@@@xsz:::   SWW~ //

A
CNCHH%%s   ;> 
A#AA#A#c                 r   	 | j         }n# t          $ r | }Y nw xY w	 |                    dd          }n# t          $ r |}Y nw xY wt          r4t	          j        t          j                  r|                    |           n"|                    t          |                     | 
                                 dS )zQImplement our own print statement that will output utf-8 when
       appropriate.utf-8ignoreN)bufferr   encoderb   inspectisclassioStringIOrf   ri   flush)outputswriterrl   s       r   _printr   2  s       hhw))     !gobk22 !QU3ZZ   
LLNNNNNs   
 4 AAc                     	 t          t          j        d| z             n# t          $ r Y nw xY w|rt          j        d           dS dS )zPrint error message and exitz
ERROR: %s
r   N)r   rc   rx   IOErrorexit)rl   do_exits     r   errorr   G  sf    sz=3.////      s     
--c                 d    	 t          t          j        d| z             dS # t          $ r Y dS w xY w)zPrint warning messagez	WARN: %s
N)r   rc   rx   r   rl   s    r   r*   r*   R  sF    sz<#-.....   s   ! 
//c                     t           r|t          j        k    rt           }	 |rt          |d| z             dS t          |d| z             dS # t          $ r Y dS w xY w)zPrint messagez%s
%sN)rb   rc   rd   r   r   )rl   r   newlines      r   msgr   Z  s~     f
** 	'66C<(((((64#:&&&&&   s   A A 
AAc                 v    t           r1	 t          t          j        d| z             dS # t          $ r Y dS w xY wdS )zPrint debug messagez
DEBUG: %s
N)	DEBUGGINGr   rc   rx   r   r   s    r   rJ   rJ   h  sX     	3:}s233333 	 	 	DD	 s   ( 
66c                 N    t          |fd|                     d                    S )z
    A word-wrap function that preserves existing line breaks
    and most spaces in the text. Expects that existing line
    breaks are posix newlines (
).
    c           	          | dt          |           |                     d          z
  dz
  t          |                    dd          d                   z   |k             |S )Nz 

r   r   )r   rfindr   )linewordwidths      r   <lambda>zword_wrap.<locals>.<lambda>w  sk    4#d))DJJt$4$44q8djjq11!45569>? A A4	3 r&    )r   r   )textr   s     r   	word_wrapr   q  s6     5   
 **S//  r&   c                 "    t          | d          S )zWord wrap to a specific widthK   )r   )r   s    r   	wrap_textr     s    T2r&   c                 @    d |                      fd           dS )a$  Sorts list of strings into numeric order, with text case-insensitive.
       Modifies list in place.

       Eg:
       [ '80', 'a222', 'a32', 'a2', 'b1', '443', 'telnet', '3', 'http', 'ZZZ']

       sorts to:
       ['3', '80', '443', 'a2', 'a32', 'a222', 'b1', 'http', 'telnet', 'ZZZ']
    c                 p    |                                  rt          |           n|                                 S N)isdigitintlower)ts    r   r   zhuman_sort.<locals>.<lambda>  s%    qyy{{9SVVV		 r&   c                 F    fdt          j        d|           D             S )Nc                 &    g | ]} |          S  r   ).0cnorms     r   
<listcomp>z0human_sort.<locals>.<lambda>.<locals>.<listcomp>  s!    FFFTT!WWFFFr&   z([0-9]+))r+   r   )kr   s    r   r   zhuman_sort.<locals>.<lambda>  s(    FFFFbhz1.E.EFFF r&   )keyN)sort)lstr   s    @r   
human_sortr     s1     :9DHHFFFFHGGGGGr&   c                    	 t          |           }n# t          $ r t          d          w xY wt          j                            dt          |          d          }t          j                            |          st          d|z            t          |          
                                d                             dd          d                                         d         }t          |          S )zdFinds parent process id for pid based on /proc/<pid>/stat. See
       'man 5 proc' for details.
    zpid must be an integer/procstatCouldn't find '%s'r   )r   )r   r   r!   rh   pathjoinr   isfiler   rS   	readlinesrsplitr   )mypidpidnameppids       r   get_ppidr     s    3%jj 3 3 312223 7<<S622D7>>$ 5*d3444 ::!!!$++C33A6<<>>qADt99s    ,c                    	 t          |           }nf# t          $ r" t          d          }t          |           Y dS t          $ r/ t          d          t          |           z  }t          |          w xY w| dk    s|dk    rdS t          j        	                    dt          |          d          }t          j        
                    |          s!t          d          |z  }t          |          	 t          |                                          d                                         d         }n/# t          $ r" t          d	          |z  }t          |          w xY wt          d
|z             |dk    rdS t          |          S )z1Determine if current process is running under sshz%Couldn't find pid (is /proc mounted?)Fz!Couldn't find parent pid for '%s'r   r   r   r   r   z"Could not find executable for '%s'zunder_ssh: exe is '%s'z(sshd)T)r   r   r    r*   r   r   r!   rh   r   r   r   rS   r   r   rJ   	under_ssh)r   r   warn_msgr$   r   exes         r   r   r     s   "}}   <==Xuu " " "788CHHE!!!" axx4199u7<<TF33D7>>$ "())T2!!!"4jj""$$Q'--//2 " " "899TB!!!" 

"c
*+++ hts    (A58A55?D5 5,E!c                     d}|rd}t          j        d|           r&t          |           dk     st          |           |k    rdS dS )zVerifies cidr netmasks       ^[0-9]+$r   FT)r+   r,   r   )r;   r<   nums      r   r/   r/     sN    
C	 8K$$ B!s2ww}}u4r&   c                     |rdS t          j        d|           r[t          j        d|           }t          |          dk    rdS |D ]-}|r&t	          |          dk     st	          |          dk    r dS .ndS dS )z.Verifies dotted quad ip addresses and netmasksFz^[0-9]+\.[0-9\.]+$z\.   r      T)r+   r,   r   r   r   )r;   r<   quadsqs       r   r7   r7     s    	 u8)2.. 	HT2&&E5zzQu ! ! !CFFQJJ#a&&3,, 55 +7! 54r&   c           	          d}|rt           t          | |          st           d}	 t          t          j        dt          j        |                     d                   }nJ# t          $ r= t          t          j        dt          j        |                     d                   }Y nw xY wd}t          d          D ]}||z	  dz  dk    rd}|rd} n|dz  }|dk    r|dk    rt          d|z
            }t          ||          st           |S )	z@Convert netmask to cidr. IPv6 dotted netmasks are not supported.r   r   >LFr   r   Tr\   )r!   r7   longstructunpackr   	inet_aton	NameErrorr   ranger   r/   )r;   r<   cidrmbitsbits	found_onens          r   rG   rG     s?   D	 #"2r** 	
	EdF,<R,@,@AA!DEEDD 	E 	E 	Ev}T6+;B+?+?@@CDDDDD	E 	r 	 	A	Q!## 		 EEQJEEA::%2++rEz??DtR(( Ks   :A! !AB('B(c                 l   d}|rt           t          | |          st           	 t          d          }n# t          $ r d}Y nw xY wt	          d          D ] }|t          |           k     r|dd|z
  z  z  }!t          j        t          j	        d|                    }t          ||          st           |S )z<Convert cidr to netmask. IPv6 dotted netmasks not supported.r   r   r   r   r5   r   )r!   r/   r   r   r   r   r   	inet_ntoar   packr7   )r   r<   r;   r   r   s        r   _cidr_to_dotted_netmaskr   $  s    	B	 7"4,, 	
	77DD 	 	 	DDD	 r 	$ 	$A3t99}}R!V#fk$5566 r2&& Is   4 AAc           	      t   d| vrt          d           | S |                     d          }t          |          dk    st          |d         d          st          |d         }|d         }|}t          |d          rt          |d          }	 t          t          j	        dt          j        |                    d                   }t          t          j	        dt          j        |                    d                   }n# t          $ rw t          t          j	        dt          j        |                    d                   }t          t          j	        dt          j        |                    d                   }Y nw xY w||z  }t          j        t          j        d|                    }|d|S )z8Convert an IPv4 address and netmask to a network addressr   z8_address4_to_network: skipping address without a netmaskr   r   Fr   r   )rJ   r   r   r7   r!   r/   r   r   r   r   r   r   r   r   r   r   )	r1   r#   hostorig_nmr;   	host_bitsnm_bitsnetwork_bitsrN   s	            r   rI   rI   A  s   
$HIII
**S//C
3xx1}}/A>>}q6D!fG	B2u%% 0$R//DtV-=d-C-CDDQGHH	v}T6+;B+?+?@@CDD D D DdF,<T,B,BCCAFGG	fmD&*:2*>*>??BCCD w&Lv{4>>??Gggww''s   A4D A>FFc                 t   d }d| vrt          d           | S |                     d          }t          |          dk    st          |d         d          st          |d         }|d         }t          j        dt          j        t          j	        |                    }	 t          d          }n# t          $ r d}Y nw xY wt          d	          D ]M} |||         d
          }t          d
          D ])}	|dt          ||	                   z  d|	z
  |d
z  z
  z  z  }*N	 t          d          }
n# t          $ r d}
Y nw xY wt          d          D ] }|t          |          k     r|
dd|z
  z  z  }
!||
z  }g }t          d	          D ]@}|                    t           ||d          |d
z  |d
z  d
z            d                     At          j        t          j	        t          j        d|d         |d         |d         |d         |d         |d         |d         |d         	  	                  }|d|S )z8Convert an IPv6 address and netmask to a network addressc                 j     d                      fdt          |dz
  dd          D                       S )zDecimal to binaryr   c                 :    g | ]}t          |z	  d z            S )r   )r   )r   yr   s     r   r   z9_address6_to_network.<locals>.dec2bin.<locals>.<listcomp>h  s)    LLLSAXN++LLLr&   r   r\   )r   r   )r   counts   ` r   dec2binz%_address6_to_network.<locals>.dec2binf  s:    wwLLLLU57B5K5KLLLMMMr&   r   z8_address6_to_network: skipping address without a netmaskr   r   Tr   z>8H      rz   r   r]   r            )rJ   r   r   r8   r!   r   r   r   r-   r.   r   r   r   r   rF   rH   r   )r1   r  r#   	orig_hostnetmaskunpackedr   ir   jr   r2   r   rN   s                 r   _address6_to_networkr  d  s   N N N $HIII
**S//C
3xx1}}M#a&$77}AI!fG}UF$4V_5>%@ %@ A AHGG		   			 1XX 9 9GHQK$$r 	9 	9A!c!A$ii-SU1R4Z88II	9q''    3ZZ * *s7||qWM))G g
C C1XX < <

3wwsC((2ad2g6::;;;; v%{5#a&#a&+.q63q63q6+.q63q63q6 C  CD DG
 ggww''s$   !B1 1C ?C !D1 1E ?E c                    |                     d          }t          |          dk    st          |d         |          st          |d         }|d         }|dk    s|dk    rdS | }d|v rM|                     d          }t          |          dk    st          |d         |          st          |d         }|dk    s|dk    rdS |r&t	          |          rt	          |          st          n%t          |          rt          |          st          t          ||          r|st          ||          }|r[t          |d|                               d          d         }t          |d|                               d          d         }nZt          |d|                               d          d         }t          |d|                               d          d         }||k    S )z&Determine if address x is in network yr   r   r   r   z0.0.0.0z::T)
r   r   r8   r!   r3   r9   r/   r   r  rI   )	
tested_add
tested_netr<   r#   r  r	  addressorig_networkrN   s	            r   
in_networkr    s:   


3

C
3xx1}}M#a&"55}AI!fGId!2!2tG
g~~mmC  s88q==c!fb 9 9=a&)w$t	 g&& 	nY.G.G 		 g&& 	nY.G.G 	7B'' 7 7)'266 
 	I+-6YY-A B BBG%**QP&(/(: ; ;;@5::aI ,-6YY-A B BBG%**QP&(/(: ; ;;@5::aI l""r&   c                      d} dD ]E}t           j                            |d          } t           j                            |           r nd} F| dk    rt	          t
          j        d          | S )Nr   )z/sbinz/binz	/usr/sbinz/usr/binz/usr/local/sbinz/usr/local/biniptableszCould not find iptables)rh   r   r   existsr_   r`   ra   )r   ds     r   _find_system_iptablesr    sr    
C3   gll1j))7>># 	ECC
byyel$=>>>Jr&   c                     | t                      } t          | dg          \  }}|dk    rt          t          j        d| z            t          j        d|          }t          j        dd|d                   S )	zReturn iptables versionNz-Vr   zError running '%s'z\sz^vr   r   )r  r   r_   r`   ra   r+   r   sub)r   rm   rl   r#   s       r   get_iptables_versionr    sq    
{#%%S$K  IR	Qwwel$8C$@AAA
(4

C6$CF###r&   c                 x   d }|r1t          j                    dk    rt          t          j        d          | t                      } g }d}|                     d          rd}|t          dd	          z  }t          | d
|g          \  }}|dk    rt          t          j	        |           || |g d          r|
                    d            || |g d          r|
                    d           t          | d|g           t          | d|g          \  }}|dk    rt          t          j	        |          |S )z[Return capabilities set for netfilter to support new features. Callers
       must be root.c                 J    | d|g}t          ||z             \  }}|dk    rdS dS )Nz-Ar   TF)r   )r   chainruleargsrm   rl   s         r   test_capz,get_netfilter_capabilities.<locals>.test_cap  s6    T5!t$$	S774ur&   r   zMust be rootNzufw-caps-test	ip6tableszufw6-caps-testr   )prefixdirz-N)-m	conntrack	--ctstateNEWr%  recentz--setz
recent-set)r%  r&  r'  r(  r%  r)  z--updatez	--seconds30z
--hitcountr>   zrecent-updatez-Fz-X)rh   getuidr_   r`   EPERMr  endswithr   r   ra   rF   )r   	do_checksr!  capsr  rm   rl   s          r   get_netfilter_capabilitiesr0    s       3RY[[A%%ek>222
{#%%DE
||K   !  
V22&&&&E S$&''IR	QwwelC((( xU 6 6 6 7 7 "L!!! xU 0 0 0 1 1 % 	O$$$ dES$&''IR	QwwelC(((Kr&   c                 T   t          |           }t                      }|                                D ]t}|                    d          s|                    d          s.|                                }|d         }|d                             d          d         }t                      }d                    |d                             d          dd                   |d<   |d	         |d
<   |d                             d          d         |d<   |d         dk    r|d         |d<   n$|d                             d          d         |d<   ||vrt                      ||<   g ||         |<   n|||         vrg ||         |<   ||         |                             |           v|S )z:Get and parse netstat the output from get_netstat_output()r   r   r   r   :r\   Nladdrr]   uidr  r   r   -r   )get_netstat_outputdict
splitlines
startswithr   r   rF   )r<   netstat_outputr  r   r#   r   r   items           r   parse_netstat_outputr<  '  s    (++NA))++ $ $u%% 	dooe.D.D 	jjllA1v||C  $vvQc!2!23B3!788W!fU!fll3''*U;#u+DKKa&,,s++A.DK>>vvAeHAeHTNN1U8##!#%	%d####Hr&   c                    d}|r1d}t           j                            |          st          t          j        d|z            t          |                                          D ]}|                                | d         k    rd	                    fdt          dt          d                   d          D                       }d	                                         d
k    r-|dt          d	                                         d          }|dk    rt          t          j        d          nt!          j        t           j        t           j                  }	 t!          j        t)          j        |                                dt/          j        d| dd                             dd                   }n(# t2          $ r t          t          j        d          w xY wt5          ||          d         S )zGet IP address for interfacer   /proc/net/if_inet6'%s' does not existr  r2  c                 6    g | ]}d          ||dz            S r   r   r   r   r  r#   s     r   r   z"get_ip_from_if.<locals>.<listcomp>[  )    LLLaCF1QqS5MLLLr&   r   r   r   80r   r  No such devicei  256sN         )rh   r   r  r_   r`   ra   rS   r   r   r   r   r   r   r   r   ENODEVr   r6   
SOCK_DGRAMr   fcntlioctlre   r   r   r   rP   )ifnamer<   r1   procr   r   r#   s         @r   get_ip_from_ifrP  M  s   D 
 :#w~~d## 	F%,(=(DEEEJJ((** 	E 	ED**,,CQxxLLLL5CAKK3K3KLLLN N q6<<>>T))&*ddCA,C,C,CDD2::%,(8999  M&.&*;<<	:#EK

F$*Kss$D$D%F %FFHe%M N NDD 	: 	: 	:%,(8999	: T2&&q))s   "AG   %G%c                    d}d}t          |           rd}d}n)t          |           st          t          j        d          t
          j                            |          st          t          j	        d|z            d}|r t          |                                          D ]}|                                d                                         }d	                    fd
t          dt!          d                   d          D                       }d                                         dk    r-|dt%          d                                         d          }| |k    sd|v rt'          | |d          r|} nnt          |                                          D ]`}d	|vr|                    d	          d                                         }	 t)          |d          }n# t          $ r Y Rw xY w|| k    r|} na|S )zGet interface for IP addressFz/proc/net/devTr>  rE  r?  r   r  r2  c                 6    g | ]}d          ||dz            S rA  r   rB  s     r   r   z"get_if_from_ip.<locals>.<listcomp>  rC  r&   r   r   r   rD  r   r  )r3   r9   r   r`   rJ  rh   r   r  r_   ra   rS   r   r   stripr   r   r   r   r   r  rP  )	r1   r<   rO  matchedr   rN  tmp_addripr#   s	           @r   get_if_from_iprW  m  s   	BDd 6#D!! 6el$45557>>$ Bel$9D$@AAAG	 JJ((** 	 	D**,,CV\\^^FxxLLLL5CAKK3K3KLLLN NH1v||~~%%&.hhCFLLNNB0G0G0GHxxJtXt$D$D JJ((** 	 	D$ZZ__Q'--//F#FE22    Tzz   Ns   G++
G87G8c                  6   t          j        d          } |                                  t          j        d          }t                      }| D ]J}|                    |          st           j                            d|d          }t          j	        |t           j
        t           j        z            sgd}	 t          j        t           j                            d|d                    }n# t          $ r Y nw xY w	 t          j        |          }n# t          $ r Y w xY w|D ]s}	 t          j        t           j                            ||                    d         }n# t          $ r Y Hw xY w|dt           j                            |          ||<   tL|S )zGet inodes of files in /procr   r   rk   r5  r   r   r   )rh   listdirr   r+   compiler7  r,   r   r   accessF_OKR_OKreadlinkr   r   basename)	
proc_filespatinodesr  fd_pathexe_pathdirsr  inodes	            r   _get_proc_inodesrg    s   G$$JOO
*[
!
!CVVF F Fyy|| 	',,w400 y"'BG"344 		{27<<E#B#BCCHH 	 	 	D		:g&&DD 	 	 	H	  	F 	FAWa 8 899!<   '(qq"'*:*:8*D*D*DEF5MM	F Ms6   73C++
C87C8<D
DD&8E
E,+E,c                    ddddddddd	d
dd}ddddd}t           j                            d|           }t          j        |t           j        t           j        z            st          g }d}t          |                                          }|D ]}|	                                }|sd}|t          ||d                  d                   }	|                     d          rd}	n|                     d          r|	d
k    rq||d                  	                    d          \  }
}||d                  }||d                  }|                    |
t          |d          |||	f           |S )z=Read /proc/net/(tcp|udp)[6] file and return a list of tuples ESTABLISHEDSYN_SENTSYN_RECV	FIN_WAIT1	FIN_WAIT2	TIME_WAITCLOSE
CLOSE_WAITLAST_ACKLISTENCLOSING)r   r   r]   r   r  r  r  r  	   
      r   r]   r  rt  )
local_addrstater4  rf  z	/proc/netFTrx  r  r   NAr   rw  r2  r4  rf  )rh   r   r   r[  r\  r]  r!   rS   r   r   r   r9  rF   )protocol
tcp_statesproc_net_fieldsrT   r   skipped_firstlinesr   fieldsrx  r3  r   r4  rf  s                 r   _read_proc_net_protocolr    s   #  !!!"   J '(!" !" O 
k8	,	,B9R27*++ 
CMHH  E > > 	 M3vog&>?DDEu%% 	EE  '' 	EX,=,=_\:;AA#FFt_U+,w/0

E3tR==#ue<====Jr&   c                 f    d}t                     dk    rdt          ddd          D ]8}d                     fdt          |dz   |d          D                       z  9t          d                    fdt          dt                    d	          D                       d
          d         }n{g  fdt          ddd          D             D ]2}                    t          t          |d                               3t          d                              d          d         }|S )zDConvert an address from /proc/net/(tcp|udp)* to a normalized addressr   r  r   r   c                 *    g | ]}|d z
  |         S r   r   r   r  paddrs     r   r   z(convert_proc_address.<locals>.<listcomp>  s%    FFFaU1Q3q5\FFFr&   r2  c                 N    g | ]!}||d z                                             "S )r   )r   )r   r  r#   s     r   r   z(convert_proc_address.<locals>.<listcomp>  s1    BBBqAacE
  ""BBBr&   r   Tc                 *    g | ]}|d z
  |         S r  r   r  s     r   r   z(convert_proc_address.<locals>.<listcomp>  s%    :::A51Q<:::r&   r  .F)r   r   r   rP   rF   r   r   )r  	convertedr  r#   s   `  @r   convert_proc_addressr    sG   I
5zzA~~q"a 	H 	HA277FFFF51a3D3DFFFGGGCC%chhBBBBE!SXXq,A,ABBB'D 'D 		 ::::q!R::: 	( 	(AJJs3q"::''''%chhsmmU;;A>	r&   c                 4   t                      }ddg}| r|ddgz  }|D ]F}	 t          |          ||<   # t          $ r$ t          d|z            }t	          |           Y Cw xY wt                      }t          |                                          }|                                 d}|D ]k}||         D ]`\  }}	}
}}t          |          }d}t          |          |v r|t          |                   }||dd	|d
|	dd	|dd	|
dd	|dd	|dz  }al|S )z5netstat-style output, without IPv6 address truncationr   r   tcp6udp6z!Could not get statistics for '%s'r   r5  5r   r2  4611r   )r7  r  r   r    r*   rg  listkeysr   r  r   )r<   proc_net_datar   pr   rb  	protocolsr   r3  r   r4  rf  rx  r1   r   s                  r   r6  r6    s   FFMENE	 "&&!!  	6q99M! 	 	 	<BCCHNNNH	
 F]''))**INN
A 
O 
O0=a0@ 		O 		O,UD#ue'..DC5zzV##SZZ(qqqqBF$$7M7M7M7M7<uuucccc5555###O OAA		O Hs   4+A"!A"c                     || S |                      d          r?t          |           dk     r|}nIt          j                            || dd                   }n t          j                            ||           }|S )zAdd prefix to dirNr   r   r   )r9  r   rh   r   r   )r$  r#  newdirs      r   	_findpathr  &  so    ~

~~c +s88a<<FFW\\&#abb'22FFfc**Mr&   c                     t           j        d         dk     rt          j        | d          S t	          j        |                     dd                                        d          S )z,Take a string and convert it to a hex stringr   r]   hexr   r   )errorsr^   )rc   rg   codecsr   binasciihexlifydecode)r   s    r   
hex_encoder  4  sX    
Q}Q&&& AHHWXH>>??FFwOOOr&   c                    t           j        d         dk     r)|                     d                              d          S t          j        dt          |           dz  r
| dd	         n| z                                dd
          S )z,Take a hex string and convert it to a stringr   r]   r  )encodingr   r   r   Nr\   backslashreplace)rc   rg   r  r  	unhexlifyr   )hs    r   
hex_decoder  =  s    
Qxxx''..w777 dA
&AaffBCCJJ#  r&   /run/ufw.lockc                 l    d}|s/t          | d          }t          j        |t          j                   |S )zCreate a blocking lockfileNw)rS   rL  lockfLOCK_EX)lockfiledryrunlocks      r   create_lockr  L  s7    D )Hc""D%-(((Kr&   c                     | dS 	 t          j        | t           j                   |                                  dS # t          $ r Y dS w xY w)z(Free lockfile created with create_lock()N)rL  r  LOCK_UNrY   r!   )r  s    r   release_lockr  U  sZ    |D%-(((

    	s   3; 
A	A	)r   )Tr   )NT)F)r  F)I__doc__
__future__r   r  r  r`   rL  r   r   rh   r+   rp   r   r   r{   rc   	functoolsr   tempfiler   r   r   rb   supported_protocolsr   ipv4_only_protocolsr   r%   r3   r9   r8   rA   rP   rU   rZ   rn   rv   r   r   r   r   r*   rd   r   rJ   r   r   r   getpidr   r   r/   r7   rG   r   rI   r  r  r  r  r0  r<  rP  rW  rg  r  r  r6  r  r  r  r  r  r   r&   r   <module>r     s   ( (" & % % % % %     				  				 				        



       $ $ $ $ $ $ $ $	
 QPP AAA v&   4  (  4  2F F F	 	 	 	4 4 4n  

L 
L 
LG G G2   % % %	& 	& 	&  *      J          
H H H 29;;    . ")++ ! ! ! !N	 	 	  2$ $ $\  : (  (  (F7( 7( 7(t,# ,# ,#h  	$ 	$ 	$ 	$6 6 6 6r# # #L* * * *@, , ,^" " "J, , ,^  &     F  P P P     
 
 
 
 
r&   