Ë
    �ïe€  ã                   ó2  — 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d9d„Zd„ Z d„ Z!d„ Z"d„ Z#d:d„Z$d„ Z%d„ Z&d„ Z'd:d„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*„ Z:d;d+„Z;d<d,„Z<d-„ Z=d=d.„Z>d/„ Z?d0„ Z@d1„ ZAd2„ ZBd3„ ZCd4„ ZDd5„ ZEd6„ ZFd>d7„ZGd8„ ZHy)?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                 ó  — 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     ú*/usr/lib/python3/dist-packages/ufw/util.pyÚget_services_protor   .   s©   € à€EðÜ×Ñ˜TÔ"ðÜ×Ñ˜T 5Ô)ØˆðÜ×Ñ˜T 5Ô)Ø�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Ü
ˆ3ƒx�1‚}Ø�1‰vˆØˆð �%ˆ=Ðô 
ˆS‹�QŠØ�1‰vˆØ�A‘ˆØÔ&Ñ&ÜÐ9¸EÑAÓBˆGÜ˜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_address6r3   \   s    € ä�?Š?ÜÐ1Ô2Øô ˆ4ƒy�2‚~œRŸX™XÐ&;¸TÔBØà
�*‰*�S‹/€CðÜ×ÑœŸ™¨#¨a©&Ô1ô ˆ3ƒx�!‚|ØÜ	ˆS‹�QŠä" 3 q¡6¨4Ô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_netmaskr0   s     r   Úvalid_address4r9   v   s¢   € ô ˆ4ƒy�2‚~œRŸX™X n°dÔ;Øà
�*‰*�S‹/€CðÜ×ÑœŸ™¨¨Q©Ô0ä" 3 q¡6¨5Ô1Øð 2ô
 ˆ3ƒx�!‚|ØÜ	ˆS‹�QŠä˜S ™V UÔ+Øàøô ò Ùðús   ¸6B Â	B*Â)B*c                 ó6   — t        | |«      xs t        | |«      S )z(Verifies if valid cidr or dotted netmask)r/   r7   )ÚnmÚv6s     r   r8   r8   �   s   € ä˜r 2Ó&Ò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   )r3   r9   r!   )r1   Úversions     r   Úvalid_addressrA   š   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)zÎConvert 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�{Ø�j‰j˜‹oˆá�#�a‘&˜E’/Ø�A‘Ù˜˜Q™ 4š¨3¨q©6Ð5FÒ+FØ�A‘à�
‰
�4Ôá”#�c“(˜a’-Ô$7¸¸A¹ÀÔ$Cð	Ü,¨S°©V°RÓ8ˆC�‰Fð
 ˆq‰6€Dô ×Ñ˜F¤F×$4Ñ$4°V¸TÓ$BÓC€DØˆs�1‰v‚~Øˆä
ˆ3ƒx�1‚}Ø��c˜!‘f‘ÑˆÙÜ*¨4Ó0ˆGØ˜$‹Ú;BÂDÐI�Ü�g”Ø�Ø�ä˜˜wÔ'Ø(¨DÑ1ˆÜˆgŒÜÐà�'ˆ?Ðøô5 ò 	áð	ús   ÂE	 Å		EÅEc                 ó   — t        | d«      S )z"Opens the specified file read-onlyÚr)Úopen)Úfns    r   Úopen_file_readrU   Ý   s   € ä��C‹=Ðr&   c                 ó~   — t        | «      }	 t        «       \  }}|| ||dœS # t        $ r |j                  «        ‚ w xY w)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   â   sJ   € ä˜"Ó€DðÜ ›‰ˆˆgð
  r°#À'ÑKÐKøô	 ò Ø�
‰
ŒØðús   �! ¡<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 descriptoréÿÿÿÿr   é   Ú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ª   € ð ˆb‚yØáÜ”e—l‘lÐ$AÓBÐBõ �bœCŸJ™J×-Ñ-Ó/Ò/Ü×Ñ˜ÔØà	€Bä
×Ñ˜Ñ˜aÒÜ�X‰X�bœ%  WÓ-Ó.‰ä�X‰X�b˜#Óˆà	ˆQ‚wÜ”e—i‘iÐ!EÓFÐFð r&   Tc                 óþ   — | d   j                  «        t        j                   | d   «       |r8t        j                  | d   | d   «       t        j                  | d   | d   «       t        j
                  | d   «       y)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     sc   € ð ˆ�K×ÑÔÜ‡H�HˆS�‰ZÔáÜ�‰˜˜J™¨¨Y©Ô8Ü�‰�C˜	‘N C¨
¡OÔ4ä‡I�Iˆc�)‰nÕr&   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)rd   ÚstderrÚuniversal_newlinesé   Nr   )	rJ   Ú
subprocessÚPopenÚPIPEÚSTDOUTr_   ÚstrÚcommunicateÚ
returncode)ÚcommandÚspÚexrl   s       r   Úcmdr…     sx   € ä	ˆ'„NðÜ×Ñ˜g¬j¯o©oÜ%/×%6Ñ%6Ø15ô7ˆð �.‰.Ó
˜1Ñ
€CØ�M‰Mœ3˜s›8Ð$Ð$øô	 ò Ø”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.)rd   )Ústdinrz   Nr   )r{   r|   r}   rd   r_   r   r€   r�   )Úcommand1Úcommand2Úsp1Úsp2r„   rl   s         r   Úcmd_piperŒ   $  sy   € ðÜ×Ñ˜x´
·±Ô@ˆÜ×Ñ˜x¨s¯z©zÔ:ˆð �/‰/Ó
˜AÑ
€CØ�N‰NœC ›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   Úencoderb   ÚinspectÚisclassÚioÚStringIOrf   ri   Úflush)ÚoutputÚsÚwriterrl   s       r   Ú_printrš   2  sˆ   € ðØ—‘ˆðØ�h‰h�w Ó)ˆõ
 ”g—o‘o¤b§k¡kÔ2Ø�‰�Q�à�‰”U˜3“ZÔ Ø
‡L�L…Nøô ò ØŠðûô ò ØŠðú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š   rc   rx   ÚIOErrorÚexit)rl   Údo_exits     r   ÚerrorrŸ   G  sC   € ðÜŒs�z‰z˜=¨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š   rc   rx   rœ   ©rl   s    r   r*   r*   R  s,   € ðÜŒs�z‰z˜<¨#Ñ-Õ.øÜò Ùðú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
ú%sN)rb   rc   rd   rš   rœ   )rl   r—   Únewlines      r   Úmsgr¥   Z  sK   € å�f¤§
¡
Ò*ÜˆðÙÜ�6˜6 C™<Õ(ä�6˜4 #™:Õ&øÜò Ùðú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š   rc   rx   rœ   r¡   s    r   rJ   rJ   h  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>w  sV   € ÙØœ#˜d›) D§J¡J¨tÓ$4Ñ4°qÑ8Ü˜dŸj™j¨¨qÓ1°!Ñ4Ó5ñ6Ø9>ñ?ò Aáð	3€ r&   ú )r   r   )Útextr®   s     r   Ú	word_wrapr²   q  s%   € ô ¨5ò ð
 —*‘*˜S“/óð r&   c                 ó   — t        | d«      S )zWord wrap to a specific widthéK   )r²   )r±   s    r   Ú	wrap_textrµ   €  s   € ä�T˜2ÓÐ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   € ˜qŸy™yœ{”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$   ø€ ¬b¯h©h°zÀ1Ó.EÖF¨™T !�WÒF€ ùÒFs   š,)ÚkeyN)Úsort)ÚlstrÀ   s    @r   Ú
human_sortrÄ   …  s   ø€ ñ :€DØ‡H�HÓF€HÕGr&   c                 óŽ  — 	 t        | «      }t        j                  j                  dt        |«      d«      }t        j                  j                  |«      st        d|z  «      ‚t        |«      j                  «       d   j                  dd«      d   j                  «       d   }t        |«      S # t        $ r t        d«      ‚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!   rh   ÚpathÚjoinr   Úisfilerœ   rS   Ú	readlinesÚrsplitr   )ÚmypidÚpidÚnameÚppids       r   Úget_ppidrÓ   “  s­   € ð3Ü�%‹jˆô �7‰7�<‰<˜¤ S£¨6Ó2€DÜ�7‰7�>‰>˜$ÔÜÐ*¨dÑ3Ó4Ð4ô �‹:×ÑÓ! !Ñ$×+Ñ+¨C°Ó3°AÑ6×<Ñ<Ó>¸qÑA€Däˆt‹9Ðøô ò 3ÜÐ1Ó2Ð2ð3ús   ‚B/ Â/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!   rh   rÊ   rË   rÌ   rS   rÍ   r   rJ   Ú	under_ssh)rÐ   rÒ   Úwarn_msgr$   rÊ   Úexes         r   rÕ   rÕ   ª  s/  € ð"Ü˜‹}ˆð ˆa‚x�4˜1’9Øä�7‰7�<‰<˜¤ T£¨FÓ3€DÜ�7‰7�>‰>˜$ÔÜÐ(Ó)¨TÑ2ˆÜ˜Ó!Ð!ð"Ü�4‹j×"Ñ"Ó$ QÑ'×-Ñ-Ó/°Ñ2ˆô 
Ð
" cÑ
*Ô+ð ˆh‚Øä˜‹Ðøô; ò ÜÐ<Ó=ˆÜˆXŒÙÜò "ÜÐ7Ó8¼CÀ»HÑEˆÜ˜Ó!Ð!ð"ûô  ò "ÜÐ8Ó9¸TÑ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Ù	Øˆä�8‰8�K Ô$¬¨B«°!ª´s¸2³wÀ²}Øàr&   c                 óÆ   — |ryt        j                  d| «      rH| 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\.]+$ú.é   r   éÿ   T)r+   r,   r   r   rº   )r;   r<   ÚquadsÚqs       r   r7   r7   Ý  se   € á	Øä�8‰8Ð)¨2Ô.Ø—H‘H˜S“MˆEÜ�5‹z˜QŠØØò !�ÙœC ›F QšJ¬#¨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!   r7   ÚlongÚstructÚunpackr   Ú	inet_atonÚ	NameErrorrº   Úranger   r/   )r;   r<   ÚcidrÚmbitsÚbitsÚ	found_oneÚns          r   rG   rG   ö  sü   € à€DÙ	ÜÐä" 2 rÔ*ÜÐàˆð
	EÜœŸ™ d¬F×,<Ñ,<¸RÓ,@ÓAÀ!ÑDÓEˆDð ˆ	Ü�r“ò 	ˆAØ˜‘	˜Q‰ !Ò#Ø ‘	áØ�EÙà˜Q‘J‘Eð	ð �AŠ:˜% 2š+Ü�r˜E‘z“?ˆDä˜t RÔ(ÜÐà€Køô) ò 	EÜ”v—}‘} T¬6×+;Ñ+;¸BÓ+?Ó@ÀÑCÓDŠDð	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   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¨Ô,ÜÐð
	Ü˜“7ˆDô �r“ò 	$ˆAØ”3�t“9‹}Ø˜˜R !™V™Ñ#‘ð	$ô ×ÑœfŸk™k¨$°Ó5Ó6ˆô ˜r 2Ô&ÜÐà€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ä   )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  sO  € à
�$�ÜÐHÔIØˆà
�*‰*�S‹/€CÜ
ˆ3ƒx�1‚}Ô/°°A±¸Ô>ÜÐàˆq‰6€DØ�!‰f€Gà	€BÜ˜2˜uÔ%Ü$ R¨Ó/ˆðDÜœŸ™ t¬V×-=Ñ-=¸dÓ-CÓDÀQÑGÓHˆ	Ü”v—}‘} T¬6×+;Ñ+;¸BÓ+?Ó@ÀÑCÓDˆð
 ˜wÑ&€LÜ×ÑœvŸ{™{¨4°Ó>Ó?€Gâ™wÐ'Ð'øô ò DÜœŸ™ d¬F×,<Ñ,<¸TÓ,BÓCÀAÑFÓGˆ	Ü”f—m‘m D¬&×*:Ñ*:¸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>.dec2binf  s9   € à�w‰w´U¸5À¹7ÀBÈÓ5KÖL°œ˜S A™X¨™NÕ+Ò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Ü
ˆ3ƒx�1‚}œM¨#¨a©&°$Ô7ÜÐà�A‘€IØ�!‰f€Gä�}‰}˜U¤F×$4Ñ$4´V·_±_Ø5>ó%@ó A€HðÜ˜“Gˆ	ô �1‹Xò 9ˆÙ�H˜Q‘K Ó$ˆÜ�r“ò 	9ˆAØ˜!œc ! A¡$›i™-¨S°©U°1°R±4©ZÑ8Ñ8‰Iñ	9ð9ðÜ�q“'ˆô �3‹Zò *ˆØŒs�7‹|ÓØ�q˜W¨™MÑ)Ñ)‰Gð*ð
 �gÑ
€Cð €CÜ�1‹Xò <ˆØ�
‰
”3‘w˜s CÓ(¨¨2©¨a°©d°2©gÐ6¸Ó:Õ;ð<ô ×ÑœvŸ™Ü%Ÿ{™{¨5°#°a±&¸#¸a¹&Ø+.¨q©6°3°q±6¸3¸q¹6Ø+.¨q©6°3°q±6¸3¸q¹6ó 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   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Ü
ˆ3ƒx�1‚}œM¨#¨a©&°"Ô5ÜÐà�A‘€IØ�!‰f€Gà�IÒ ¨dÒ!2Øà€GØ
ˆg�~Ø�m‰m˜CÓ ˆÜˆs‹8�qŠ=¤¨c°!©f°bÔ 9ÜÐØ�a‘&ˆà�)Ò˜w¨$šØá	Ü˜gÔ&¬n¸YÔ.GÜÐä˜gÔ&¬n¸YÔ.GÜÐä˜7 BÔ'±Ü)¨'°2Ó6ˆñ 
Ü+Ú-6¹ð-Aó BßBGÁ%ÈÃ*ÈQñPˆä&Ú(/±ð(:ó ;ß;@¹5À»:ÀañIˆð �lÑ"Ð"ô ,Ú-6¹ð-Aó BßBGÁ%ÈÃ*ÈQñPˆä&Ú(/±ð(:ó ;ß;@¹5À»:ÀañIˆð �lÑ"Ð"r&   c                  óÜ   — d} dD ]E  }t         j                  j                  |d«      } t         j                  j                  | «      r nd} ŒG | 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  Ò  sf   € Ø
€Cð3ò ˆô �g‰g�l‰l˜1˜jÓ)ˆÜ�7‰7�>‰>˜#ÔÙà‰Cðð ˆb‚yÜ”e—l‘lÐ$=Ó>Ð>Ø€Jr&   c                 óÒ   — | €
t        «       } t        | dg«      \  }}|dk7  rt        t        j                  d| z  «      ‚|j                  «       }t        j                  dd|d   «      S )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  á  sa   € à
€{Ü#Ó%ˆä�S˜$�KÓ �I€RˆØ	ˆQ‚wÜ”e—l‘lÐ$8¸CÑ$@ÓAÐAØ
�)‰)‹+€CÜ�6‰6�$˜˜C ™FÓ#Ð#r&   c                 ó(  — d„ }|r1t        j                  «       dk7  rt        t        j                  d«      ‚| €
t        «       } 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Úargsrm   rl   s         r   Útest_capz,get_netfilter_capabilities.<locals>.test_capñ  s-   € Ø�T˜5Ð!ˆÜ˜˜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)rh   Úgetuidr_   r`   ÚEPERMr  Úendswithr   r…   ra   rF   )r×   Ú	do_checksr  Úcapsr  rm   rl   s          r   Úget_netfilter_capabilitiesr,  î  s  € òñ ”R—Y‘Y“[ AÒ%Ü”e—k‘k >Ó2Ð2à
€{Ü#Ó%ˆà€Dà€EØ
‡|�|�KÔ Ø ˆð 
ŒV˜2 2Ô&Ñ&€Eô �S˜$ Ð&Ó'�I€RˆØ	ˆQ‚wÜ”e—l‘l CÓ(Ð(ñ ��Uò 6ô 7à�‰�LÔ!ñ ��Uò 0ô 1ð 	�‰�OÔ$ô ˆˆd�EÐÔÜ�S˜$ Ð&Ó'�I€RˆØ	ˆQ‚wÜ”e—l‘l CÓ(Ð(à€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Ë   rF   )r<   Únetstat_outputr  r¬   r#   r   r   Úitems           r   Úparse_netstat_outputr8  '  sP  € ô (¨Ó+€Nä‹€AØ×)Ñ)Ó+ó $ˆØ�‰˜uÔ%¨d¯o©o¸eÔ.DØà�j‰j‹lˆà�A‘ˆØ�1‰v�|‰|˜CÓ  Ñ$ˆä‹vˆØŸ™  Q¡§¡¨cÓ!2°3°BÐ!7Ó8ˆˆW‰Ø˜!‘fˆˆU‰Ø˜!‘f—l‘l 3Ó'¨Ñ*ˆˆU‰Ø�‰;˜#ÒØ˜u™+ˆD�ŠKà˜a™&Ÿ,™, sÓ+¨AÑ.ˆD�‰Kà˜‰>Ü“vˆAˆe‰HØˆAˆe‰H�TŠNà˜1˜U™8Ñ#Ø!#��%‘˜‘Ø	ˆ%‰�‰×Ñ˜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(  rŸt        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é   é   é   )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_ifrH  M  s•  € à€Dò 
Ø#ˆÜ�w‰w�~‰~˜dÔ#Üœ%Ÿ,™,Ð(=ÀÑ(DÓEÐEä˜“J×(Ñ(Ó*ò 	EˆDØ—*‘*“,ˆCØ˜˜Q™ÓØ—x‘xÜ38¸¼CÀÀAÁ»KÈÓ3KÖL¨a˜C ™F 1 Q q¡SšMÒLóN�ð �q‘6—<‘<“> TÓ)Ú&*¬C°°A±·±³ÀÔ,CÐD‘Dð	Eð �2Š:Üœ%Ÿ,™,Ð(8Ó9Ð9ä�M‰Mœ&Ÿ.™.¬&×*;Ñ*;Ó<ˆð	:Ü×#Ñ#¤E§K¡K°·±³
¸FÜ$*§K¡K°¸¸sÀ¸Ó$Dó%FØFHÈð%Mó NˆDô
 ˜T 2Ó& 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}|rÖt        |«      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/devTr:  r=  r;  r   r  r.  r   rß   r   r<  r   r   )r3   r9   rœ   r`   rB  rh   rÊ   r  r_   ra   rS   rÍ   r   ÚstriprË   rê   r   r»   rº   r  rH  )
r1   r<   rG  Úmatchedr¬   r#   rF  r  Útmp_addrÚips
             r   Úget_if_from_iprN  m  sÁ  € à	€BØ€DÜ�dÔØˆØ#‰Ü˜DÔ!Ü”e—l‘lÐ$4Ó5Ð5ä�7‰7�>‰>˜$ÔÜ”e—l‘lÐ$9¸DÑ$@ÓAÐAà€Gá	Ü˜“J×(Ñ(Ó*ò 	ˆDØ—*‘*“,ˆCØ˜‘V—\‘\“^ˆFà—x‘xÜ38¸¼CÀÀAÁ»KÈÓ3KÖL¨a˜C ™F 1 Q q¡SšMÒLóNˆHà�1‰v�|‰|‹~ Ò%Ú&.´°C¸±F·L±L³NÀBÔ0GÐH�à�xÒØ�x’¤J¨t°X¸tÕ$DØ �Øð  €Nð9	ð8 €Nô ˜“J×(Ñ(Ó*ò 	ˆDØ˜$‰ØØ—Z‘Z “_ QÑ'×-Ñ-Ó/ˆFðÜ# F¨EÓ2�ð �T‹zØ �Øà€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Û   rk   r1  r×   r   r   )rh   ÚlistdirrÂ   r+   Úcompiler3  r,   rÊ   rË   ÚaccessÚF_OKÚR_OKÚreadlinkr   rÇ   Úbasename)	Ú
proc_filesÚpatÚinodesr  Úfd_pathÚexe_pathÚdirsr  Úinodes	            r   Ú_get_proc_inodesr^  œ  sZ  € ä—‘˜GÓ$€JØ‡O�OÔÜ
�*‰*�[Ó
!€CÜ‹V€FØó FˆØ�y‰y˜Œ|Øä—'‘'—,‘,˜w¨¨4Ó0ˆô �y‰y˜¤"§'¡'¬B¯G©GÑ"3Ô4Øàˆð	Ü—{‘{¤2§7¡7§<¡<°¸¸EÓ#BÓCˆHð	Ü—:‘:˜gÓ&ˆDð ò 	FˆAðÜŸ™¤§¡§¡¨W°aÓ 8Ó9¸!Ñ<�ò ()¬"¯'©'×*:Ñ*:¸8Ô*DÐEˆF�5ŠMò	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  rk  )Ú
local_addrÚstater0  r]  z	/proc/netFTro  r   r   ÚNAr   rn  r.  r0  r]  )rh   rÊ   rË   rR  rS  rT  r!   rS   rÍ   r   rº   r5  rF   )ÚprotocolÚ
tcp_statesÚproc_net_fieldsrT   rÃ   Úskipped_firstÚlinesr¬   Úfieldsro  r/  r   r0  r]  s                 r   Ú_read_proc_net_protocolrw  Á  s]  € à#Ø Ø Ø!Ø!Ø!ØØ"Ø ØØ ñ€Jð '(Ø!"Ø Ø!"ñ€Oô 
�‰�‰�k 8Ó	,€Bä�9‰9�RœŸ™¤2§7¡7Ñ*Ô+ÜÐà
€CØ€MÜ�‹H×ÑÓ €EØò >ˆØ—‘“ˆÙØ ˆMØØœ3˜v o°gÑ&>Ñ?ÀÓDÑEˆØ×Ñ˜uÔ%Ø‰EØ× Ñ  Ô'¨E°XÒ,=ØØ˜_¨\Ñ:Ñ;×AÑAÀ#ÓF‰ˆˆtØ�_ UÑ+Ñ,ˆØ� wÑ/Ñ0ˆØ�
‰
�Eœ3˜t R›=¨#¨u°eÐ<Õ=ð>ð €Jr&   c                 óX  — d}t        | «      dkD  r d}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   rÞ   F)r   rê   rË   rP   r»   rF   r   rº   )ÚpaddrÚ	convertedr#   r  r  s        r   Úconvert_proc_addressr|  ð  s2  € à€IÜ
ˆ5ƒz�A‚~ØˆÜ�q˜"˜a“ò 	HˆAØ�2—7‘7´5¸¸1¹¸aÀÓ3DÖF¨a˜U 1 Q¡3 qš\ÒFÓGÑG‰Cð	Hä% c§h¡hÜ,1°!´S¸³X¸qÓ,AÖB q��A�a˜‘c�
× Ñ Õ"ÒBó'Dàóàñˆ	ð Ðð ˆÜ).¨q°!°R«Ö: A�5˜˜1™˜Q’<Ò:ò 	(ˆAØ�J‰J”sœ3˜q "›:“Õ'ð	(ä% c§h¡h¨s£m°UÓ;¸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   r1  Ú5r°   r.  Ú46Ú11rª   )r3  rw  r   r    r*   r^  ÚlistÚkeysrÂ   r|  rº   )r<   Úproc_net_datar   ÚprÖ   rY  Ú	protocolsr˜   r/  r   r0  r]  ro  r1   r×   s                  r   r2  r2    s$  € ä“F€MØ�EˆN€EÙ	Ø�&˜&Ð!Ñ!ˆØò ˆð	Ü6°qÓ9ˆM˜!Òðô Ó€Fä�]×'Ñ'Ó)Ó*€IØ‡N�NÔà
€AØò 
OˆØ0=¸aÑ0@ò 		OÑ,ˆU�D˜#˜u eÜ'¨Ó.ˆDàˆCÜ�5‹z˜VÑ#àœS ›ZÑ(�Ø³qÚBFÉÓ7MÛ7<»cÃ5Ê#ðOñ O‰Añ		Oð
Oð €Høô/ ò 	ÜÐ<ÀÑBÓCˆHÜ�Œ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   )r5  r   rh   rÊ   rË   )r   r  Únewdirs      r   Ú	_findpathrŠ  &  sm   € à€~Øˆ
Ø
‡~�~�cÔÜˆs‹8�aŠ<ØˆFð
 €Mô —W‘W—\‘\ &¨#¨a¨b¨'Ó2ˆFð €Mô —‘—‘˜f cÓ*ˆØ€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^   )rc   rg   Úcodecsr‘   ÚbinasciiÚhexlifyÚdecode)r˜   s    r   Ú
hex_encoder’  4  sQ   € ä
×Ñ˜Ñ˜QÒÜ�}‰}˜Q Ó&Ð&ô ×Ñ˜AŸH™H W°X˜HÓ>Ó?×FÑFÀwÓOÐOr&   c                 óæ   — t         j                  d   dk  r!| j                  d¬«      j                  d«      S t        j                  dt        | «      dz  r| dd	 n| z  «      j                  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˜  =  sn   € ä
×Ñ˜Ñ˜QÒØ�x‰x ˆxÓ'×.Ñ.¨wÓ7Ð7ô ×Ñ˜d´°A³¸²
 a¨¨¡fÀÑBÓC×JÑJØÐ#óð r&   c                 ón   — d}|s0t        | d«      }t        j                  |t        j                  «       |S )zCreate a blocking lockfileNÚw)rS   rD  ÚlockfÚLOCK_EX)ÚlockfileÚdryrunÚlocks      r   Úcreate_lockr   L  s-   € à€DÙÜ�H˜cÓ"ˆÜ�‰�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)rD  r›  ÚLOCK_UNrY   r!   )rŸ  s    r   Úrelease_lockr£  U  s>   € à€|ØðÜ�‰�Dœ%Ÿ-™-Ô(Ø�
‰
�øÜò ñ 	ðús   …4: º	AÁA)r   )Tr¸   )NT)F)z/run/ufw.lockF)IÚ__doc__Ú
__future__r   r�  rŽ  r`   rD  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  r,  r8  rH  rN  r^  rw  r|  r2  rŠ  r’  r˜  r   r£  © r&   r   ú<module>r¬     sv  ðÙ (õ" &Û Û Û Û Û 	Û Û 	Û 	Û Û Û Û Û 
å ß $à€	Ø€
ò QÐ ÚAÐ Ø˜vÐ&Ð òò4ò(ò4ò2Fó	ò4ònò

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