o MHdX@sjdZddlZddlZddlZddlmZdZdZdZeZ dZ dZ d Z d Z Gd d d eZGd ddZdS)z!common.py: common classes for ufwN)debugufwz/lib/ufwz/usr/share/ufwz/etcz/usrz /usr/sbinTc@s eZdZdZddZddZdS)UFWErrorz$This class represents ufw exceptionscCs ||_dSN)value)selfrr,/usr/lib/python3/dist-packages/ufw/common.py__init__# zUFWError.__init__cCs t|jSr)reprrrrrr __str__&r zUFWError.__str__N)__name__ __module__ __qualname____doc__r rrrrr r!s rc@seZdZdZ   d9ddZd d Zd d Zd dZddZddZ d:ddZ ddZ ddZ ddZ ddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8S);UFWRulez$This class represents firewall rulesany 0.0.0.0/0inFc Csd|_d|_d|_d|_d|_d|_d|_d|_d|_d|_ d|_ d|_ d|_ d|_ d|_d|_d|_||_d|_z,||||||||d|||||||| WdStymw)NFrrsrc)removeupdatedv6dstrdportsportprotocolmultidappsappactionpositionlogtype interface_in interface_out directionforwardcomment set_action set_protocolset_portset_srcset_dst set_direction set_commentr) rr#rrrrrr(r)r*rrr r ,s>        zUFWRule.__init__cCs|Sr) format_ruler rrr rOszUFWRule.__str__cCs>d|}t|j}||D] }|d||j|f7}q|S)zPrint rule to stdoutz'%s'z, %s=%s)list__dict__sort)rreskeyskrrr _get_attribRs  zUFWRule._get_attribcCst|j|j}|j|_|j|_|j|_|j|_|j|_|j|_|j |_ |j |_ |j |_ |j |_ |j |_ |j|_|j|_|j|_|j|_|j|_|j|_|S)zReturn a duplicate of a rule)rr#rrrrrrrrr r!r"r$r%r&r'r(r)r*)rrulerrr dup_rule[s&zUFWRule.dup_rulecCsrd}|jdkr|d|j7}|jdkr|d|j7}|jdkr$|d7}nD|d|j7}|jrh|d7}|jdkrO|jdkrO|d|j7}|d7}|d |j7}n|jdkr\|d|j7}n |jdkrh|d |j7}|jd kry|jd kry|d |j7}|js|jdkr|d |j7}|jd kr|jd kr|d|j7}|js|jdkr|d|j7}d}|jdkrd|j}|j dkr|d|7}n'|j dkr|d|7}|jdkr|d7}n|j dkr|d|7}n|d|7}|j dks|j dkr5d}t d}|j dkr |d|d|j 7}|j dkr|j dkr|d7}|j dkr+|d|d|j 7}|d 7}|d|7}|S)!zFormat rule for later parsingrz -i %sz -o %srz -p allz -p z -m multiportz --dports z --sports r::/0z -d z --dport z -s z --sport _allowz -j ACCEPT%srejectz -j REJECT%stcpz --reject-with tcp-resetlimitz -j LIMIT%sz -j DROP%sz-m comment --comment ' dapp_z%20,sapp_')r&r'rr rrrrr%r#r!r"recompilesubstrip)rrule_strlstrr* pat_spacerrr r2rsf                  zUFWRule.format_rulecCsj|d}|ddks|ddks|ddkr|d|_nd|_d}t|dkr.|d}||d S) zSets action of the ruler=rr>r?rAdenyrN)lowersplitr#len set_logtype)rr#tmpr%rrr r+s$  zUFWRule.set_actionrc Cstd|}|dkr n|dkr|jrn|dkr|jrntd|s'td|r+t||d|dd kr;t||d}t|d krId |_ d }|D]y}td |rd |_ |d}|D]}t |d ksmt |dkrqt|q_t |dt |d krt|n4td|rt |d kst |dkrt|ntd|rzt |}Wnt yt|wt||r|dt|7}qMt|}qM|}|dkrt||_dSt||_dS)z:Sets port and location (destination or source) of the rulez Bad port '%s'rrrz^[,:]z[,:]$rD:rOTrz ^\d+:\d+$irz^\d+$z ^\w[\w\-]+N)r=r!r"rGmatchrcountrQrRr intsocket getservbyname Exceptionstrrr) rportlocerr_msgportsrTpranqrrr r-sX         zUFWRule.set_portcCs0|tjjdgvr||_dStd|}t|)zSets protocol of the rulerzUnsupported protocol '%s'N)rutilsupported_protocolsrr=r)rrr`rrr r,s  zUFWRule.set_protocolcCs|jr)|jr|jdks|jdkrd|_|jr%|jdks |jdkr'd|_dSdSdS|jr9|jdks6|jdkr9d|_|jrK|jdksF|jdkrMd|_dSdSdS)zAdjusts src and dst based on v6rrr<N)rrrr rrr _fix_anywheres  zUFWRule._fix_anywherecCs||_|dS)zXSets whether this is ipv6 rule, and adjusts src and dst accordingly. N)rrg)rrrrr set_v6 s zUFWRule.set_v6cC@|}|dkrtj|dstd}t|||_|dS)zSets source address of rulerzBad source addressN)rPrre valid_addressr=rrrgraddrrTr`rrr r.  zUFWRule.set_srccCri)z Sets destination address of rulerzBad destination addressN)rPrrerjr=rrrgrkrrr r/rmzUFWRule.set_dstcCs|dkr|dkrtd}t|dt|vrtd}t|dt|vr,td}t|t|dks8t|d kr@td }t|tt|d krPtd }t|tt|d kr`td}t|tdt|sptd}t||dkry||_dS||_dS)zSets an interface for ruleroutzBad interface type!z+Bad interface name: reserved character: '!'rUz/Bad interface name: can't use interface aliases.z..z)Bad interface name: can't use '.' or '..'rz+Bad interface name: interface name is emptyz+Bad interface name: interface name too longz^[a-zA-Z0-9_\-\.\+,=%@]+$zBad interface nameN)r=rr]rRrGrWr&r')rif_typenamer`rrr set_interface's0     zUFWRule.set_interfacecCs>t|dkrtdt|std|}t|t||_dS)zSets the position of the rulez-1z^[0-9]+z,Insert position '%s' is not a valid positionN)r]rGrWr=rrYr$)rnumr`rrr set_positionWs zUFWRule.set_positioncCsB|dks|dks|dkr||_dStd|}t|)zSets logtype of the rulelogzlog-allrzInvalid log type '%s'N)rPr%r=r)rr%r`rrr rSas  zUFWRule.set_logtypecCs.|dks|dkr ||_dStd|}t|)zSets direction of the rulerrnzUnsupported direction '%s'N)r(r=r)rr(r`rrr r0js  zUFWRule.set_directioncCstj|jS)zGet decoded comment of the rule)rre hex_decoder*r rrr get_commentrszUFWRule.get_commentcCs ||_dS)zSets comment of the ruleN)r*)rr*rrr r1vs zUFWRule.set_commentcCsd}|jr(ztj|j|j\|_}Wnty"td}t|w|r(||_|j rNztj|j |j\|_ }WntyHtd}t|w|rN||_|j rc|j d}tj |d ||_ |jrz|j d}tj |d ||_dSdS)z&Normalize src and dst to standard formFz"Could not normalize source addressz'Could not normalize destination addressrDN)rrrenormalize_addressrr\r=rrrrrQ human_sortjoinr)rchangedr`rarrr normalizezs@         zUFWRule.normalizecCs|r|std||f}|j|jkrt|dS|j|jkr%t|dS|j|jkr1t|dS|j|jkr=t|dS|j|jkrIt|dS|j|jkrUt|dS|j|jkrat|dS|j |j krmt|dS|j |j kryt|dS|j |j krt|dS|j |j krt|dS|j |j krt|dS|j|jkr|j|jkr|j|jkrtd}t|dS|j|jkr|j|jkr|j|jkrtd}t|dStd|j|j|j|j|j|jd}t|d S) zCheck if rules match Return codes: 0 match 1 no match -1 match all but action, log-type and/or comment -2 match all but comment zNo match '%s' '%s'rOzFound exact matchrz$Found exact match, excepting commentzZFound non-action/non-logtype/comment match (%(xa)s/%(ya)s/'%(xc)s' %(xl)s/%(yl)s/'%(yc)s'))xayaxlylxcyc) ValueErrorrrrrrrrr!r"r&r'r(r)r#r%r*r=)xydbg_msgrrr rWsr               z UFWRule.matchcCsdd}|r|s t||dkrdSd||j||jf}|jdkr-td|ddS|j|jkr;t|d dS|j|jkrN|jd krNtd |dS|jd krb||j|jsbtd |dS|jd kr|jd krs| |j rsn|j |j krd|j vrtd|dS|j |j krd|j vr|j|jkrt j |j |j |jstd|d|j |j fdSn|jd kr|j|jkrtd|d|j|jfdSz t j |j|j}Wntytd|d|jYdSw|j |kr d|j vr td|d|j |fdS|j |kr7d|j vr7|j|jkr7t j ||j |js7td|d||j fdS|j|jkrNtd|d|j |j fdStd||j||jfdS)aThis will match if x is more specific than y. Eg, for protocol if x is tcp and y is all or for address if y is a network and x is a subset of y (where x is either an address or network). Returns: 0 match 1 no match -1 fuzzy match This is a fuzzy destination match, so source ports or addresses are not considered, and (currently) only incoming. cSs~d|vsd|vr||krdSdS|dD]'}||krdSd|vr<|d\}}t|t|kr._match_portsrz(No fuzzy match '%s (v6=%s)' '%s (v6=%s)'rz (direction) z (not incoming)rOz (forward does not match)rz (protocol) z(dport) r/z(dst) z ('%s' not in network '%s')z (interface) z (%s != %s)z %s does not existz(v6) z'(fuzzy match) '%s (v6=%s)' '%s (v6=%s)'r)rrWrr(rr)rrr& _is_anywhererrre in_networkget_ip_from_ifIOError)rrrrif_iprrr fuzzy_dst_matchs        "       & zUFWRule.fuzzy_dst_matchcCs|dks|dkr dSdS)zCheck if address is anywherer<rTFr)rrlrrr rNszUFWRule._is_anywherecCsd}|jdks |jdkred|j|j|j|jf}|jdkr)d|j|j|j|jf}|jdkr:d|j|j|j|jf}|jdkrM|jdkrM|d|j7}|S|jdkrY|d|j7}|jdkre|d|j7}|S)aReturns a tuple to identify an app rule. Tuple is: dapp dst sapp src direction_iface|direction or dport dst sapp src direction_iface|direction or dapp dst sport src direction_iface|direction where direction_iface is of form 'in_eth0', 'out_eth0' or 'in_eth0 out_eth0' (ie, both interfaces used). If no interfaces are specified, then tuple ends with the direction instead. rz %s %s %s %sz %sz in_%sz out_%s) r!r"rrrrr&r'r()rtuplrrr get_app_tupleTs&     zUFWRule.get_app_tuplecCs|jdkr|jdks|jdkrtd|j}t||jtjjvr0|dkr0td|j}t||jtjjvrL|j dksA|j dkrNtd|j}t|dSdS)z Verify rulerrz3Improper rule syntax ('%s' specified with app rule)rz'Invalid IPv6 address with protocol '%s'zInvalid port with protocol '%s'N) rr"r!r=rrreipv4_only_protocolsportless_protocolsrr)r rule_iptyper`rrr verifyvs( zUFWRule.verifyN)rrrrrFr)r)rrrrr rr9r;r2r+r-r,rgrhr.r/rtrvrSr0ryr1r~rWrrrrrrrr r*s: # C 5   0  #Cn "r)rrGrZufw.utilrr programName state_dir share_dir trans_dir config_dir prefix_dir iptables_dir do_checksr\rrrrrr s