3 YÉj'Kã#@sdddddddddd d d d d ddddddddddddddddddd d!d"g#Zd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d$lZd#d%l m Z d#d&l m Z m Z ejd'kZd(d)„ed#d*ƒDƒZd+d„Zd,d„ZdXd.d„Zd/d0„Zd1d2„Zd3d4„Zd5d„Zd6d„Zd7d8„Zd9d„Zd:d„Zd;d"„Zdd „Z d?d „Z!d@d „Z"dAd „Z#dBd„Z$dCd„Z%dDd„Z&dEdF„Z'dGd„Z(dHd„Z)dId„Z*dJd„Z+dKd„Z,dLd„Z-dMd!„Z.dNd„Z/dOd„Z0dPd„Z1dQd„Z2dRd„Z3dSd„Z4dTd„Z5dUd„Z6dVd„Z7dWd „Z8d$S)YÚPY2Ú getPortIDÚ getPortRangeÚportStrÚgetServiceNameÚcheckIPÚcheckIP6Ú checkIPnMaskÚ checkIP6nMaskÚ checkProtocolÚcheckInterfaceÚ checkUINT32Úfirewalld_is_activeÚtempFileÚreadfileÚ writefileÚenable_ip_forwardingÚ check_portÚ check_addressÚcheck_single_addressÚ check_macÚuniqifyÚ ppid_of_pidÚmax_zone_name_lenÚ checkUserÚcheckUidÚ checkCommandÚ checkContextÚjoinArgsÚ splitArgsÚb2uÚu2bÚ u2b_if_py2Úmax_policy_name_lenÚstripNonPrintableCharacterséN)Úlog)ÚFIREWALLD_TEMPDIRÚFIREWALLD_PIDFILEÚ3cCs"i|]}|dko|dksd|“qS)ééN©)Ú.0Úir+r+ú/usr/lib/python3.6/functions.pyú .sr/é cCstt|tƒr|}nT|r|jƒ}y t|ƒ}Wn:tk rbytj|ƒ}Wntjk r\dSXYnX|dkrpdS|S)zÎ Check 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 éiÿÿééÿÿÿÿéþÿÿÿ)Ú isinstanceÚintÚstripÚ ValueErrorÚsocketZ getservbynameÚerror)ÚportZ_idr+r+r.r7s   cCsÀt|tƒst|tƒr|St|tƒs*|jƒrDt|ƒ}|dkr@|fS|S|jdƒ}t|ƒdkrÀ|djƒrÀ|djƒrÀt|dƒ}t|dƒ}|dkrÀ|dkrÀ||krª||fS||krº||fS|fSg}xÎtt|ƒddƒD]º}tdj |d|…ƒƒ}dj ||d…ƒ}t|ƒdk�rnt|ƒ}|dk�r�|dk�r�||k�rF|j ||fƒn&||k�r`|j ||fƒn |j |fƒqÖ|dkrÖ|j |fƒ|t|ƒkrÖPqÖWt|ƒdk�r¦dSt|ƒdk�r¸dS|dS)aI 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. r$ú-r2r1Nr3r3) r5ÚtupleÚlistr6ÚisdigitrÚsplitÚlenÚrangeÚjoinÚappend)ZportsZid1ÚsplitsZid2Zmatchedr-Zport2r+r+r.rNsL $      ú:cCsX|dkr dSt|ƒ}t|tƒr*|dkr*dSt|ƒdkr>d|Sd|d||dfSdS)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 Úr$Nr1z%sz%s%s%s)rr5r6rA)r;Z delimiterÚ_ranger+r+r.rˆs cCst|ƒ}t|ƒ}t|ƒdkr‚t|ƒdkr@t|dƒt|dƒkSt|ƒdkrþt|dƒt|dƒkrþt|dƒt|dƒkrþdSn|t|ƒdkrþt|ƒdkrþt|dƒt|dƒkrþt|dƒt|dƒkrþt|dƒt|dƒkrþt|dƒt|dƒkrþdSdS)Nr1r$r2TF)rrAr)r;rBZ_portrHr+r+r.ÚportInPortRangešs   0  00rIcCsTt|ƒ}t|ƒdkr$|d|df}tt|ƒ}ttdd„|ƒdd„d�}g}xÎ|D]Æ}|d|dkr‚|d|dkr‚|j|ƒqR|d|dkrÎ|d|dkrÎ|d|dkrÎ|j|ƒ|d|df}qR|d|dkoü|d|dkoü|d|dkrR|j|ƒ|d|df}qRWttdd„|ƒƒ}|d|dk�rJ|df}|g|fS)zû Coalesce 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) r1r$cSs t|ƒdkr|d|dfS|S)Nr1r$)rA)Úxr+r+r.Ú¹sz#coalescePortRange..cSs|dS)Nr$r+)rJr+r+r.rK¹s)ÚkeycSs|d|dkr|dfS|S)Nr$r1r+)rJr+r+r.rKÌs)rrAÚmapÚsortedrDr>)Z new_rangeÚrangesZcoalesced_rangeÚ_rangesÚremoved_rangesrBr+r+r.ÚcoalescePortRange¬s*          rRcCsÊt|ƒ}t|ƒdkr$|d|df}tt|ƒ}ttdd„|ƒdd„d�}g}g}�xJ|D�]@}|d|dkrŠ|d|dkrŠ|j|ƒqX|d|dkrà|d|dkrà|d|dkrà|j|ƒ|j|dd|dfƒqX|d|dk�r<|d|dk�r<|d|dk�r<|j|ƒ|j|d|ddfƒqX|d|dkrX|d|dkrX|j|ƒ|j|d|ddfƒ|j|dd|dfƒqXWttdd„|ƒƒ}ttdd„|ƒƒ}||fS) zü break 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) r1r$cSs t|ƒdkr|d|dfS|S)Nr1r$)rA)rJr+r+r.rKßsz breakPortRange..cSs|dS)Nr$r+)rJr+r+r.rKßs)rLcSs|d|dkr|dfS|S)Nr$r1r+)rJr+r+r.rKøscSs|d|dkr|dfS|S)Nr$r1r+)rJr+r+r.rKùs)rrArMrNrDr>)Z remove_rangerOrPrQZ added_rangesrBr+r+r.ÚbreakPortRangeÒs2      $   rSc Cs0ytjt|ƒ|ƒ}Wntjk r*dSX|S)zÞ Check 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)r9Z getservbyportr6r:)r;ÚprotoÚnamer+r+r.rýs c Cs.ytjtj|ƒWntjk r(dSXdS)zl Check IPv4 address. @param ip address string @return True if address is valid, else False FT)r9Ú inet_ptonZAF_INETr:)Úipr+r+r.r s cCs |jdƒS)z� Normalize the IPv6 address This is mostly about converting URL-like IPv6 address to normal ones. e.g. [1234::4321] --> 1234:4321 z[])r7)rWr+r+r.Ú normalizeIP6srXc Cs2ytjtjt|ƒƒWntjk r,dSXdS)zl Check IPv6 address. @param ip address string @return True if address is valid, else False FT)r9rVZAF_INET6rXr:)rWr+r+r.r s c Cs°d|krN|d|jdƒ…}||jdƒdd…}t|ƒdksHt|ƒdkrVdSn|}d}t|ƒsbdS|r¬d|krvt|ƒSy t|ƒ}Wntk r–dSX|dks¨|dkr¬dSdS)Nú/r1FÚ.r$é T)ÚindexrArr6r8)rWÚaddrÚmaskr-r+r+r.r-s& cCs |jtƒS)N)Ú translateÚNOPRINT_TRANS_TABLE)Zrule_strr+r+r.r#Dsc Cs d|krN|d|jdƒ…}||jdƒdd…}t|ƒdksHt|ƒdkrVdSn|}d}t|ƒsbdS|rœy t|ƒ}Wntk r†dSX|dks˜|dkrœdSdS)NrYr1Fr$é€T)r\rArr6r8)rWr]r^r-r+r+r.r Gs" cCs`y t|ƒ}Wn:tk rFytj|ƒWntjk r@dSXYnX|dksX|dkr\dSdS)NFr$éÿT)r6r8r9Zgetprotobynamer:)Zprotocolr-r+r+r.r \s  cCs4| st|ƒdkrdSxdD]}||krdSqWdS) z¬ Check interface string @param interface string @return True if interface is valid (maximum 16 chars and does not contain ' ', '/', '!', ':', '*'), else False éFú rYú!Ú*T)rdrYrerf)rA)ZifaceÚchr+r+r.r ks  c Cs<yt|dƒ}Wntk r"dSX|dkr8|dkr8dSdS)Nr$FlÿÿT)r6r8)ÚvalrJr+r+r.r ~scCs¨tjjtƒsdSy"ttdƒ�}|jƒ}WdQRXWntk rFdSXtjjd|ƒs\dSy&td|dƒ�}|jƒ}WdQRXWntk r–dSXd|kr¤dSdS)zv Check 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'ÚopenÚreadlineÚ Exception)ÚfdÚpidZcmdliner+r+r.r ˆs"  cCsby*tjjtƒstjtdƒtjddtdd�Stk r\}ztj d|ƒ‚WYdd}~XnXdS)NièZwtztemp.F)ÚmodeÚprefixÚdirÚdeletez#Failed to create temporary file: %s) rjrkrlr&ÚmkdirÚtempfileZNamedTemporaryFileror%r:)Úmsgr+r+r.r¥s   cCsXyt|dƒ� }|jƒSQRXWn4tk rR}ztjd||fƒWYdd}~XnXdS)NrizFailed to read file "%s": %s)rmÚ readlinesror%r:)ÚfilenameÚfÚer+r+r.r±s  $cCs\y$t|dƒ�}|j|ƒWdQRXWn2tk rV}ztjd||fƒdSd}~XnXdS)NÚwz Failed to write to file "%s": %sFT)rmÚwriteror%r:)rzÚliner{r|r+r+r.r¹s cCs(|dkrtddƒS|dkr$tddƒSdS)NÚipv4z/proc/sys/net/ipv4/ip_forwardz1 Úipv6z&/proc/sys/net/ipv6/conf/all/forwardingF)r)Úipvr+r+r.rÂs   cCs|jddƒjddƒS)NÚ_r<z nf-conntrack-rG)Úreplace)Úmoduler+r+r.Úget_nf_conntrack_short_nameÉsr†cCs¶t|ƒ}|d ks<|d ks<|dks 65535z'%s': port is invalidz'%s': port is ambiguousz'%s': range start >= endFTr4r3r4r3)rrAr%Zdebug2)r;rHr+r+r.rÌscCs(|dkrt|ƒS|dkr t|ƒSdSdS)Nr€r�F)rr )r‚Úsourcer+r+r.rÛs cCs(|dkrt|ƒS|dkr t|ƒSdSdS)Nr€r�F)rr)r‚r‡r+r+r.rãs c CsRt|ƒdkrNxdD]}||dkrdSqWxdD]}||tjkr0dSq0WdSdS)Né ér2éé érFFr$r1ééééé é é ércTé)r2r‰rŠr‹rŒ) r$r1r�rŽr�r�r‘r’rˆr“r”rc)rAÚstringZ hexdigits)Zmacr-r+r+r.rës    cCs(g}x|D]}||kr |j|ƒq W|S)N)rD)Z_listÚoutputrJr+r+r.r÷s  c CsHy.tjd|ƒ}t|jƒdjƒƒ}|jƒWntk rBdSX|S)z Get parent for pid zps -o ppid -h -p %d 2>/dev/nullr$N)rjÚpopenr6ryr7Úclosero)rqr{r+r+r.rÿs cCsBddlm}ddlm}ttt|jƒƒƒ}d|t|ƒtdƒS)z¬ iptables limits length of chain to (currently) 28 chars. The longest chain we create is POST__allow, which leaves 28 - 11 = 17 chars for . r$)ÚPOLICY_CHAIN_PREFIX)Ú SHORTCUTSéZ_allow)Zfirewall.core.ipXtablesršÚfirewall.core.baser›ÚmaxrMrAÚvalues)ršr›Úlongest_shortcutr+r+r.r" s  cCs.ddlm}ttt|jƒƒƒ}d|tdƒS)z© Netfilter limits length of chain to (currently) 28 chars. The longest chain we create is FWDI__allow, which leaves 28 - 11 = 17 chars for . r$)r›rœZ__allow)r�r›ržrMrArŸ)r›r r+r+r.rs cCsTt|ƒdkst|ƒtjdƒkr"dSx,|D]$}|tjkr(|tjkr(|d kr(dSq(WdS) Nr1ÚSC_LOGIN_NAME_MAXFrZr<rƒú$T)rZr<rƒr¢)rArjÚsysconfr–Z ascii_lettersZdigits)ÚuserÚcr+r+r.rs   c CsDt|tƒr,y t|ƒ}Wntk r*dSX|dkr@|dkr@dSdS) NFr$r2r)r1Tliÿÿÿ)r5Ústrr6r8)Zuidr+r+r.r(s  cCsJt|ƒdkst|ƒdkrdSxd D]}||kr"dSq"W|ddkrFdSd S) Nr1iFú|Ú úr$rYT)r§r¨r©)rA)Zcommandrgr+r+r.r2s  cCs†|jdƒ}t|ƒdkrdS|ddkr>|ddd…dkr>dS|d dd…d krVdS|ddd…d krndSt|d ƒd kr‚dSd S)NrFrŽr‰Fr$Úrootr2Z_ur1Z_rZ_tr�T)rŽr‰r4r4r4)r@rA)ÚcontextrEr+r+r.r<s   cCs8dttƒkr djdd„|DƒƒSdjdd„|DƒƒSdS)NÚquoterdcss|]}tj|ƒVqdS)N)Úshlexr¬)r,Úar+r+r.ú PszjoinArgs..css|]}tj|ƒVqdS)N)Úpipesr¬)r,r®r+r+r.r¯Rs)rtr­rC)Úargsr+r+r.rNs cCs8tr*t|tƒr*t|ƒ}tj|ƒ}tt|ƒStj|ƒSdS)N)rr5Úunicoder r­r@rMr)Ú_stringrEr+r+r.rTs   cCst|tƒr|jddƒS|S)z bytes to unicode zUTF-8r„)r5ÚbytesÚdecode)r³r+r+r.r]s  cCst|tƒs|jddƒS|S)z unicode to bytes zUTF-8r„)r5r´Úencode)r³r+r+r.r cs  cCstrt|tƒr|jddƒS|S)z" unicode to bytes only if Python 2zUTF-8r„)rr5r²r¶)r³r+r+r.r!is )rF)9Ú__all__r9rjZos.pathr­r°r–ÚsysrwZfirewall.core.loggerr%Zfirewall.configr&r'ÚversionrrBr`rrrrIrRrSrrrXrrr#r r r r r rrrrr†rrrrrrr"rrrrrrrrr r!r+r+r+r.Úsz   : &+