#fdkdZddlZddlZddlZddlZddlZddlZddlZddlm Z m Z m Z m Z ddl mZmZddlZGddZy)z&backend.py: interface for ufw backendsN)errorwarndebug _findpath)UFWErrorUFWRuleceZdZdZ d!dZdZdZdZd"dZdZ d Z d Z d Z d Z d ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ d Z!y)# UFWBackendzInterface for backendsNcJd|_||_||_g|_g|_t t jj|}tjj|dtjj|dtjj|dd|_ ||jj|ddddd d |_t jj|_|j!|j#|j%t j&j)|jd |_tjjt jj,d |_tjjt jj,d |_tjjt jj,d|_tjjt jj,d|_ t j6j9|j.|_d|_!y#t<$rt?d}tA|wxYw)Nz default/ufwz ufw/ufw.confzufw/applications.d)defaultsconfappsrdi,i)offlowmediumhighfullriptablesziptables-restore ip6tableszip6tables-restorez#Couldn't determine iptables version)"r namedryrunrulesrules6rufwcommon config_dirospathjoinfilesupdate loglevels do_checks _do_checks _get_defaults _read_rules applications get_profilesprofiles iptables_dirriptables_restorerip6tables_restoreutilget_iptables_versioniptables_versionOSError_rcaps)selfrr extra_filesrootdirdatadirperr_msgs -/usr/lib/python3/dist-packages/ufw/backend.py__init__zUFWBackend.__init__ s     cjj++W 5"$'',,q-"@ ggll1n= ggll1.BCF   " JJ  k *!"!$$'"%"% ( --   ((55djj6HI  SZZ%<%G7# # $s .J J"c>|jyi|_i|jd<d|jdd<d|jdd<|jrtjdk(r|js t j j|j}d |vrd |vrd|jdd<nd|jdd<|jrX t j j|j}d |vrd |vrd|jdd<yd|jdd<yyyyy#t$r5}d|z}|jr t|t|Yd}~yd}~wwxYw#t$r}td|zYd}~d}~wwxYw) zgInitialize the capabilities database. This needs to be called before accessing the database.NlimitT4F6rz initcaps %sz recent-setz recent-update)r4r%rgetuidrrr/get_netfilter_capabilitiesrr2 is_enabledrruse_ipv6r)r5nf_capsemsgs r;initcapszUFWBackend.initcapsLs 99   '#' '3"' '3 >>biikQ.t{{ ((==dmmLw&?g+E*. '"3'*/ '"3'}}.!hhAA$..QG 7*'/I.2DIIg&s+.3DIIg&s+%8C.> $q(??$#JS   "..1,--.s08)D:)E;: E8+E33E8; FFFcFd|jvr|jddk(ryy)z!Is firewall configured as enabledenabledyesTF)r r5s r;rCzUFWBackend.is_enabledxs%  % == #u ,cd|jvr2|jddk(r tjjdryy)z"Is firewall configured to use IPv6ipv6rKz/proc/sys/net/ipv6TF)r rr existsrLs r;rDzUFWBackend.use_ipv6s6 T]] " == E ) 77>>. /rMcd|zdz}d}|j|dk(rd}n|j|dk(rd}nd}|r|dk(rd }td }tjj d d g\}}|d k7r t |d|vrd}|j r^tjj d dg\}}|d k(rd|vrd}tjj d dg\}}|d k(rd|vrd}|sd}|S)z.Get default policy for specified primary chaindefault__policyacceptallowrejectdenyforwardFzproblem running sysctlsysctlznet.ipv4.ip_forwardr1Tz net.ipv6.conf.default.forwardingznet.ipv6.conf.all.forwardingdisabled)r r3rr/cmdrrD) r5primary check_forwardpolicyrstrrJr:rcouts r;_get_default_policyzUFWBackend._get_default_policysg% 1 == H ,D ]]6 "h .DD W 1G01G h0E%FGIRQww''cz}}HHLL(4V)WX S7scz"GHHLL(4R)ST S7scz"G! rMc |jstd}t|ytjtj k7rtd}t |tjtjk7rtd}t |tj}|dk7rtd}t |i}i}i}g}tjj|jds'td|jdz}t|ntjd }tj|jdD]P} |j| r|j!tjj#|jd| Rt%|jj'tjj)t*j,dgz|zD] } | j/d stj0d | } t3d | z| |jdk(r-tjj|jds| tj4| } | t4j6} d } d}d} t=j>| j@d| k(s%t=j>| j@d|k(rd}| j@dk7rD|sB| |vr>tdtE|| tE| j@dz}t|d|| <| t4jFzr"| |vrtd| z}t|d|| <| t4jHzr1| |vr-| jJdk7rtd| z}t|d|| <| d k(r| }tjjM| } | st9tNjPd|z|jD]]}|dk7s tjjS|j|r6td||j|dz}t |y#t8$rtd | z}t |t:$rwxYw#tB$rYwxYw)a8Perform basic security checks: is setuid or setgid (for non-Linux systems) checks that script is owned by root checks that every component in absolute path are owned by root warn if script is group writable warn if part of script path is group writable Doing this at the beginning causes a race condition with later operations that don't do these checks. However, if the user running this script is root, then need to be root to exploit the race condition (and you are hosed anyway...) zChecks disabledTz%ERROR: this script should not be SUIDz%ERROR: this script should not be SGIDrz&You need to be root to run this scriptrz'%s' does not existz^\./z Checking zCouldn't stat '%s'clickpkg snappypkgFz4uid is %(uid)s but '%(path)s' is owned by %(st_uid)s)uidr st_uidz%s is world writable!z%s is group writable!zCould not find parent for '%s'z&'%(f)s' file '%(name)s' does not exist)frN)*r%r3rrrAgeteuidrgetgidgetegidr isdirr"recompilelistdirsearchappendr!listvaluesabspathsysargv startswithgetcwdrstatST_MODEr2 ExceptionpwdgetpwuidrjKeyErrorstrS_IWOTHS_IWGRPst_giddirnameerrnoENOENTisfile)r5r:riwarned_world_writewarned_group_write warned_ownerr+warn_msgpatprofiler statinfomode click_user snap_useris_unpack_user last_pathrks r;r&zUFWBackend._do_checkss+~~)*G M 99;"**, &?@G7# # 99;"**, &?@G7# #iik !8@AG7# #  ww}}TZZ/0./4::f3EFH N**V$C::djj&89 Ozz'*OOBGGLLF1CW$MN O**,-''//#((1+.019 /D??3'"$))+t4kD()4::f--!ww}}TZZ-?@!wwt}H#DLL1D( ' !&||HOO4Q7:ELL9!< I)-??a'L0 ". /:=c(7;9>$**Q-#@DE"#TZZ];=w''  ([, 45>G"7++  s (R :A R8 ,R58 SSci|_|jd|jdfD]} tjj |}tjd}|D]x}|j|stjd|j}|djjd|j|dj<z|jgd }d D]^}d |z|jvrt d |z}t||jd |z} | |vsDt d | |dz}t|y#t $rt d|z}t|wxYw)z#Get all settings from defaults filer r zCouldn't open '%s' for readingz ^\w+="?\w+"?="'r)rUdroprW)inputoutputrYzdefault_%s_policyzMissing policy for '%s'z+Invalid policy '%(policy)s' for '%(chain)s')r`chainN)r r"rr/open_file_readr~r3rrprqrssplitstriplowerclose) r5rkorigr:rlinetmppoliciescr9s r;r'zUFWBackend._get_defaultssr **Z($**V*<= A (xx..q1**_-C P::d#((46C47FLLN4H4H4ODMM#a&,,.1 P JJL 01 (A"a( =5;<w'' 1Q78A I()A689w'' ( (<=Cw'' (s E#E8cLtjd|std}t|t j |tj std|z}t|tjj|}|d}d}tjd|zdz}|dD]_} |j| r,tjj||dz|zd zd }@tjj|| a|s)tjj||dz|zd z tjj||jj!d |j"|j<y #t$rwxYw) zSets option in defaults filez^[\w_]+$zInvalid optionz'%s' is not writablerF^rr TrN)rpmatchr3rraccessW_OKrr/ open_filesrqrs write_to_file close_filesr~rrr ) r5fnoptvaluer:fnsfdfoundrrs r; set_defaultzUFWBackend.set_default:saxx S)()G7# #yyRWW%."56G7# #hh!!"% Zjjc)*K 1Dzz$&&r39u+F F#c|js|dk(r!|j|jdddn|dk(r!|j|jdddne|dk(r!|j|jdddn?|d k(r!|j|jddd ntd |z}t |td |z}|S) z+Sets default application policy of firewallrVr DEFAULT_APPLICATION_POLICYz"ACCEPT"rXz"DROP"rWz"REJECT"skipz"SKIP"zUnsupported policy '%s'z*Default application policy changed to '%s')rrr"r3r)r5r`r:ras r;set_default_application_policyz)UFWBackend.set_default_application_policy^s{{   J!7(D(466!  J!7(D(248#  J!7(D(466!  J!7(D(2456&Aw''=>&I rMcNg}t|jj}|j|vr=|j|vr.t j j|j|j}t j j|j|j}|D]}|j}d|_ |jddt jj|\}} |j| |j|d|j|_ |j|jk(rpd|_t jj|\}} |j| |j|d|j|_|j| |D]} |j} d| _t jj| \}} | j| | j|d| j dk(r| j|j |j| _|j| n|j|vrt j j|j|jD]} |j} d| _t jj| \}} | j| | j|d|j| _|j| n|j|vrt j j|j|jD]} |j} d| _ t jj| \}} | j| | j|d|j| _ |j| t#|dkrt%d} t'| |S)z4Return a list of UFWRules based on the template rulerTanysrcdstrz&No rules found for application profile)rur+keysdportsportrr) get_portsdup_ruledappset_portr/parse_port_proto set_protocolsapprtprotocollenr3r)r5templater profile_namesdportssportsirportprotojruler9r:s r;get_app_rules_from_templatez&UFWBackend.get_app_rules_from_templateys9T]]//12 >>] *x~~/N%%// hnn0MNF%%// hnn0MNF +'') UE* # 9 9! < u  ' T5)#==>>X^^3 "CH$'HH$=$=a$@MT5$$U+LLu-'}}CHLL%# +"||~$& (+(A(A!(D u))%0 dE2==E1 --cll;$,MM  T* ++ +B^^} ,%%// hnn0MN #((* # 9 9! < u!!%( dE*$MM  T" #^^} ,%%// hnn0MN #((* # 9 9! < u!!%( dE*$MM  T" # u:>@AG7# # rMcg}g}d}d}d}|j|jzD];}|j|k(s|j|k(r|j }||k(r8|j } | j d| jdk7r| j| jd| jdk7r| j| jd|j| } | D]A} | j| jr|j| 1|j| C|}d} |jr|j|+|j|>|rF||_||_|td|zz } |jd|jd||fS||fS#t$rtd} t| wxYw) zUpdate rule for profile in place. Returns result string and bool on whether or not the profile is used in the current ruleset. rTFrrrTzRules updated for profile '%s'z!Couldn't update application rules)rrrr get_app_tuplerrrr normalizev6rtr3 _write_rulesr~r) r5r updated_rulesupdated_rules6 last_tupleraupdated_profilertuplr new_app_rulesnew_rr:s r;update_app_rulezUFWBackend.update_app_rules  dkk)" ,Avv AFFg$5(:% !zz|H))%0}}* ))(--?}}* ))(--?$($D$D*2%4M"/8) 88*11%8)007 8"&J&*O44"))!,!((+E" ,H &DJ(DK A677C CD (!!%(!!$' o&&o&&  (?@w'' (s "F// Gcl||jvr|Sd}d}t|jjD]+}|j|jk(s%|}|dz }-d||fz}t ||dk(r|S|dkDrt d|z}t |t d|z}t |)z2Find the application profile name for profile_namerTrrz'%d' matches for '%s'z>Found multiple matches for '%s'. Please use exact profile namez&Could not find a profile matching '%s')r+rurrrr3r)r5 profile_namermatchesn debug_msgr:s r;find_application_namez UFWBackend.find_application_names 4== ( dmm((*+ AwwyL..001   ,w .EE  i a<L q[XY%'G w@A%'GwrMc|r"|t|jkDr t|s"|t|jkDr t|dkr tg}|r |j}n |j}i}d}t |D]L\}}||k\rnBd}|j dk7s|j dk7s.|j}||vr|dz }Hd||<Ng}|rA|j}|j|dz |zj} | jdn@|j}|j|dz |zj} | jdd} |D]$}tj|| dk(r| cS| dz } &y)a.Return the absolute position in the other list of the rule with the user position of the given list. For example, find_other_position(4, True) will return the absolute position of the rule in the ipv4 list matching the user specified '4' rule in the ipv6 list. rrrTTF) rr ValueErrorr enumeraterrrrset_v6rr) r5positionrr app_rules tuple_offsetrrr match_rulecounts r;find_other_positionzUFWBackend.find_other_positions (S--, hTZZ0,  a<,  KKEJJE  e$ +DAqH}Dvv|qvv|(9$ A%L&*IdO + JJEX\L%@AJJLJ   e $KKEHqL<$?@IIKJ   d # A}}Q +q0 QJE  rMcJd}td}d|jvs2|jdt|jj vrd}|tdz }||fS|j|jd}|dk(r |dz }||fS|d|jdzz }||fS)z"Gets current log level of firewallrz Logging: loglevelunknownrzon (%s))r3r rur$r)r5levelras r; get_loglevelzUFWBackend.get_loglevelOs~ T]] * == $D1D1D1F,G GE AiL Dt} NN4==#<=Ez t} T]]:%>??t}rMc|t|jjdgzvrtd|z}t ||}|dk(r2d|j vs|j ddk(rd}n|j d}|j |jdd||j||dk(r tdStd S) zSets log level of firewallonzInvalid log level '%s'rrrr LOGLEVELzLogging disabledzLogging enabled) rur$rr3rr rr"update_logging)r5rr: new_levels r; set_loglevelzUFWBackend.set_loglevel_s T^^0023tf< <01U;G7# # D=.}}Z(E1!  MM*5  F+ZC I&  '( (&' 'rMcD|j|jzS)zReturn list of all rules)get_rules_ipv4get_rules_ipv6rLs r; get_ruleszUFWBackend.get_rulesus""$t':':'<<?&*IdO QJE  rMc|j}d}i}|D]a}d}|jdk7s|jdk7r(|j}||vrt d|zFd||<|t |k(r|cS|dz }cy)z:Return rule specified by number seen via "status numbered"rrTrTN)rrrrrint)r5numrrrrrs r;get_rule_by_numberzUFWBackend.get_rule_by_numbers   ADvv|qvv|(9$5>?&*IdOC  QJE rMcg}d}|jD]/}|dz }|j|}|dks|j|1|S)zmSee if there is a matching rule in the existing ruleset. Note this does not group rules by tuples.rr)rfuzzy_dst_matchrt)r5rmatchedrrrets r; get_matchingzUFWBackend.get_matchingsW! &A QJE&&q)CQwu%  & rMctd)z*Set default policy for specified directionz/UFWBackend.set_default_policy: need to overrider)r5r` directions r;set_default_policyzUFWBackend.set_default_policysHIIrMctd)zGet status of running firewallz,UFWBackend.get_running_raw: need to overrider)r5 rules_types r;get_running_rawzUFWBackend.get_running_rawsEFFrMctd)zGet managed rulesz'UFWBackend.get_status: need to overrider)r5verbose show_counts r; get_statuszUFWBackend.get_statuss@AArMctd)zUpdate firewall with rulez%UFWBackend.set_rule: need to overrider)r5r allow_reloads r;set_rulezUFWBackend.set_rules>??rMctd)zStart the firewallz+UFWBackend.start_firewall: need to overriderrLs r;start_firewallzUFWBackend.start_firewallDEErMctd)zStop the firewallz*UFWBackend.stop_firewall: need to overriderrLs r; stop_firewallzUFWBackend.stop_firewallsCDDrMctd)z%Get a list if rules based on templatez6UFWBackend.get_app_rules_from_system: need to overrider)r5rrs r;get_app_rules_from_systemz$UFWBackend.get_app_rules_from_systems"# #rMctd)z#Update loglevel of running firewallz+UFWBackend.update_logging: need to overrider)r5rs r;rzUFWBackend.update_loggingr"rMctd)zReset the firewallz"UFWBackend.reset: need to overriderrLs r;resetzUFWBackend.resets;<r2s7," 22(B =B =rM