
    6mg                     F   S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJrJr  SrSr/ SQr/ SQrS	S
/rS rS rS rS rS rS9S jrS r S r!S r"S r#S:S jr$S r%S r&S r'S:S jr(S r)\RT                  S4S jr+S r,S r-S r.S  r/\	R`                  " 5       4S! jr1\	R`                  " 5       4S" jr2S# r3S$ r4S% r5S& r6S' r7S( r8S) r9S* r:S;S+ jr;S<S, jr<S- r=S=S. jr>S/ r?S0 r@S1 rAS2 rBS3 rCS4 rDS5 rES6 rFS>S7 jrGS8 rHg)?z"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                    Sn [         R                  " U 5         [         R                  " U S5        Sn [         R                  " U S5        US:X  a  SnU$ Sn U$ ! [         a    e f = f! [         a     NBf = f! [         a     U$ f = f)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>E L	 E L%      Ls3   A A* A: A: A'*
A76A7:
BBc                 
   SnSnU R                  S5      n[        U5      S:X  a
  US   nSnX4$ [        U5      S:X  a1  US   nUS   nU[        ;   a  [        SU-  5      n[	        U5      e X4$ [        S5      n[	        U5      e)	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
3x1}1v = 
SQ1vA&&9EABGW%% ' = J-!!    c                    [         R                  (       d  [        S5        g[        U 5      S:  d  [        R
                  " SU 5      (       d  gU R                  S5      n [         R                  " [         R                  US   5        [        U5      S:  a  g[        U5      S:X  a  [        US   S	5      (       d  gg	! [         a     gf = f)
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 4y2~RXX&;TBB
**S/C#a&1 3x!|	SQ"3q6400  s    (B= =
C
	C
c                    [        U 5      S:  d  [        R                  " SU 5      (       d  gU R                  S5      n [        R
                  " [        R                  US   5        [        US   S5      (       d  g [        U5      S:  a  g[        U5      S:X  a  [        US   S5      (       d  gg! [         a     gf = f)	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     4y2~RXXnd;;
**S/CQ0"3q6511 2
 3x!|	SQSVU++  s   <B2 2
B?>B?c                 <    [        X5      =(       d    [        X5      $ )z(Verifies if valid cidr or dotted netmask)r/   r7   )nmv6s     r   r8   r8      s    r&E*=b*EEr&   c                     US:X  a  [        U 5      $ US:X  a  [        U 5      $ US:X  a  [        U 5      =(       d    [        U 5      $ [        e)zValidate IP addresses64r   )r3   r9   r!   )r1   versions     r   valid_addressrA      sI    #~d##	Cd##	E	d#;~d';;
r&   c                    / nSnSn[         R                  nU(       a  Sn[         R                  nSU ;   aB  U R                  S5      nU(       a  US   S:X  a  US	 O.U(       d  US   S:X  d	  US   S:X  a  US	 OUR	                  U 5        U(       d6  [        U5      S	:X  a'  [        US   U5      (       a   [        US   U5      US'   US
   n[         R                  " U[         R                  " XV5      5      nXbS
   :w  a  Sn[        U5      S	:X  a<  USUS   -   -  nU(       d*  [        U5      nXv:w  a  SU< SU< S3n[        U5        UnSn[        Xd5      (       d  SU-  n[        U5        [        eXc4$ ! [         a     Nf = f)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      sy   
 CGG^^F	
d{jjo#a&E/AQ43q65F+FA

4#c(a-$7A$C$C	,SVR8CF
 q6D FF$4$4V$BCD1v~
3x1}c!f*40G;BDIg''(D1g?5  		s   4E4 4
F Fc                     [        U S5      $ )z"Opens the specified file read-onlyr)open)fns    r   open_file_readrU      s    C=r&   c                 z    [        U 5      n [        5       u  p#XX#S.$ ! [         a    UR                  5         e f = f)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      sD    "D 
 #KK	  

s    :c                    US:X  a  gU (       d  [        [        R                  S5      e[        (       a8  U [        R
                  R                  5       :X  a  [        R                  U5        gSn[        R                  S   S:  a"  [        R                  " U [        US5      5      nO[        R                  " X5      nUS::  a  [        [        R                  S5      eg)	zwWrite 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     byell$ABB zbCJJ--//	B
aXXb%W-.XXb	Qweii!EFF r&   Tc                    U S   R                  5         [        R                   " U S   5        U(       a:  [        R                  " U S   U S   5        [        R                  " U S   U S   5        [        R
                  " U S   5        g)zjCloses 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     sc     KHHSZJY8C	NC
O4IIc)nr&   c                    [        U 5         [        R                  " U [        R                  [        R                  SS9nUR                  5       S   nUR                  [        U5      /$ ! [
         a  nS[        U5      /s SnA$ SnAff = f)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     sx    	'Ngjoo%/%6%6157 ..
1
CMM3s8$$	  SW~s   3A* *
B4B BBc                 "    [         R                  " U [         R                  S9n[         R                  " XR                  S9nUR                  5       S   nUR                  [        U5      /$ ! [         a  nS[        U5      /s SnA$ SnAff = f)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   $  sw    x
@xzz: //
A
CNNCH%%	  SW~s   AA- -
B7B	B	Bc                 l    U R                   n UR                  SS5      n[        (       a;  [        R
                  " [        R                  5      (       a  UR                  U5        OUR                  [        U5      5        U R                  5         g! [         a    U n Nf = f! [         a    Un Nf = f)zJImplement 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)
 zgoobkk22QU3Z 
LLN    s"   B B$ B! B!$B32B3c                      [        [        R                  SU -  5        U(       a  [        R                  " S5        gg! [         a     N+f = f)zPrint error message and exitz
ERROR: %s
r   N)r   rc   rx   IOErrorexit)rl   do_exits     r   errorr   G  sC    szz=3./    s   > 
A
Ac                 `     [        [        R                  SU -  5        g! [         a     gf = f)zPrint warning messagez	WARN: %s
N)r   rc   rx   r   rl   s    r   r*   r*   R  s,    szz<#-. s     
--c                     [         (       a  U[        R                  :X  a  [         n U(       a  [        USU -  5        g[        USU -  5        g! [         a     gf = f)zPrint messagez%s
%sN)rb   rc   rd   r   r   )rl   r   newlines      r   msgr   Z  sM    zf

*66C<(64#:& s   A A 
AAc                 x    [         (       a   [        [        R                  SU -  5        gg! [         a     gf = f)zPrint debug messagez
DEBUG: %s
N)	DEBUGGINGr   rc   rx   r   r   s    r   rJ   rJ   h  s8    y	3::}s23   		s   , 
99c                 @    [        U4S jU R                  S5      5      $ )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           	          U < S[        U 5      U R                  S5      -
  S-
  [        UR                  SS5      S   5      -   U:     < U< 3$ )Nz 

r   r   )r   rfindr   )linewordwidths      r   <lambda>word_wrap.<locals>.<lambda>w  sT    #d)DJJt$44q8djjq1!4569>? A	3r&    )r   r   )textr   s     r   	word_wrapr   q  s%     5 
 **S/ r&   c                     [        U S5      $ )zWord wrap to a specific widthK   )r   )r   s    r   	wrap_textr     s    T2r&   c                 2   ^ S mU R                  U4S jS9  g)zSorts 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                 b    U R                  5       (       a  [        U 5      $ U R                  5       $ N)isdigitintlower)ts    r   r   human_sort.<locals>.<lambda>  s     qyy{{SV9	9r&   c                 j   > [         R                  " SU 5       Vs/ s H  nT" U5      PM     sn$ s  snf )Nz([0-9]+))r+   r   )kcnorms     r   r   r     s(    bhhz1.EF.ET!W.EFFs   0)keyN)sort)lstr   s    @r   
human_sortr     s     :DHHFHGr&   c                     [        U 5      n[        R                  R                  S[        U5      S5      n[        R                  R                  U5      (       d  [        SU-  5      e[        U5      R                  5       S   R                  SS5      S   R                  5       S   n[        U5      $ ! [         a    [        S5      ef = f)zYFinds 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%j 77<<S62D77>>$*d344 :!!$++C3A6<<>qADt9  31223s   B4 4C
c                     [        U 5      nU S:X  d  US::  a  g[        R                  R                  S[        U5      S5      n[        R                  R                  U5      (       d  [        S5      U-  n[        U5      e [        U5      R                  5       S   R                  5       S   n[        S
U-  5        US:X  a  g[        U5      $ ! [         a    [        S5      n[        U5         g[         a#    [        S5      [        U 5      -  n[        U5      ef = f! [         a    [        S	5      U-  n[        U5      ef = f)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     s2   "} ax41977<<TF3D77>>$()T2!!"4j""$Q'--/2 

"c
*+ h;  <=X "78CHE!!"   "89TB!!"s   C -D   D1,D $Ec                     SnU(       a  Sn[         R                  " SU 5      (       a  [        U 5      S:  d  [        U 5      U:  a  gg)zVerifies cidr netmasks       ^[0-9]+$r   FT)r+   r,   r   )r;   r<   nums      r   r/   r/     s:    
C	88K$$B!s2w}r&   c                     U(       a  g[         R                  " SU 5      (       aR  U R                  S5      n[        U5      S:w  a  gU H*  nU(       a   [	        U5      S:  d  [	        U5      S:  d  M*    g   gg)z.Verifies dotted quad ip addresses and netmasksFz^[0-9]+\.[0-9\.]+$.   r      T)r+   r,   r   r   r   )r;   r<   quadsqs       r   r7   r7     sc    	88)2..HHSME5zQCFQJ#a&3,    r&   c           	         SnU(       a  [         e[        X5      (       d  [         eSn [        [        R                  " S[
        R                  " U 5      5      S   5      nSn[        S5       H"  nXF-	  S-  S:X  a  SnM  U(       a  Sn  O	US-  nM$     US:  a  US::  a  [        SU-
  5      n[        X!5      (       d  [         eU$ ! [         a:    [        [        R                  " S[
        R                  " U 5      5      S   5      n Nf = f)	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	"2**
	EdF,<,<R,@A!DED 	rA	Q!# 	EQJE  A:%2+rEz?Dt((K)  	Ev}}T6+;+;B+?@CDD	Es   7C AD	D	c                 j   SnU(       a  [         e[        X5      (       d  [         e [        S5      n[	        S5       H  nU[        U 5      :  d  M  USSU-
  -  -  nM!     [        R                  " [        R                  " SU5      5      n[        X!5      (       d  [         eU$ ! [         a    Sn Nf = f)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	"4,,
	7D rA3t9}R!V#  fkk$56 r&&I  	D	s   B# #B21B2c           	      8   SU ;  a  [        S5        U $ U R                  S5      n[        U5      S:w  d  [        US   S5      (       d  [        eUS   nUS   nUn[        US5      (       a  [        US5      n [        [        R                  " S[        R                  " U5      5      S   5      n[        [        R                  " S[        R                  " U5      5      S   5      nXV-  n[        R                  " [        R                  " SU5      5      nU< SU< 3$ ! [         aq    [        [        R                  " S[        R                  " U5      5      S   5      n[        [        R                  " S[        R                  " U5      5      S   5      n Nf = f)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  sS   
$HI
**S/C
3x1}/A>>q6D!fG	B2u%%$R/DtV-=-=d-CDQGH	v}}T6+;+;B+?@CD
 &Lv{{4>?Gw''  DdF,<,<T,BCAFG	fmmD&*:*:2*>?BCDs   8A.D A8FFc                    S nSU ;  a  [        S5        U $ U R                  S5      n[        U5      S:w  d  [        US   S5      (       d  [        eUS   nUS   n[
        R                  " S[        R                  " [        R                  U5      5      n [        S5      n[        S	5       H?  nU" XW   S
5      n[        S
5       H"  n	US[        X   5      -  SU	-
  US
-  -
  -  -  nM$     MA      [        S5      n
[        S5       H  nU[        U5      :  d  M  U
SSU-
  -  -  n
M!     Xj-  n/ n[        S	5       H1  nUR                  [        U" US5      US
-  US
-  S
-    S5      5        M3     [        R                  " [        R                  [
        R                   " SUS   US   US   US   US   US   US   US   5	      5      nU< SU< 3$ ! [         a    Sn GN?f = f! [         a    Sn
 Nf = f)z8Convert an IPv6 address and netmask to a network addressc           	          SR                  [        US-
  SS5       Vs/ s H  n[        X-	  S-  5      PM     sn5      $ s  snf )zDecimal to binaryr   r   r\   )r   r   r   )r   countys      r   dec2bin%_address6_to_network.<locals>.dec2binf  s=    wwU57B5KL5KSXN+5KLMMLs   ?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 $HI
**S/C
3x1}M#a&$77AI!fG}}UF$4$4V__5>%@ AHG	 1XHK$rA!c!$i-SU1R4Z88I  q' 3Zs7|qWM))G 
 
C C1X

3wsC(2ad2g6:;  v%{{5#a&#a&+.q63q63q6+.q63q63q6 CDG
 w''A  	  s$   G 0G$ G! G!$G32G3c                 v   UR                  S5      n[        U5      S:w  d  [        US   U5      (       d  [        eUS   nUS   nUS:X  d  US:X  a  gU nSU;   a?  UR                  S5      n[        U5      S:w  d  [        US   U5      (       d  [        eUS   nUS:X  d  US:X  a  gU(       a'  [	        U5      (       a  [	        U5      (       d  [        eO&[        U5      (       a  [        U5      (       d  [        e[        XR5      (       a  U(       d  [        XR5      nU(       aL  [        U< SU< 35      R                  S5      S   n[        U< SU< 35      R                  S5      S   nX:H  $ [        U< SU< 35      R                  S5      S   n[        U< SU< 35      R                  S5      S   nX:H  $ )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
3x1}M#a&"55AI!fGId!2G
g~mmC s8q=c!fb 9 9a&)w$	g&&nY.G.G /H g&&nY.G.G7'')'6 
+-6-A BBG%*QP&(/(: ;;@5:aI "" ,-6-A BBG%*QP&(/(: ;;@5:aI ""r&   c                      Sn S HK  n[         R                  R                  US5      n [         R                  R                  U 5      (       a    OSn MM     U S:X  a  [	        [
        R                  S5      eU $ )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    sd    
C3 ggll1j)77>>#C3 byell$=>>Jr&   c                     U c
  [        5       n [        U S/5      u  pUS:w  a  [        [        R                  SU -  5      eUR                  5       n[        R                  " SSUS   5      $ )zReturn iptables versionz-Vr   zError running '%s'z^vr   r   )r  r   r_   r`   ra   r   r+   sub)r   rm   rl   r#   s       r   get_iptables_versionr    s_    
{#%S$K IR	Qwell$8C$@AA
))+C66$CF##r&   c                 L   S nU(       a3  [         R                  " 5       S:w  a  [        [        R                  S5      eU c
  [        5       n / nSnU R                  S5      (       a  SnU[        SSS9-  n[        U S	U/5      u  pVUS:w  a  [        [        R                  U5      eU" X/ S
Q5      (       a  UR                  S5        U" X/ SQ5      (       a  UR                  S5        [        U SU/5        [        U SU/5      u  pVUS:w  a  [        [        R                  U5      eU$ )zTReturn capabilities set for netfilter to support new features. Callers
must be root.c                 :    U SU/n[        X2-   5      u  pEUS:X  a  gg)Nz-Ar   TF)r   )r   chainruleargsrm   rl   s         r   test_cap,get_netfilter_capabilities.<locals>.test_cap  s)    T5!$	7r&   r   zMust be rootz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    RYY[A%ekk>22
{#%DE
||K    
V22&&E S$&'IR	QwellC((  6 7 7L!  0 1 1 	O$ dES$&'IR	QwellC((Kr&   c                    [        U 5      n[        5       nUR                  5        GH  nUR                  S5      (       d  UR                  S5      (       d  M2  UR	                  5       nUS   nUS   R	                  S5      S   n[        5       nSR                  US   R	                  S5      SS 5      US'   US	   US
'   US   R	                  S5      S   US'   US   S:X  a	  US   US'   OUS   R	                  S5      S   US'   XR;  a  [        5       X%'   / X%   U'   OXbU   ;  a  / X%   U'   X%   U   R                  U5        GM      U$ )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<  '  sE    (+NA))+u%%dooe.D.DjjlA1v||C $vQc!23B!78W!fU!fll3'*U;#u+DKa&,,s+A.DK>vAHAHTNU8#!#	d#1 ,4 Hr&   c                    SnU(       Ga  Sn[         R                  R                  U5      (       d  [        [        R
                  SU-  5      e[        U5      R                  5        H  nUR                  5       nXS   :X  d  M  SR                  [        S[        US   5      S5       Vs/ s H  oeS   XfS-    PM     sn5      nUS   R                  5       S	:w  d  Mv  U< S
[        US   R                  5       S5      < 3nM     US:X  a  [        [        R                  S5      eO[         R                   " [         R"                  [         R$                  5      n [         R&                  " [(        R*                  " UR-                  5       S[.        R0                  " SU SS 5      5      SS 5      n[5        X!5      S   $ s  snf ! [2         a    [        [        R                  S5      ef = f)zGet IP address for interfacer   /proc/net/if_inet6'%s' does not existr  r2  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
  r   s           r   get_ip_from_ifrL  M  s   D 
#ww~~d##%,,(=(DEEJ((*D**,CQxx38CAK3KL3KaF1qSM3KLN q6<<>T)&*CA,CDD + 2:%,,(899  MM&..&*;*;<	:##EKK
F$*KKs$D%FFH%M ND
 T&q)) M  	:%,,(899	:s   *F=
AG %G'c           
         SnSn[        U 5      (       a  SnSnO*[        U 5      (       d  [        [        R                  S5      e[
        R                  R                  U5      (       d  [        [        R                  SU-  5      eSnU(       a  [        U5      R                  5        H  nUR                  5       nUS   R                  5       nS	R                  [        S
[!        US
   5      S5       Vs/ s H  ouS
   XwS-    PM     sn5      nUS   R#                  5       S:w  a$  U< S[%        US   R#                  5       S5      < 3nX:X  d  SU;   d  M  ['        XS5      (       d  M  Un  U$     U$ [        U5      R                  5        HD  nS	U;  a  M  UR                  S	5      S
   R                  5       n [)        US5      n	X:X  d  MA  Un  U$    U$ s  snf ! [         a     M\  f = f)zGet interface for IP addressFz/proc/net/devTr>  rA  r?  r   r  r2  r   r   r   r@  r   r  )r3   r9   r   r`   rF  rh   r   r  r_   ra   rS   r   r   stripr   r   r   r   r   r  rL  )
r1   r<   rK  matchedr   r#   rJ  r
  tmp_addrips
             r   get_if_from_iprR  m  s   	BDd#D!!ell$45577>>$ell$9D$@AAG	J((*D**,CV\\^Fxx38CAK3KL3KaF1qSM3KLNH1v||~%&.CFLLNB0GHxJtt$D$D   N9 +8 N J((*D$ZZ_Q'--/F#FE2 z N + N/ M   s   3G
9G
G('G(c                  h   [         R                  " S5      n U R                  5         [        R                  " S5      n[        5       nU  GH1  nUR                  U5      (       d  M  [         R                  R                  SUS5      n[         R                  " U[         R                  [         R                  -  5      (       d  Mz  Sn [         R                  " [         R                  R                  SUS5      5      n [         R                  " U5      nU Hb  n [         R                  " [         R                  R                  XG5      5      S   nU< S[         R                  R                  U5      < 3X('   Md     GM4     U$ ! [         a     Nf = f! [         a     GMV  f = f! [         a     M  f = f)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_inodesrb    sM   G$JOO
**[
!CVFyy||'',,w40 yy"''BGG"344	{{277<<E#BCH	::g&D AW 89!< ()"''*:*:8*DEFM + 8 M  		
  		  s6   5F<F6F#
FF
F F #
F10F1c                    SSSSSSSSS	S
SS.nSSSSS.n[         R                  R                  SU 5      n[         R                  " U[         R                  [         R
                  -  5      (       d  [        e/ nSn[        U5      R                  5       nU H  nUR                  5       nU(       d  SnM  U[        XS      S5         n	U R                  S5      (       a  Sn	OU R                  S5      (       a  U	S
:w  a  Mi  XS      R                  S5      u  pXS      nXS      nUR                  U
[        US5      XU	45        M     U$ )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  ro  )
local_addrstater4  ra  z	/proc/netFTrs  r  r   NAr   rr  r2  r4  ra  )rh   r   r   rV  rW  rX  r!   rS   r   r   r   r9  rF   )protocol
tcp_statesproc_net_fieldsrT   r   skipped_firstlinesr   fieldsrs  r3  r   r4  ra  s                 r   _read_proc_net_protocolr{    sU   #  !!!"  J '(!" !"O 
k8	,B99R277*++
CMH E M3vg&>?DEu%%E  ''EX,=\:;AA#FU+,w/0

E3tR=#e<=  Jr&   c                 l   Sn[        U 5      S:  a  Sn[        SSS5       H;  nUSR                  [        US-   US5       Vs/ s H
  o@US-
  U PM     sn5      -  nM=     [        SR                  [        S[        U5      S5       Vs/ s H  oBXDS-    R	                  5       PM     sn5      S	5      S   nU$ / n[        SSS5       Vs/ s H
  o@US-
  U PM     sn H'  nUR                  [        [        US
5      5      5        M)     [        SR                  U5      S5      S   nU$ s  snf s  snf s  snf )zDConvert an address from /proc/net/(tcp|udp)* to a normalized addressr   r  r   r   r   r2  r   Tr  r   F)r   r   r   rP   r   rF   r   r   )paddr	convertedr#   r
  r  s        r   convert_proc_addressr    s.   I
5zA~q"aA27751a3DF3Da1Q3q\3DFGGC !%chh,1!SXq,AB,AqAc
  ",AB'D	  ).q!R:A1Q<:AJJs3q":' ;%chhsmU;A>	 GB ;s   D'D,D1c                    [        5       nSS/nU (       a  USS/-  nU H  n [        U5      X'   M     [        5       n[        UR                  5       5      nUR                  5         SnU Hd  nX    HY  u  ppn[        U5      nSn[        U5      U;   a  U[        U5         nXs<S S	U< S
U	< 3<S S	U<S S	U
<S S	U<S S	U< S3-  nM[     Mf     U$ ! [         a    [        SU-  5      n[	        U5         M  f = f)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*   rb  listkeysr   r  r   )r<   proc_net_datar   pr   r]  	protocolsr   r3  r   r4  ra  rs  r1   r   s                  r   r6  r6    s
   FMENE	&&!!	6q9M  F]'')*INN
A0=0@,U#e'.DC5zV#SZ(qBF7M7<c5#O OA 1A  H/  	<BCHN	s   C#C<;C<c                     Uc  U $ U R                  S5      (       a8  [        U 5      S:  a  UnU$ [        R                  R	                  XSS 5      n U$ [        R                  R	                  X5      nU$ )zAdd prefix to dirNr   r   r   )r9  r   rh   r   r   )r$  r#  newdirs      r   	_findpathr  &  sl    ~

~~cs8a<F
 M WW\\&ab'2F M f*Mr&   c                     [         R                  S   S:  a  [        R                  " U S5      $ [        R
                  " U R                  SSS95      R                  S5      $ )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  sQ    
Q}}Q&& AHHWXH>?FFwOOr&   c                     [         R                  S   S:  a  U R                  SS9R                  S5      $ [        R                  " S[        U 5      S-  (       a  U SS	 OU -  5      R                  SS
5      $ )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  =  sn    
Qxxx'..w77 dA
afBCJJ# r&   c                 z    SnU(       d1  [        U S5      n[        R                  " U[        R                  5        U$ )zCreate a blocking lockfileNw)rS   rH  lockfLOCK_EX)lockfiledryrunlocks      r   create_lockr  L  s-    DHc"D%--(Kr&   c                     U c  g [         R                  " U [         R                  5        U R                  5         g! [         a     gf = f)z(Free lockfile created with create_lock()N)rH  r  LOCK_UNrY   r!   )r  s    r   release_lockr  U  s>    |D%--(

  	s   5< 
A	A	)r   )Tr   )NT)F)z/run/ufw.lockF)I__doc__
__future__r   r  r  r`   rH  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<  rL  rR  rb  r{  r  r6  r  r  r  r  r   r&   r   <module>r     sr   (" &     	  	 	     
  $	
 Q A v& 4(42F	4n

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