+
    iF  c                   s   ^ RI t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	H
t
 ]! ^ ^4       U u/ uF  p V ^8  d
   V ^8  d   K  V RbK  	  up tR tR tR+R ltR tR tR	 tR
 tR tR tR tR tR tR tR tR tR tR tR tR tR t R t!R t"R t#R t$R t%R t&R t'R t(R  t)R! t*R" t+R# t,R$ t-R% t.R& t/R' t0R( t1R) t2R* t3R# u up i ),    N)log)FIREWALLD_TEMPDIRFIREWALLD_PIDFILEc                s    \        V \        4      '       d   T pM$V '       d   V P                  4       p  \        V 4      pVR8  d   R# V#   \         d:     \        P
                  ! T 4      p L/  \        P                   d    Ru u # i ; ii ; i)zCheck and Get port id from port string or port id using socket.getservbyname

@param port port string or port id
@return Port id if valid, -1 if port can not be found and -2 if port is too big
  )
isinstanceintstrip
ValueErrorsocketZgetservbynameerror)portZ_id   & 7/usr/lib/python3.14/site-packages/firewall/functions.py	getPortIDr      s     $::<D	d)C U{	J  	**40<< 		s)   A	 	BA--B	BB		Bc                sd   \        V \        4      '       g   \        V \        4      '       d   V # \        V \        4      '       g   V P	                  4       '       d   \        V 4      pV^ 8  d   V3# V# V P                  R4      p\        V4      ^8X  d   V^ ,          P	                  4       '       de   V^,          P	                  4       '       dH   \        V^ ,          4      p\        V^,          4      pV^ 8  d   V^ 8  d   W8  d   W3# W8  d   W13# V3# . p\        \        V4      ^ R4       F  p\        RP                  VRV 4      4      pRP                  W%R 4      p\        V4      ^ 8  df   \        V4      pV^ 8  dR   V^ 8  dI   W8  d   VP                  W34       Kv  W8  d   VP                  W134       K  VP                  V34       K  K  K  V^ 8  g   K  VP                  V34       V\        V4      8X  g   K   M	  \        V4      ^8  d   R# \        V4      ^8  d   R# V^ ,          # )a<  Get port range for port range string or single port id

@param ports an integer or port string or port range string
@return Array containing start and end port id for a valid range or -1 if port can not be found and -2 if port is too big for integer input or -1 for invalid ranges or None if the range is ambiguous.
-Nr   )r   Ztuplelistr   isdigitr   splitlenrangejoinappend)ZportsZid1splitsZid2ZmatchediZport2s   &      r   getPortRanger   5   s    %:eT#:#: %!86M
[[F 6{aF1I--//F1I4E4E4G4Gq	"q	"!8qyz!z!v G3v;2&,-$u:>E"CaxC1H9NNC:.YNNC:.NNC6* %x axv&F## '$ 7|a		W	1:    c                s    V R8X  d   R# \        V 4      p\        V\        4      '       d
   V^ 8  d   R# \        V4      ^8X  d
   RV,          # V^ ,          : V: V^,          : 2# )a  Create port and port range string

@param port port or port range int or [int, int]
@param delimiter of the output string for port ranges, default ':'
@return Port or port range string, empty string if port isn't specified, None if port or port range is not valid
 Nz%s)r   r   r   r   )r   Z	delimiter_range   && r   portStrr    p   sY     rz$F&#6A:	V	f}!!9i;;r   c                 s   \        V 4      p\        V4      p\        V4      ^8X  d   \        V4      ^8X  d&   \        V^ ,          4      \        V^ ,          4      8H  # \        V4      ^8X  dQ   \        V^ ,          4      \        V^ ,          4      8  d*   \        V^ ,          4      \        V^,          4      8:  d   R# R# \        V4      ^8X  d   \        V4      ^8X  d   \        V^ ,          4      \        V^ ,          4      8  dx   \        V^ ,          4      \        V^,          4      8:  dQ   \        V^,          4      \        V^ ,          4      8  d*   \        V^,          4      \        V^,          4      8:  d   R# R# )   TF)r   r   r   )r   r   Z_portr      &&  r   portInPortRanger#      s   E% F
5zQv;!U1X&)F1I*>>>K1%(#y';;%(#y';;  
UqK1%(#y';;%(#y';;%(#y';;%(#y';;r   c                sN   \        V 4      p\        V4      ^8X  d   V^ ,          V^ ,          3p\        \         V4      p\        \        R V4      R R7      p. pV EF  pV^ ,          V^ ,          8:  d)   V^,          V^,          8  d   VP	                  V4       KA  V^ ,          V^ ,          8:  dP   V^,          V^,          8  d;   V^,          V^ ,          8  d&   VP	                  V4       V^ ,          V^,          3pK  V^ ,          V^ ,          8  g   K  V^,          V^,          8  g   K  V^ ,          V^,          8:  g   K  VP	                  V4       V^ ,          V^,          3pEK  	  \        \        R V4      4      pV^ ,          V^,          8X  d   V^ ,          3pV.V3# )zCoalesce a port range with existing list of port ranges

@param new_range tuple/list/string
@param ranges list of tuple/list/string
@return tuple of (list of ranges added after coalescing, list of removed original ranges)
c                 J    \        V 4      ^8X  d   V ^ ,          V ^ ,          3# T # r!   r   x   &r   <lambda>#coalescePortRange.<locals>.<lambda>   "    c!fkqtQqTl8q8r   c                     V ^ ,          # r     r'   r)   r   r*   r+          RSTURVr   Zkeyc                 D    V ^ ,          V ^,          8X  d   V ^ ,          3# T # r.   r/   r'   r)   r   r*   r+           1Q41Q4<1(FQ(Fr   r   r   mapZsortedr   r   )Z	new_rangerangesZcoalesced_range_rangesremoved_rangesr      &&    r   coalescePortRanger:      s    #9-O
?q *1-q/AB,'G8'BG N1q)oa.@E!H.L!!%(A%(*"U1X-"eAh. !!%(.q158<OAq)"eAh."eAh. !!%($Qx);<O' , #FWXNq_Q//*1-/~..r   c                s   \        V 4      p \        V 4      ^8X  d   V ^ ,          V ^ ,          3p \        \         V4      p\        \        R V4      R R7      p. p. pV EF  pV ^ ,          V^ ,          8:  d)   V ^,          V^,          8  d   VP	                  V4       KA  V ^ ,          V^ ,          8:  df   V ^,          V^,          8  dQ   V ^,          V^ ,          8  d<   VP	                  V4       VP	                  V ^,          ^,           V^,          34       K  V ^ ,          V^ ,          8  dg   V ^,          V^,          8  dR   V ^ ,          V^,          8:  d=   VP	                  V4       VP	                  V^ ,          V ^ ,          ^,
          34       EK6  V ^ ,          V^ ,          8  g   EKN  V ^,          V^,          8  g   EKf  VP	                  V4       VP	                  V^ ,          V ^ ,          ^,
          34       VP	                  V ^,          ^,           V^,          34       EK  	  \        \        R V4      4      p\        \        R V4      4      pWC3# )zbreak a port range from existing list of port ranges

@param remove_range tuple/list/string
@param ranges list of tuple/list/string
@return tuple of (list of ranges added after breaking up, list of removed original ranges)
c                 r$   r%   r&   r'   r)   r   r*    breakPortRange.<locals>.<lambda>   r,   r   c                 r-   r.   r/   r'   r)   r   r*   r;      r0   r   r1   c                 r2   r.   r/   r'   r)   r   r*   r;      r3   r   c                 r2   r.   r/   r'   r)   r   r*   r;      s     11qtg&D1&Dr   r4   )Zremove_ranger6   r7   r8   Zadded_rangesr   r9   r   breakPortRanger<      s     -L
<A$Qa9,'G8'BG NL?eAh&<?eAh+F!!%(OuQx'Q%(*Q58+ !!%(a1!4eAh ?@OeAh&Q58+Q58+ !!%(q<?Q+> ?@!_uQx'LOeAh,F!!%(q<?Q+> ?@a1!4eAh ?@1 6 #FWXNDlSTL))r   c                s     \         P                  ! \        V 4      V4      pV#   \         P                   d     R# i ; i)zCheck and Get service name from port and proto string combination using socket.getservbyport

@param port string or id
@param protocol string
@return Service name if port and protocol are valid, else None
N)r   Zgetservbyportr   r   )r   ZprotoZnamer   r   getServiceNamer=      s<    ##CIu5 K << s    $ ==c                s     \         P                  ! \         P                  V 4       R#   \         P                   d     R# i ; i)z[Check IPv4 address.

@param ip address string
@return True if address is valid, else False
FT)r   	inet_ptonZAF_INETr   ipr)   r   checkIPrA     s8    ,  << s   %) AAc                s$    V P                  R4      # )zNormalize the IPv6 address

This is mostly about converting URL-like IPv6 address to normal ones.
e.g. [1234::4321] --> 1234:4321
z[])r	   r?   r)   r   normalizeIP6rB     s     88D>r   c                s     \         P                  ! \         P                  \        V 4      4       R#   \         P                   d     R# i ; i)z[Check IPv6 address.

@param ip address string
@return True if address is valid, else False
FT)r   r>   ZAF_INET6rB   r   r?   r)   r   checkIP6rC   &  s=    ,r*:;  << s   .2 A
Ac                 s:   V P                  R 4      pVR8w  d$   V RV pW^,           R pV'       d	   V'       g   R# MT pRp\        V4      '       g   R# V'       d/   RV9   d   \        V4      #  \        V4      pT^ 8  g   T^ 8  d   R# R#   \         d     R# i ; i)/NF.Tr   )findrA   r   r
   r@   ZindexZaddrZmaskr      &    r   checkIPnMaskrI   4  s    GGCLE{&5z!)+4   4==$;4= I 1uB	  s   .B BBc                 s,    V P                  \        4      # N)Z	translateNOPRINT_TRANS_TABLE)Zrule_strr)   r   stripNonPrintableCharactersrL   M  s    122r   c                 s   V P                  R 4      pVR8w  d$   V RV pW^,           R pV'       d	   V'       g   R# MT pRp\        V4      '       g   R# V'       d    \        V4      pT^ 8  g   T^8  d   R# R#   \         d     R# i ; i)rD   NFTr   )rF   rC   r   r
   rG   rH   r   checkIP6nMaskrM   Q  s    GGCLE{&5z!)+4   D>>	D	A q5AG  		s   A9 9BBc                 s     \        V 4      pV^ 8  g   V^8  d   R#  R#   \         d9     \        P                  ! T 4        R#   \        P                   d      R# i ; ii ; i)r    FT)r   r
   r   Zgetprotobynamer   )Zprotocolr   r   r   checkProtocolrN   h  sm    
M q5AG    	!!(+  || 			s&     A#AAA#AA#c                 s    V '       d>   V P                  4       '       d   \        V 4      R 8  d   R#  R# V R8X  d   R# V R8w  d   R# R# )i  FZNoneTZpmtu)r   r   )Ztcp_mss_clamp_valuer)   r   checkTcpMssClamprO   x  sJ    &&((&'#- . 	 !F* F*r   c                s^    V '       d   \        V 4      ^8  d   R# R F  pW9   g   K   R# 	  R# )zCheck interface string

@param interface string
@return True if interface is valid (maximum 16 chars and does not contain ' ', '/', '!', ':', '*'), else False
FT) rD   Z!Z*r&   )Zifacechr   r   checkInterfacerR     s+     CJO"; # r   c                     \        V \        4      '       g    \        V ^ 4      p V ^ 8  d
   V R8:  d   R# R#   \         d     R# i ; i)r    Fr   Tr   r   r
   Zvalr)   r   checkUINT16rV     sH    c3	c1+C axC5L  		   6 AAc                 rS   )r    Fl    TrT   rU   r)   r   checkUINT32rX     sI    c3	c1+C axC:%  		rW   c                 s,   \         P                  P                  \        4      '       g   R#  \	        \        R4      ;_uu_ 4       p V P                  4       pRRR4       \         P                  P                  RX,          4      '       g   R#  \	        RT,          R4      ;_uu_ 4       p T P                  4       pRRR4       RX9   d   R# R#   + '       g   i     L~; i  \         d     R# i ; i  + '       g   i     L@; i  \         d     R# i ; i)zmCheck if firewalld is active

@return True if there is a firewalld pid file and the pid is used by firewalld
FrNz/proc/%sz/proc/%s/cmdlineZ	firewalldT)ospathexistsr   openZreadline	Exception)ZfdpidZcmdline      r   firewalld_is_activera     s     77>>+,,#S))R++-C *
 77>>*s*++$s*C00BkkmG 1
 g# *)  10 s_   C CC D (C19D C	C C C.-C.1D	<D D DDc                  s*    \         P                  P                  \        4      '       g   \         P                  ! \        R 4       \
        P                  ! RR\        RR7      #   \         d$   p \        P                  ! RT ,          4       h Rp ? ii ; i)i  Zwtztemp.F)ZmodeZprefixZdirZdeletez#Failed to create temporary file: %sN)
rZ   r[   r\   r   ZmkdirtempfileZNamedTemporaryFiler^   r   r   )Zmsgs    r   tempFilerc     sn    	ww~~/00HH&.**g+<U
 	
  		7#=>s   (A$ 8A$ $B/BBc                 s     \        V R 4      ;_uu_ 4       pVP                  4       uuRRR4       #   + '       g   i     R# ; i  \         d*   p\        P                  ! RT : RT: 24        Rp?R# Rp?ii ; i)rY   NzFailed to read file "": )r]   	readlinesr^   r   r   )filenamefe   &  r   readfilerj     s^    B(C  A;;= !      B		Ha@AABs0   A 1
A A	A A A9A44A9c                 s     \        V R 4      ;_uu_ 4       pVP                  V4       RRR4       R#   + '       g   i     R# ; i  \         d*   p\        P                  ! RT : RT: 24        Rp?R# Rp?ii ; i)ZwNzFailed to write to file "rd   FT)r]   Zwriter^   r   r   )rf   Zlinerg   rh   r"   r   	writefilerk     s^    (C  AGGDM !
  ! 
   		!DEs0   A 2A A	A A A:A55A:c                 sR    V R 8X  d   \        RR4      # V R8X  d   \        RR4      # R# )ipv4z/proc/sys/net/ipv4/ip_forwardz1
ipv6z&/proc/sys/net/ipv6/conf/all/forwardingF)rk   )ipvr)   r   enable_ip_forwardingro     s/    
f}8%@@	A5IIr   c                 sF    V P                  R R4      P                  RR4      # )_r   znf-conntrack-r   )Zreplace)Zmoduler)   r   get_nf_conntrack_short_namerq     s     >>#s#++OR@@r   c                 s   \        V 4      pVR8X  g1   VR8X  g*   Ve&   \        V4      ^8X  d   V^ ,          V^,          8  d   VR8X  d    \        P                  ! RV ,          4       R# VR8X  d    \        P                  ! RV ,          4       R# Vf    \        P                  ! RV ,          4       R# \        V4      ^8X  d3   V^ ,          V^,          8  d   \        P                  ! RV ,          4       R# R# )	   z'%s': port > 65535z'%s': port is invalidz'%s': port is ambiguousz'%s': range start >= endFTr   r   )r   r   r   Zdebug2)r   r   r   r   
check_portrs     s    $F"R<>K1fQi!7R<JJ+d23  r\JJ.56
 	 ^JJ0478  [A&)vay"8JJ1D89r   c                 N    V R 8X  d   \        V4      # V R8X  d   \        V4      # R# rl   rm   F)rI   rM   rn   Zsource   &&r   check_addressrx     s)    
f}F##	V$$r   c                 rt   ru   )rA   rC   rv   rw   r   check_single_addressry     s(    
f}v	r   c                 s    \        V 4      ^8X  dC   R F  pW,          R8w  g   K   R# 	  R F!  pW,          \        P                  9  g   K    R# 	  R# R# )   :FT)rr      i   i   i   )r    r!   i      i   i   i	   i
   rz   i   i   i   )r   stringZ	hexdigits)Zmacr   r   r   	check_macr   "  sK    
3x6"Av} # ;AvV--- ; r   c                 sN    . pV  F  pW!9  g   K  VP                  V4       K  	  V# rJ   )r   )Z_listZoutputr(   ri   r   uniqifyr   /  s)    F?MM!  Mr   c                s     \         P                  ! RV ,          4      p\        VP                  4       ^ ,          P	                  4       4      p VP                  4        V #   \         d     R# i ; i)zGet parent for pidzps -o ppid -h -p %d 2>/dev/nullN)rZ   Zpopenr   re   r	   Zcloser^   )r_   rg   r   r   ppid_of_pidr   8  s]    HH6<=!++-"((*+		 J  s   AA A.-A.c                 s    ^ RI Hp  ^ RIHp \	        \        \        VP                  4       4      4      p^V\        V 4      ,           \        R4      ,           ,
          # )z
iptables limits length of chain to (currently) 28 chars.
The longest chain we create is POST_<policy>_allow,
which leaves 28 - 11 = 17 chars for <policy>.
)POLICY_CHAIN_PREFIX	SHORTCUTSZ_allow)Zfirewall.core.ipXtablesr   firewall.core.baser   maxr5   r   values)r   r   longest_shortcutr`   r   max_policy_name_lenr   C  sE     <,3sI$4$4$678!C(;$<<s8}LMMr   c                 s    ^ RI Hp  \        \        \        V P                  4       4      4      p^V\	        R4      ,           ,
          # )z
Netfilter limits length of chain to (currently) 28 chars.
The longest chain we create is POST_<zone>_allow,
which leaves 28 - 11 = 17 chars for <zone>.
r   Z__allow)r   r   r   r5   r   r   )r   r   s     r   max_zone_name_lenr   P  s7     -3sI$4$4$678!C	N233r   c                 s    \        V 4      ^8  g%   \        V 4      \        P                  ! R4      8  d   R# V  F;  pV\        P                  9  g   K  V\        P
                  9  g   K1  VR9  g   K:   R# 	  R# )r!   ZSC_LOGIN_NAME_MAXFT)rE   r   rp   Z$)r   rZ   Zsysconfr~   Zascii_lettersZdigits)ZuserZcr   r   	checkUserr   \  sZ    
4y1}D	BJJ/B$CCV)))&--  r   c                 s    \        V \        4      '       d    \        V 4      p V ^ 8  d
   V R8:  d   R# R #   \         d     R # i ; i)FTi)r   Zstrr   r
   )Zuidr)   r   checkUidr   i  sG    #s	c(C axC9$	  		s   5 AAc                 s    \        V 4      ^8  g   \        V 4      R8  d   R# R F  pW9   g   K   R# 	  V ^ ,          R8w  d   R# R# )r!   i   FrD   T)Z|Z
Z r&   )ZcommandrQ   r   r   checkCommandr   t  sB    
7|a3w<$.=   qzSr   c                 s   V P                  R 4      p\        V4      R9  d   R# V^ ,          R8w  d   V^ ,          R	R R8w  d   R# V^,          R	R R8w  d   R# V^,          R	R R8w  d   R# \        V^,          4      ^8  d   R# R# )
r{   FZrootNZ_uZ_rZ_tT)r}   r|   r   )r   r   )Zcontextr   r   r   checkContextr     s    ]]3F
6{& ayFvay~5ay~ay~
6!9~r   c                 s2    R P                  R V  4       4      # )rP   c              3   sN   "   T F  p\         P                  ! V4      x  K  	  R # 5irJ   )shlexZquote)Z.0ar   r   Z	<genexpr>ZjoinArgs.<locals>.<genexpr>  s     1DqEKKNNDs   #%)r   )Zargsr)   r   joinArgsr     s    881D111r   c                 s.    \         P                  ! V 4      # rJ   )r   r   )Z_stringr)   r   	splitArgsr     s    ;;wr   c                 sz    ^ RI pVP                  V 4      p VP                  ! V/ VB  R#   \         d     R# i ; i)r    NFT)inspectZ	signatureZbindZ	TypeError)Zfcnr   Zkwr   Zsigs   &*,  r   wrong_args_for_callabler     sF    
 

C
 C!r   s   + ::)r{   )4r   rZ   Zos.pathr   r~   rb   Zfirewall.core.loggerr   Zfirewall.configr   r   r   rK   r   r   r    r#   r:   r<   r=   rA   rB   rC   rI   rL   rM   rN   rO   rR   rV   rX   ra   rc   rj   rk   ro   rq   rs   rx   ry   r   r   r   r   r   r   r   r   r   r   r   r   )r   s   0r   <module>r      s(    	     $ @ 1c]	 Fq3w AtG	 08v<&4,/^1*h23. 	(

<
A(

N	4
&2 S	s   C
C
