
    -f{                     ,   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d8dZd Z d Z!d Z"d Z#d9dZ$d Z%d Z&d Z'd9dZ(d Z)ejT                  dfdZ+d Z,d Z-d Z.d  Z/ e	j`                         fd!Z1 e	j`                         fd"Z2d# Z3d$ Z4d% Z5d& Z6d' Z7d( Z8d) Z9d:d*Z:d;d+Z;d, Z<d<d-Z=d. Z>d/ Z?d0 Z@d1 ZAd2 ZBd3 ZCd4 ZDd5 ZEd=d6ZFd7 ZGy)>z"util.py: utility functions for ufw    )print_functionN)reduce)mkstempmktempF)tcpudpipv6espahigmpgre)r	   r
   r   r   r   r	   r   c                    d}	 t        j                  |        	 t        j                  | d       d}	 t        j                  | d       |dk(  rd}|S d}	 |S # t        $ r  w xY w# t        $ r Y >w xY w# t        $ r Y |S w xY w)z8Get the protocol for a specified port from /etc/services r   r   any)socketgetservbyname	Exception)portprotos     E/var/www/html/flask-app/venv/lib/python3.12/site-packages/ufw/util.pyget_services_protor   .   s    ET"T5)T5)E>E L	 E L%      Ls3   A A% A4 A4 A"%	A10A14	B Bc                    d}d}| j                  d      }t        |      dk(  r|d   }d}||fS t        |      dk(  r/|d   }|d   }|t        v rt        d|z        }t	        |      ||fS t        d      }t	        |      )	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                 p   t         j                  st        d       yt        |       dkD  st	        j
                  d|       sy| j                  d      }	 t        j                  t         j                  |d          t        |      dkD  ryt        |      dk(  rt        |d   d	      syy	# t        $ r Y yw xY w)
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_address6r2   \   s    ??12 4y2~RXX&;TB
**S/C#a&1 3x!|	SQ"3q640  s   'B) )	B54B5c                 Z   t        |       dkD  st        j                  d|       sy| j                  d      }	 t	        j
                  t        j                  |d          t        |d   d      sy	 t        |      dkD  ryt        |      dk(  rt        |d   d      syy# t        $ r Y yw xY w)	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_netmaskr/   s     r   valid_address4r8   v   s     4y2~RXXnd;
**S/CQ0"3q651 2
 3x!|	SQSVU+  s   6B 	B*)B*c                 6    t        | |      xs t        | |      S )z(Verifies if valid cidr or dotted netmask)r.   r6   )nmv6s     r   r7   r7      s    r2&E*=b"*EEr%   c                     |dk(  rt        |       S |dk(  rt        |       S |dk(  rt        |       xs t        |       S t        )zValidate IP addresses64r   )r2   r8   r    )r0   versions     r   valid_addressr@      sI    #~d##	Cd##	E	d#;~d';;
r%   c                    g }d}d}t         j                  }|rd}t         j                  }d| v r5| j                  d      }|r|d   dk(  r|d= n'|s%|d   dk(  s|d   dk(  r|d= n|j	                  |        |s0t        |      d	k(  r"t        |d   |      r	 t        |d   |      |d<   |d
   }t        j                  |t        j                  ||            }||d
   k7  rd}t        |      d	k(  r5|d|d   z   z  }|s(t        |      }||k7  rd|d|d}t        |       |}d}t        ||      sd|z  }t        |       t        ||fS # t        $ r Y w xY w)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   r5   r-   r   appendr   r6   _dotted_netmask_to_cidrr   	inet_ntopr,   _address4_to_networkdebugr@   r    )	origr;   r1   changedr?   s_typer0   networkdbg_msgs	            r   normalize_addressrO      s|   
 CGG^^F	
d{jjo#a&E/AQ43q65F+FA

4#c(a-$7A$C	,SVR8CF
 q6D FF$4$4VT$BCDs1v~
3x1}c!f*40G$;BDIgw'(D1g'?5  		s   E	 		EEc                 <    	 t        | d      }|S # t        $ r  w xY w)z"Opens the specified file read-onlyr)openr   )fnrJ   s     r   open_file_readrT      s-    B} K  s    c                     	 t        |       }	 t               \  }}|| ||dS # t        $ r  w xY w# t        $ r |j                           w xY w)z=Opens the specified file read-only and a tempfile read-write.)rJ   orignamer"   tmpname)rT   r   r   close)rS   rJ   r"   rW   s       r   
open_filesrY      sb    b! g
 r#'KK  
  

s   " 0 -Ac                    |dk(  ry| st        t        j                  d      t        r7| t        j
                  j                         k(  rt        j                  |       yd}t        j                  d   dk\  r!t        j                  | t        |d            }nt        j                  | |      }|dk  rt        t        j                  d      y)	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_filerm      s     byell$ABB bCJJ--//	B
aXXb%W-.XXb#	Qweii!EFF r%   Tc                 :   | d   j                          t        j                   | d          |r9	 t        j                  | d   | d          t        j                  | d   | d          	 t        j                  | d          y# t
        $ r  w xY w# t        $ r  w xY w)zuCloses the specified files (as returned by open_files), and update
       original file with the temporary file.
    rJ   r"   rV   rW   N)rX   rg   shutilcopystatcopyr   unlinkr^   )fnsupdates     r   close_filesru     s     KHHSZ	OOC
OS^<KKIJ8
		#i.!	  		
  s   8B (B BBc                    t        |        	 t        j                  | t        j                  t        j                  d      }|j                         d   }|j                  t        |      gS # t
        $ r}dt        |      gcY d}~S d}~ww xY w)z!Try to execute the given command.T)rc   stderruniversal_newlines   Nr   )	rI   
subprocessPopenPIPESTDOUTr^   strcommunicate
returncode)commandspexrk   s       r   cmdr   $  sx    	'Ngjoo%/%6%6157 ..
1
CMM3s8$$	  SW~s   5A, ,	B5BBBc                 *   	 t        j                  | t         j                        }t        j                  ||j                        }|j                         d   }|j                  t        |      gS # t        $ r}dt        |      gcY d}~S d}~ww xY w)z#Try to pipe command1 into command2.)rc   )stdinry   Nr   )rz   r{   r|   rc   r^   r~   r   r   )command1command2sp1sp2r   rk   s         r   cmd_piper   2  sy    x
@xszz: //
A
CNNCH%%	  SW~s   AA2 2	B;BBBc                 R   	 | j                   }	 |j                  dd      }t        r5t	        j
                  t        j                        r|j                  |       n|j                  t        |             | j                          y# t        $ r | }Y w xY w# t        $ r |}Y w xY w)zQImplement our own print statement that will output utf-8 when
       appropriate.utf-8ignoreN)bufferr   encodera   inspectisclassioStringIOre   rh   flush)outputswriterrk   s       r   _printr   @  s    hhw)
 goobkk2QU3Z 
LLN    s"   B B BBB&%B&c                     	 t        t        j                  d| z         |rt        j                  d       yy# t        $ r Y $w xY w)zPrint error message and exitz
ERROR: %s
r   N)r   rb   rw   IOErrorexit)rk   do_exits     r   errorr   U  sC    szz=3./    s   8 	AAc                 ^    	 t        t        j                  d| z         y# t        $ r Y yw xY w)zPrint warning messagez	WARN: %s
N)r   rb   rw   r   rk   s    r   r)   r)   `  s,    szz<#-. s     	,,c                     t         r|t        j                  k(  rt         }	 |rt        |d| z         yt        |d| z         y# t        $ r Y yw xY w)zPrint messagez%s
z%sN)ra   rb   rc   r   r   )rk   r   newlines      r   msgr   h  sK    f

*66C<(64#:& s   A A 	AAc                 l    t         r	 t        t        j                  d| z         yy# t        $ r Y yw xY w)zPrint debug messagez
DEBUG: %s
N)	DEBUGGINGr   rb   rw   r   r   s    r   rI   rI   v  s6    	3::}s23   		s   ' 	33c                 >    t        |fd| j                  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        |       | j                  d      z
  dz
  t        |j                  dd      d         z   |k\     |S )Nz 

r   r   )r   rfindr   )linewordwidths      r   <lambda>zword_wrap.<locals>.<lambda>  sV    #d)DJJt$44q8djjq1!4569>? A	3 r%    )r   r   )textr   s     r   	word_wrapr     s%     5 
 **S/ r%   c                     t        | d      S )zWord wrap to a specific widthK   )r   )r   s    r   	wrap_textr     s    T2r%   c                 6    d | j                  fd       y)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                 X    | j                         rt        |       S | j                         S )N)isdigitintlower)ts    r   r   zhuman_sort.<locals>.<lambda>  s    qyy{SV 	 r%   c                 b    t        j                  d|       D cg c]
  } |       c}S c c}w )Nz([0-9]+))r*   r   )kcnorms     r   r   zhuman_sort.<locals>.<lambda>  s$    bhhz1.EFT!WF Fs   ,)keyN)sort)lstr   s    @r   
human_sortr     s     :DHHFHGr%   c                    	 t        |       }t        j                  j                  dt        |      d      }t        j                  j                  |      st        d|z        	 t        |      j                         d   j                  d      d   j                         d   }t        |      S # t        $ r t        d      w xY w# t        $ r  w xY w)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    rg   pathjoinr~   isfiler   rR   	readlinesr   )mypidpidnameppids       r   get_ppidr     s    3%j 77<<S62D77>>$*d344 Dz##%a(..s3A6<<>qA t9  31223  s   B/ %?C /CCc                 x   	 t        |       }| dk(  s|dk  ryt        j                  j                  dt        |      d      }t        j                  j                  |      st        d      |z  }t        |      	 t        |      j                         d   j                         d   }t        d
|z         |dk(  ryt        |      S # t        $ r t        d      }t        |       Y yt        $ r# t        d      t        |       z  }t        |      w xY w# t        $ r t        d	      |z  }t        |      w xY w)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    rg   r   r   r   rR   r   r   rI   	under_ssh)r   r   warn_msgr#   r   exes         r   r   r     s/   "} 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(+D#D9c                 v    d}|rd}t        j                  d|       rt        |       dk  st        |       |kD  ryy)zVerifies cidr netmasks       ^[0-9]+$r   FT)r*   r+   r   )r:   r;   nums      r   r.   r.     s7    
C	88K$B!s2w}r%   c                     |ryt        j                  d|       rMt        j                  d|       }t        |      dk7  ry|D ]"  }|rt	        |      dk  st	        |      dkD  s" y yy)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   r6   r6     sh    	88)2.HHT2&E5zQ !CFQJ#a&3, !  r%   c           	         d}|rt         t        | |      st         d}	 t        t        j                  dt        j                  |             d         }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 # t        $ r8 t        t        j                  dt        j                  |             d         }Y w xY w)	z@Convert netmask to cidr. IPv6 dotted netmasks are not supported.r   r   >LFr   r   Tr[   )r    r6   longstructunpackr   	inet_aton	NameErrorr   ranger~   r.   )r:   r;   cidrmbitsbits	found_onens          r   rF   rF     s    D	"2r*
	EdF,<,<R,@A!DED 	r 	A	Q!# 	EQJE	 A:%2+rEz?DtR(K)  	Ev}}T6+;+;B+?@CDD	Es   5B, ,>C-,C-c                 B   d}|rt         t        | |      st         	 t        d      }t	        d      D ]  }|t        |       k  s|dd|z
  z  z  } t        j                  t        j                  d|            }t        ||      st         |S # t        $ r d}Y tw xY w)z<Convert cidr to netmask. IPv6 dotted netmasks not supported.r   r   r   r   r4   r   )r    r.   r   r   r   r   r   	inet_ntoar   packr6   )r   r;   r:   r   r   s        r   _cidr_to_dotted_netmaskr   3  s    	B	"4,
	7D r 	$A3t9}R!V#	$ fkk$56 r2&I  	D	s   B BBc           	         d| vrt        d       | S | j                  d      }t        |      dk7  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         }||z  }t        j                  t        j                  d|            }|d|S # t        $ rm t        t        j                  dt        j                  |            d         }t        t        j                  dt        j                  |            d         }Y w xY w)z8Convert an IPv4 address and netmask to a network addressr   z8_address4_to_network: skipping address without a netmaskr   r   Fr   r   )rI   r   r   r6   r    r.   r   r   r   r   r   r   r   r   r   r   )	r0   r"   hostorig_nmr:   	host_bitsnm_bitsnetwork_bitsrM   s	            r   rH   rH   P  sO   
$HI
**S/C
3x1}/A>q6D!fG	B2u%$R/DtV-=-=d-CDQGH	v}}T6+;+;B+?@CD
 w&Lv{{4>?Gw''  DdF,<,<T,BCAFG	fmmD&*:*:2*>?BCDs   +A*D
 
A3F ?F c                    d }d| vrt        d       | S | j                  d      }t        |      dk7  st        |d   d      st        |d   }|d   }t        j                  dt        j                  t        j                  |            }	 t        d      }t        d	      D ]>  } |||   d
      }t        d
      D ]"  }	|dt        ||	         z  d|	z
  |d
z  z
  z  z  }$ @ 	 t        d      }
t        d      D ]  }|t        |      k  s|
dd|z
  z  z  }
 ||
z  }g }t        d	      D ]0  }|j                  t         ||d      |d
z  |d
z  d
z    d             2 t        j                  t        j                  t        j                   d|d   |d   |d   |d   |d   |d   |d   |d   	            }|d|S # t        $ r d}Y 3w xY w# t        $ r d}
Y w xY w)z8Convert an IPv6 address and netmask to a network addressc           	          dj                  t        |dz
  dd      D cg c]  }t        | |z	  dz         c}      S c c}w )zDecimal to binaryr   r   r[   )r   r   r~   )r   countys      r   dec2binz%_address6_to_network.<locals>.dec2binu  s9    wwU57B5KLSAXN+LMMLs   =r   z8_address6_to_network: skipping address without a netmaskr   r   Tr   z>8H      ry   r   r\   r            )rI   r   r   r7   r    r   r   r   r,   r-   r   r   r   r   rE   rG   r   )r0   r   r"   	orig_hostnetmaskunpackedr   ir   jr   r1   r   rM   s                 r   _address6_to_networkr  s  s   N $HI
**S/C
3x1}M#a&$7AI!fG}}UF$4$4V__5>%@ AHG	 1X 9HQK$r 	9A!c!A$i-SU1R4Z88I	99q' 3Z *s7|qWM))G*
 g
C C1X <

3wsC(2ad2g6:;< v%{{5#a&#a&+.q63q63q6+.q63q63q6 CDG
 w''A  	  s$   F< $G <G
GGGc                    |j                  d      }t        |      dk7  st        |d   |      st        |d   }|d   }|dk(  s|dk(  ry| }d|v r9|j                  d      }t        |      dk7  st        |d   |      st        |d   }|dk(  s|dk(  ry|rt	        |      rt	        |      s"t        t        |      rt        |      st        t        ||      r|st        ||      }|rIt        |d|      j                  d      d   }t        |d|      j                  d      d   }||k(  S t        |d|      j                  d      d   }t        |d|      j                  d      d   }||k(  S )z&Determine if address x is in network yr   r   r   r   z0.0.0.0z::T)
r   r   r7   r    r2   r8   r.   r   r  rH   )	
tested_add
tested_netr;   r"   r   r   addressorig_networkrM   s	            r   
in_networkr
    s   


3
C
3x1}M#a&"5AI!fGId!2G
g~mmC s8q=c!fb 9a&)w$	g&nY.Gg&nY.G7B')'26 
+-6-A BBG%*QP&(/(: ;;@5:aI l"" ,-6-A BBG%*QP&(/(: ;;@5:aI l""r%   c                     t        | dg      \  }}|dk7  rt        t        j                  d| z        t	        j
                  d|      }t	        j                  dd|d         S )zReturn iptables versionz-Vr   zError running '%s'z\sz^vr   r   )r   r^   r_   r`   r*   r   sub)r   rl   rk   r"   s       r   get_iptables_versionr    sY    S$K IR	Qwell$8C$@AA
((4
C66$CF##r%   c                    d }|r1t        j                         dk7  rt        t        j                  d      g }d}| j                  d      rd}|t        dd      z  }t        | d	|g      \  }}|dk7  rt        t        j                  |       || |g d
      r|j                  d        || |g d      r|j                  d       t        | d|g       t        | d|g      \  }}|dk7  rt        t        j                  |      |S )z[Return capabilities set for netfilter to support new features. Callers
       must be root.c                 <    | d|g}t        ||z         \  }}|dk(  ryy)Nz-Ar   TF)r   )r   chainruleargsrl   rk   s         r   test_capz,get_netfilter_capabilities.<locals>.test_cap  s-    T5!t$	S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)
rg   getuidr^   r_   EPERMendswithr   r   r`   rE   )r   	do_checksr  capsr  rl   rk   s          r   get_netfilter_capabilitiesr"    s
    RYY[A%ekk>22DE
||K   
V22&&E S$&'IR	QwellC(( U 6 7L! U 0 1 	O$ dES$&'IR	QwellC((Kr%   c                 |   t        |       }t               }|j                         D ]  }|j                  d      s|j                  d      s'|j	                         }|d   }|d   j	                  d      d   }t               }dj                  |d   j	                  d      dd       |d<   |d	   |d
<   |d   j	                  d      d   |d<   |d   dk(  r	|d   |d<   n|d   j	                  d      d   |d<   ||vrt               ||<   g ||   |<   n|||   vrg ||   |<   ||   |   j                  |        |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   rE   )r;   netstat_outputdr   r"   r   r   items           r   parse_netstat_outputr/    sP    (+NA))+ $u%dooe.DjjlA1v||C $vQc!23B!78W!fU!fll3'*U;#u+DKa&,,s+A.DK>vAeHAeHTN1U8#!#%	%d#1$4 Hr%   c                    d}|rd}t         j                  j                  |      st        t        j
                  d|z        t        |      j                         D ]  }|j                         }| |d   k(  sdj                  t        dt        |d         d      D cg c]  }|d   ||dz     c}      }|d   j                         d	k7  sr|d
t        |d   j                         d      } |dk(  rt        t        j                  d      t!        j                   t         j"                  t         j$                        }	 t!        j&                  t)        j*                  |j-                         dt/        j0                  d| dd             dd       }t5        ||      d   S c c}w # t2        $ r t        t        j                  d      w xY w)zGet IP address for interfacer   /proc/net/if_inet6'%s' does not existr   r$  r   r   r   80r   r   No such devicei  256sN         )rg   r   existsr^   r_   r`   rR   r   r   r   r   r   r   r   r   ENODEVr   r5   
SOCK_DGRAMr   fcntlioctlrd   r   r   r   rO   )ifnamer;   r0   procr   r"   r  r   s           r   get_ip_from_ifr@  B  s   D 
#ww~~d#%,,(=(DEEJ((* 	ED**,CQxx38CAK3KLaCF1QqSMLN q6<<>T)&*CA,CDD	E 2:%,,(899MM&..&*;*;<	:##EKK
F$*KKs$D%FFH%M ND
 T2&q)) M  	:%,,(899	:s   F&
AF+ +$Gc           
         d}d}t        |       rd}d}n%t        |       st        t        j                  d      t
        j                  j                  |      st        t        j                  d|z        d}|rt        |      j                         D ]  }|j                         }|d   j                         }d	j                  t        d
t!        |d
         d      D cg c]  }|d
   ||dz     c}      }|d   j#                         dk7  r"|dt%        |d   j#                         d      }| |k(  sd|v st'        | |d      s|} |S  |S t        |      j                         D ]@  }d	|vr|j                  d	      d
   j                         }	 t)        |d      }	|	| k(  s=|} |S  |S c c}w # t        $ r Y Uw xY w)zGet interface for IP addressFz/proc/net/devTr1  r4  r2  r   r   r$  r   r   r   r3  r   r   )r2   r8   r   r_   r:  rg   r   r9  r^   r`   rR   r   r   stripr   r   r   r   r   r
  r@  )
r0   r;   r?  matchedr   r"   r>  r  tmp_addrips
             r   get_if_from_iprF  b  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LaCF1QqSMLNH1v||~%&.CFLLNB0GHxxJtXt$D   N9	8 N J((* 	D$ZZ_Q'--/F#FE2 Tz N	 N/ M   s   F.
F33	F?>F?c                  2   t        j                  d      } | j                          t        j                  d      }t               }| D ]  }|j                  |      st         j                  j                  d|d      }t        j                  |t         j                  t         j                  z        smd}	 t        j                  t         j                  j                  d|d            }	 t        j                  |      }|D ]`  }	 t        j                  t         j                  j                  ||            d   }|dt         j                  j                  |      ||<   b ! |S # t        $ r Y w xY w# t        $ r Y ?w xY w# t        $ r Y w xY w)zGet inodes of files in /procr   r   rj   r'  r   r   r   )rg   listdirr   r*   compiler)  r+   r   r   accessF_OKR_OKreadlinkr   r   basename)	
proc_filespatinodesr  fd_pathexe_pathdirsr  inodes	            r   _get_proc_inodesrV    sZ   G$JOO
**[
!CVF Fyy|'',,w40 yy"''BGG"34	{{277<<E#BCH	::g&D  	FAWa 89!< ()"''*:*:8*DEF5M	F+F8 M  		
  		  s6   74E+,E:6F
+	E76E7:	FF
	FFc                 l   ddddddddd	d
dd}ddddd}t         j                  j                  d|       }t        j                  |t         j                  t         j
                  z        st        g }d}t        |      j                         }|D ]  }|j                         }|sd}|t        ||d      d         }	| j                  d      rd}	n| j                  d      r|	d
k7  rX||d      j                  d      \  }
}||d      }||d      }|j                  |
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   rc  )
local_addrstater&  rU  z	/proc/netFTrg  r   r   NAr   rf  r$  r&  rU  )rg   r   r   rJ  rK  rL  r    rR   r   r   r   r+  rE   )protocol
tcp_statesproc_net_fieldsrS   r   skipped_firstlinesr   fieldsrg  r%  r   r&  rU  s                 r   _read_proc_net_protocolro    s]   #  !!!"  J '(!" !"O 
k8	,B99R277*+
CMH E > M3vog&>?DEu%E  'EX,=_\:;AA#Ft_U+,w/0

E3tR=#ue<=> Jr%   c                 X   d}t        |       dkD  rd}t        ddd      D ]8  }|dj                  t        |dz   |d      D cg c]
  }| |dz
  |  c}      z  }: t        dj                  t        dt        |      d      D cg c]  }|||dz    j	                          c}      d	      d   }|S g }t        ddd      D cg c]
  }| |dz
  |  c}D ]&  }|j                  t        t        |d
                   ( t        dj                  |      d      d   }|S c c}w c c}w c c}w )zDConvert an address from /proc/net/(tcp|udp)* to a normalized addressr   r   r   r   r   r$  r   Tr   .F)r   r   r   rO   r   rE   r~   r   )paddr	convertedr"   r  r  s        r   convert_proc_addressru    s2   I
5zA~q"a 	HA27751a3DFaU1Q3q\FGGC	H%chh,1!SXq,ABqAac
  "B'D	  ).q!R:A51Q<: 	(AJJs3q":'	(%chhsmU;A>	 GB ;s   DD"D'c                    t               }ddg}| r|ddgz  }|D ]  }	 t        |      ||<    t               }t        |j                               }|j                          d}|D ][  }||   D ]Q  \  }}	}
}}t        |      }d}t        |      |v r|t        |         }||dd	|d
|	dd	|dd	|
dd	|dd	|dz  }S ] |S # t        $ r t        d|z        }t	        |       Y w xY w)z5netstat-style output, without IPv6 address truncationr   r   tcp6udp6z!Could not get statistics for '%s'r   r'  5r   r$  4611r   )r)  ro  r   r   r)   rV  listkeysr   ru  r   )r;   proc_net_datar   pr   rQ  	protocolsr   r%  r   r&  rU  rg  r0   r   s                  r   r(  r(    s$   FMENE	&&!! 	6q9M! F]'')*INN
A 
O0=a0@ 		O,UD#ue'.DC5zV#SZ(qBF7M7<c5#O OA		O
O H/  	<BCHN	s   C"C*)C*c                     || S | j                  d      r7t        |       dk  r|}|S t        j                  j	                  || dd       }|S t        j                  j	                  ||       }|S )zAdd prefix to dirNr   r   r   )r+  r   rg   r   r   )r  r  newdirs      r   	_findpathr    sm    ~

~~cs8a<F
 M WW\\&#ab'2F M fc*Mr%   c                     t         j                  d   dk  rt        j                  | d      S t	        j
                  | j                  dd            j                  d      S )z,Take a string and convert it to a hex stringr   r\   hexr   r   )errorsr]   )rb   rf   codecsr   binasciihexlifydecode)r   s    r   
hex_encoder  )  sQ    
Q}}Q&& AHHWXH>?FFwOOr%   c                     t         j                  d   dk  r!| j                  d      j                  d      S t        j                  |       j                  d      S )z,Take a hex string and convert it to a stringr   r\   r  )encodingr   )rb   rf   r  r  	unhexlify)hs    r   
hex_decoder  2  sM    
Qxxx'..w77a ''00r%   c                 n    d}|s0t        | d      }t        j                  |t        j                         |S )zCreate a blocking lockfileNw)rR   r<  lockfLOCK_EX)lockfiledryrunlocks      r   create_lockr  9  s-    DHc"D%--(Kr%   c                     | y	 t        j                  | t         j                         | j                          y# t        $ r Y yw xY w)z(Free lockfile created with create_lock()N)r<  r  LOCK_UNrX   r    )r  s    r   release_lockr  B  s>    |D%--(

  	s   4: 	AA)r   )T)/sbin/iptables)r  T)F)z/run/ufw.lockF)H__doc__
__future__r   r  r  r_   r<  r   r   rg   r*   ro   r   r   rz   rb   	functoolsr   tempfiler   r   r   ra   supported_protocolsr   ipv4_only_protocolsr   r$   r2   r8   r7   r@   rO   rT   rY   rm   ru   r   r   r   r   r)   rc   r   rI   r   r   r   getpidr   r   r.   r6   rF   r   rH   r  r
  r  r"  r/  r@  rF  rV  ro  ru  r(  r  r  r  r  r   r%   r   <module>r     sq   (" &     	  	 	     
  $	
 K ; ( 4(42F	4nL G2(%	&* JJ 
H 299; 0 "))+ !N	2$\: (F7(t,#^$3l#L*@,^"J,^& FP1
r%   