o Fa7j@s~dZddlZddlZddlZddlZddlZddlZddlZddlm Z m Z m Z m Z ddl mZmZddlZGdddZdS)z&backend.py: interface for ufw backendsN)errorwarndebug _findpath)UFWErrorUFWRulec@seZdZdZ  d=ddZddZddZd d Zd>d dZddZ ddZ ddZ ddZ ddZ ddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Zd7d8Zd9d:Zd;d<ZdS)? UFWBackendzInterface for backendsNcCsBd|_||_||_g|_g|_ttjj|}t j |dt j |dt j |dd|_ |dur6|j |ddddd d |_tjj|_|||tj|j d |_t j tjjd |_t j tjjd |_t j tjjd|_t j tjjd|_z tj|j|_Wntytd}t |wd|_!dS)Nz default/ufwz ufw/ufw.confzufw/applications.d)defaultsconfappsrdi,i)offlowmediumhighfullr iptablesziptables-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_msgr8-/usr/lib/python3/dist-packages/ufw/backend.py__init__ sL         zUFWBackend.__init__c Csj|jdurdSi|_i|jd<d|jdd<d|jdd<|jrtdkr|jsz tj|j}Wn#t yU}zd|}| rFt |t |WYd}~dSd}~wwd |vrfd |vrfd|jdd<nd|jdd<| rz tj|j}Wnt y}z t d|WYd}~nd}~wwd |vrd |vrd|jdd<dSd|jdd<dSdSdSdSdS) zgInitialize the capabilities database. This needs to be called before accessing the database.NlimitT4F6rz initcaps %sz recent-setz recent-update)r1r"rgetuidrrr,get_netfilter_capabilitiesrr/ is_enabledrruse_ipv6r)r2nf_capsemsgr8r8r9initcapsLs@   zUFWBackend.initcapscCs d|jvr|jddkrdSdS)z!Is firewall configured as enabledenabledyesTF)r r2r8r8r9r@xs zUFWBackend.is_enabledcCs,d|jvr|jddkrtjdrdSdS)z"Is firewall configured to use IPv6ipv6rGz/proc/sys/net/ipv6TF)r rrexistsrHr8r8r9rAs  zUFWBackend.use_ipv6inputFc Csd|d}d}|j|dkrd}n |j|dkrd}nd}|rr|dkrrd }td }tjd d g\}}|d krgeteuidrgetgidgetegidrisdirrrecompilelistdirsearchappendrlistvaluesabspathsysargv startswithgetcwdrstatST_MODEr/ ExceptionpwdgetpwuidrcKeyErrorstrS_IWOTHS_IWGRPst_giddirnameerrnoENOENTisfile)r2r7rbwarned_world_writewarned_group_write warned_ownerr(warn_msgpatprofilerstatinfomode click_user snap_useris_unpack_user last_pathrdr8r8r9r#s                 6zUFWBackend._do_checksc Csi|_|jd|jdfD]G}ztj|}Wnty(td|}t|wt d}|D]}| |rOt d| }|d d|j|d <q0|q gd }d D]+}d ||jvrntd |}t||jd |} | |vrtd | |d}t|q[dS)z#Get all settings from defaults filer r zCouldn't open '%s' for readingz ^\w+="?\w+"?="'r)rOdroprQ)rKoutputrSzdefault_%s_policyzMissing policy for '%s'z+Invalid policy '%(policy)s' for '%(chain)s')rZchainN)r rrr,open_file_readrwr0rrirjrlsplitstriplowerclose) r2rdorigr7rlinetmppoliciescr6r8r8r9r$s8       zUFWBackend._get_defaultsc Cs td|std}t|t|tjstd|}t|tj |}|d}d}t d|d}|dD]} | | rOtj ||d|d d }q8tj || q8|sftj ||d|d ztj |Wntyvw|d |j|<d S) zSets option in defaults filez^[\w_]+$zInvalid optionz'%s' is not writablerF^rr TrN)rimatchr0rraccessW_OKrr, open_filesrjrl write_to_file close_filesrwrrr ) r2fnoptvaluer7fnsfdfoundrrr8r8r9 set_default:s.      zUFWBackend.set_defaultcCs|jsI|dkr||jdddn7|dkr!||jdddn(|dkr0||jdddn|d kr?||jddd n td |}t|td |}|S) z+Sets default application policy of firewallrPr DEFAULT_APPLICATION_POLICYz"ACCEPT"rRz"DROP"rQz"REJECT"skipz"SKIP"zUnsupported policy '%s'z*Default application policy changed to '%s')rrrr0r)r2rZr7r[r8r8r9set_default_application_policy^s2      z)UFWBackend.set_default_application_policycCsNg}t|j}|j|vr|j|vrtj|j|j}tj|j|j}|D]}|}d|_ | ddtj |\}} | | | |d|j |_ |j|jkrud|_tj |\}} | | | |d|j|_||q)|D]0} |} d| _tj | \}} | | | |d| jdkr| |j|j| _|| qwq)nl|j|vrtj|j|jD]%} |} d| _tj | \}} | | | |d|j| _|| qn6|j|vrtj|j|jD]%} |} d| _ tj | \}} | | | |d|j | _ || qt|dkr%td} t| |S)z4Return a list of UFWRules based on the template rulerNanysrcdstrz&No rules found for application profile)rnr(keysdportsportrr& get_portsdup_ruledappset_portr,parse_port_proto set_protocolsapprmprotocollenr0r)r2templater profile_namesdportssportsirportprotojruler6r7r8r8r9get_app_rules_from_templateysn             !       z&UFWBackend.get_app_rules_from_templatec CsRg}g}d}d}d}|j|jD]e}|j|ks|j|krg|}||kr%q|} | d| jdkr:| | jd| jdkrF| | jd|| } | D]} | | j r\| | qM| | qM|}d}q|j rp| |q| |q|r||_||_|t d|7}z| d| dW||fStyt d} t| w||fS) zUpdate rule for profile in place. Returns result string and bool on whether or not the profile is used in the current ruleset. rNFrrrTzRules updated for profile '%s'z!Couldn't update application rules)rrrr get_app_tuplerrrr normalizev6rmr0 _write_rulesrwr) r2r updated_rulesupdated_rules6 last_tupler[updated_profilertuplr new_app_rulesnew_rr7r8r8r9update_app_rulesT          zUFWBackend.update_app_rulecCs||jvr|Sd}d}t|jD]}||kr"|}|d7}qd||f}t||dkr3|S|dkrAtd|}t|td|}t|)z2Find the application profile name for profile_namerNrrz'%d' matches for '%s'z>Found multiple matches for '%s'. Please use exact profile namez&Could not find a profile matching '%s')r(rnrrrr0r)r2 profile_namermatchesn debug_msgr7r8r8r9find_application_names,  z UFWBackend.find_application_namec Cs<|r |t|jkr t|s|t|jkrt|dkrtg}|r'|j}n|j}i}d}t|D]'\}}||kr<nd}|jdksH|jdkrY|}||vrU|d7}q2d||<q2g}|rr|j}|j|d|} | dn|j}|j|d|} | dd} |D]}t || dkr| S| d7} qdS)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. rrrNTF) rr ValueErrorr enumeraterrrrset_v6rr) r2positionrr app_rules tuple_offsetrrr match_rulecountr8r8r9find_other_positionsH    zUFWBackend.find_other_positioncCsd}td}d|jvs|jdt|jvr#d}|td7}||fS|j|jd}|dkr7|d7}||fS|d|jd7}||fS)z"Gets current log level of firewallrz Logging: loglevelunknownrzon (%s))r0r rnr!r)r2levelr[r8r8r9 get_loglevelOs  zUFWBackend.get_loglevelcCs|t|jdgvrtd|}t||}|dkr0d|jvs(|jddkr+d}n|jd}||jdd||||dkrGtdStd S) zSets log level of firewallonzInvalid log level '%s'rrrr LOGLEVELzLogging disabledzLogging enabled) rnr!rr0rr rrupdate_logging)r2rr7 new_levelr8r8r9 set_loglevel_s    zUFWBackend.set_loglevelcCs |j|jS)zReturn list of all rules)rrrHr8r8r9 get_rulesus zUFWBackend.get_rulescCsrg}|r|j}n|j}d}i}|D]%}d}|jdks|jdkr2|}||vr.td|qd||<|d7}q|S)z/Return number of ufw rules (not iptables rules)rrNSkipping found tuple '%s'Tr)rrrrrr)r2rrrrrrr8r8r9get_rules_countys   zUFWBackend.get_rules_countcCsx|}d}i}|D]/}d}|jdks|jdkr+|}||vr'td|q d||<|t|kr5|S|d7}q dS)z:Return rule specified by number seen via "status numbered"rrNrTN)rrrrrint)r2numrrrrrr8r8r9get_rule_by_numbers   zUFWBackend.get_rule_by_numbercCs>g}d}|D]}|d7}||}|dkr||q|S)zmSee if there is a matching rule in the existing ruleset. Note this does not group rules by tuples.rr)rfuzzy_dst_matchrm)r2rmatchedrrretr8r8r9 get_matchings   zUFWBackend.get_matchingcCtd)z*Set default policy for specified directionz/UFWBackend.set_default_policy: need to overrider)r2rZ directionr8r8r9set_default_policyzUFWBackend.set_default_policycCr)zGet status of running firewallz,UFWBackend.get_running_raw: need to overrider)r2 rules_typer8r8r9get_running_rawrzUFWBackend.get_running_rawcCr)zGet managed rulesz'UFWBackend.get_status: need to overrider)r2verbose show_countr8r8r9 get_statusrzUFWBackend.get_statuscCr)zUpdate firewall with rulez%UFWBackend.set_rule: need to overrider)r2r allow_reloadr8r8r9set_rulerzUFWBackend.set_rulecCr)zStart the firewallz+UFWBackend.start_firewall: need to overriderrHr8r8r9start_firewallrzUFWBackend.start_firewallcCr)zStop the firewallz*UFWBackend.stop_firewall: need to overriderrHr8r8r9 stop_firewallrzUFWBackend.stop_firewallcCr)z%Get a list if rules based on templatez6UFWBackend.get_app_rules_from_system: need to overrider)r2rrr8r8r9get_app_rules_from_systemrz$UFWBackend.get_app_rules_from_systemcCr)z#Update loglevel of running firewallz+UFWBackend.update_logging: need to overrider)r2rr8r8r9rrzUFWBackend.update_loggingcCr)zReset the firewallz"UFWBackend.reset: need to overriderrHr8r8r9resetrzUFWBackend.reset)NNN)rKF) __name__ __module__ __qualname____doc__r:rEr@rAr^r#r$rrrrrrrrrrrrrrrrrrrrrr8r8r8r9rs@ ,, &p$D>< r)r rrrxrirurqufw.utilrrrrr ufw.commonrrufw.applicationsrr8r8r8r9s