bSr@sdZddlmZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlmZddlmZdZdZddZd d Zd d Zd dZddZdddZddZddZddZddZdddZdd Zd!d"Z d#d$Z!dd%d&Z"d'd(Z#e j$dd)d*Z%d+d,Z&d-d.Z'd/d0Z(d1d2Z)ej*d3d4Z+ej*d5d6Z,d7d8Z-d9d:Z.d;d<Z/d=d>Z0d?d@Z1dAdBZ2dCdDZ3dEdFdGZ4dEddHdIZ5dJdKZ6ddLdMZ7dNdOZ8dPdQZ9dRdSZ:dTdUZ;dVdWZ<dS)Xz"util.py: utility functions for ufw)print_functionN)reduce)mkstempFcCsd}ytj|Wntk r.YnXytj|dd}Wntk r]YnXy/tj|d|dkrd}nd}Wntk rYnX|S)z8Get the protocol for a specified port from /etc/servicestcpudpany)socketZ getservbyname Exception)portprotor */usr/lib/python3/dist-packages/ufw/util.pyget_services_proto&s$       rcCsyd}d}|jd}t|dkr@|d}d}n/t|dkri|d}|d}nt||fS)zParse port or port and protocolr/rr)splitlen ValueError)Zp_strr r tmpr r rparse_port_proto@s    rc CstjstddSt|dks<tjd| r@dS|jd}ytjtj|dWnt k rdSYnXt|dkrdSt|dkrt |dd sdSnd S) zVerifies if valid IPv6 addressz"python does not have IPv6 support.F+z^[a-fA-F0-9:\./]+$rrrrT) r Zhas_ipv6warnrrematchr inet_ptonAF_INET6r _valid_cidr_netmask)addrnetr r rvalid_address6Ps   %  r!c Cst|dks%tjd| r)dS|jd}y2tjtj|dt|ddsidSWntk rdSYnXt|dkrdSt|dkrt |ddsdSndS) zVerifies if valid IPv4 addressz ^[0-9\./]+$FrrrrT) rrrrr rAF_INET_valid_dotted_quadsr valid_netmask)rr r r rvalid_address4js%  r&cCst||pt||S)z(Verifies if valid cidr or dotted netmask)rr$)nmv6r r rr%sr%rcCsX|dkrt|S|dkr,t|S|dkrNt|pMt|StdS)zValidate IP addresses64rN)r!r&r)rversionr r r valid_addresss     r,c Csg}d}d}tj}|r3d}tj}nd|kr|jd}|rn|ddkrn|d=q| r|ddks|ddkr|d=qn |j|| rt|d krt|d|ryt|d||dxs 4zword_wrap.. )rr)textrtr r r word_wraprsrxcCs t|dS)zWord wrap to a specific widthK)rx)rwr r r wrap_textsrzcs,dd|jdfdddS)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'] cSs |jrt|S|jS)N)isdigitintlower)tr r rruszhuman_sort..keycs#fddtjd|DS)Ncsg|]}|qSr r ).0c)normr r s z0human_sort....z([0-9]+))rr)k)rr rrusN)sort)lstr )rr human_sorts rcCsyt|}Wntk r0tdYnXtjjdt|d}tjj|sttd|ny1t |j dj ddj d}Wntk rYnXt|S)zdFinds parent process id for pid based on /proc//stat. See 'man 5 proc' for details. zpid must be an integerz/procstatzCouldn't find '%s'r)r) r|r rrIpathjoinrYisfilerkr6 readlinesr)Zmypidpidnameppidr r rget_ppids 1 rcCs^yt|}Wn_tk r>td}t|dSYn4tk rqtdt|}t|YnX|dks|dkrdStjj dt|d}tjj |std|}t|ny$t |j dj d}Wn.tk r1td |}t|YnXtd ||d krPd St|Sd S)z1Determine if current process is running under sshz%Couldn't find pid (is /proc mounted?)Fz!Couldn't find parent pid for '%s'rz/procrzCouldn't find '%s'rz"Could not find executable for '%s'zunder_ssh: exe is '%s'z(sshd)TN)rrk_rr rYrrIrrrr6rrr1 under_ssh)rrwarn_msgZerr_msgrexer r rrs0    $  rcCsTd}|rd}ntjd| sLt|dksLt||krPdSdS)zVerifies cidr netmasks z^[0-9]+$rFT)rrr|)r'r(numr r rrs  7rcCs|r dStjd|rtjd|}t|dkrDdSxD|D]5}| s|t|dks|t|dkrKdSqKWndSdS)z.Verifies dotted quad ip addresses and netmasksFz^[0-9]+\.[0-9\.]+$z\.rT)rrrrr|)r'r(Zquadsqr r rr$s + r$c Cs1d}|rtnt||s-tnd}y)ttjdtj|d}Wn7tk rttjdtj|d}YnXd}xKt dD]=}||?d@dkrd}q|rd}Pq|d7}qW|dkr|dkrt d|}nt ||s-tn|S) z@Convert netmask to cidr. IPv6 dotted netmasks are not supported.rrz>LFrrTr?) rr$longstructunpackr inet_aton NameErrorr|rangerYr)r'r(cidrZmbitsbitsZ found_onenr r rr.s.  ) *  r.c Csd}|rtnt||s-tnytd}Wntk rWd}YnXx;tdD]-}|t|kre|dd|>O}qeqeWtjtj d|}t ||stn|S)zL) rrrrrr|r inet_ntoarpackr$)rr(r'rrr r r_cidr_to_dotted_netmask's      rc Cssd|krtd|S|jd}t|dksOt|dd rXtn|d}|d}|}t|drt|d}nyNttj dt j |d}ttj dt j |d}Wn\t k r?t tj dt j |d}t tj dt j |d}YnX||@}t jtjd|}d||fS) z8Convert an IPv4 address and netmask to a network addressrz8_address4_to_network: skipping address without a netmaskrrFrz>Lz%s/%s)r1rrr$rrrrrrr rrr|rr) rrhostZorig_nmr' host_bitsnm_bitsZ network_bitsr3r r rr0Ds(  &   %) %* r0cCsVdd}d|kr&td|S|jd}t|dks[t|dd rdtn|d}|d}tjd tjtj |}yt d}Wnt k rd}YnXxft d D]X}|||d }x<t d D].} |dt || @d | |d >O}qWqWyt d} Wnt k rWd} YnXx;t d D]-}|t |kre| dd|>O} qeqeW|| @} g} xIt d D];}| jt || d |d |d d dqWtjtj tjd | d| d| d| d| d| d| d| d } d| |fS)z8Convert an IPv6 address and netmask to a network addresscs0djfddt|dddDS)zDecimal to binaryrcs$g|]}t|?d@qS)r)rY)ry)rr rrjs z9_address6_to_network..dec2bin..rr?r?)rr)rcountr )rrdec2binhsz%_address6_to_network..dec2binrz8_address6_to_network: skipping address without a netmaskrrTrz>8HrUrr=rz%s/%srU)r1rrr%rrrr rrrrrr|r-r/r)rrr orig_hostnetmaskZunpackedrirjrr rr3r r r_address6_to_networkfsF   &      0   9 rc Cs|jd}t|dks5t|d| r>tn|d}|d}|dksj|dkrndS|}d|kr|jd}t|dkst|d| rtn|d}n|dks|dkrdS|rt| st| r6tq6n#t| s-t| r6tnt||r^| r^t||}n|rtd||fjdd}td||fjdd}nFt d||fjdd}t d||fjdd}||kS) z&Determine if address x is in network yrrrrz0.0.0.0z::Tz%s/%s) rrr%rr!r&rrrr0) Z tested_addZ tested_netr(rrrZaddressZ orig_networkr3r r r in_networks@&    &     rz/sbin/iptablescCsft|dg\}}|dkr=ttjd|ntjd|}tjdd|dS)zReturn iptables versionz-VrzError running '%s'z\sz^vrr)r]r@rArBrrsub)rrMrLrr r rget_iptables_versions  rcCsfdd}|r9tjdkr9ttjdng}d}|jdr]d}nt|d|g\}}|dkrttj|n|||d d d d d d dgr|jdn|||d d d d d d dddddg r|jdnt|d|gt|d|g\}}|dkrbttj|n|S)z[Return capabilities set for netfilter to support new features. Callers must be root.cSs9|d|g}t||\}}|dkr5dSdS)Nz-ArTF)r])rchainZruleargsrMrLr r rtest_caps  z,get_netfilter_capabilities..test_caprz Must be rootz ufw-caps-testZ ip6tableszufw6-caps-testz-Nz-mZ conntrackz --ctstateZNEWZrecentz--setz recent-setz--updatez --secondsZ30z --hitcountr)z recent-updatez-Fz-X) rIgetuidr@rAZEPERMendswithr]rBr-)rZ do_checksrZcapsrrMrLr r rget_netfilter_capabilitiess.     rcCs{t|}t}x_|jD]Q}|jd rN|jd rNq"n|j}|d}|djdd}t}dj|djddd|d<|d|d <|d jd d|d <|d d kr|d |d.rrr80z%s/%srzNo such deviceiZ256sN)rIrexistsr@rArBr6rrrrrr}r|rkENODEVr r#Z SOCK_DGRAMrfcntlZioctlrFrrr r4)ifnamer(rprocrsrhr )rrget_ip_from_if.s* 2- 0 rc sd}d}t|r'd}d}n!t|sHttjdntjj|ssttj d|nd}|rcxjt |j D]}|j dj }d jfd d td td d D}djdkr(d|tdjdf}n||ksRd|krt||dr|}PqqWnxt |j D]r}d |krqvn|j d d j }yt|d}Wntk rwvYnX||krv|}PqvqvW|S)zGet interface for IP addressFz /proc/net/devTz/proc/net/if_inet6zNo such devicez'%s' does not existrrrcs(g|]}d||dqS)rrr )rr)rr rrcs z"get_if_from_ip..rrrrz%s/%srr)r!r&rkrArrIrrr@rBr6rrstriprrrr}r|rr)rr(rZmatchedrsrZtmp_addrZipr )rrget_if_from_ipNsD    2&     rc Csetjd}|jtjd}t}x-|D]%}|j|sSq8ntjjd|d}tj |tj tj Bsq8nd}y%tj tjjd|d}Wnt k rYnXytj|}Wn w8YnXxl|D]d}y&tjtjj||d}Wnt k r8wYnXd|tjj|f||.rrcs*g|] }||djqS)r)r})rr)rr rrs rTcs$g|]}|d|qS)rr )rr)rr rrs r.Fr)rrrr4r-rYr|)rZ convertedrr )rrrconvert_proc_addresss: +, rc CsJt}ddg}|r.|ddg7}nxT|D]L}yt|||sn                 7        '  .  " : / / & / % /