コード例 #1
0
ファイル: access.py プロジェクト: maximerobin/Ufwi
 def getConfigs(self):
     if self.__disabled:
         return
     try:
         data = self.mainwindow.init_call('access', 'getConfig')
     except RpcdError:
         self.__disable(tr("Could not get Access to services configuration."))
         return
     if data is None:
         self.access_cfg = AccessConf.defaultConf()
     else:
         self.access_cfg = AccessConf.deserialize(data)
コード例 #2
0
ファイル: access.py プロジェクト: maximerobin/Ufwi
    def read_config(self, responsible, *args, **kwargs):
        if (responsible is not None) \
        and (responsible.caller_component == "access"):
            return
        try:
            serialized = self.core.config_manager.get(self.NAME)
            self.access_cfg = AccessConf.deserialize(serialized)
        except (ConfigError, DatastructureIncompatible):
            self.debug("Read config error: create new permissions")
            self.access_cfg = AccessConf()

        # force update
        self.services = None
コード例 #3
0
ファイル: access.py プロジェクト: maximerobin/Ufwi
 def service_setConfig(self, context, message, config):
     new_conf = AccessConf.deserialize(config)
     valid, errmsg = new_conf.isValidWithMsg()
     if not valid:
        raise AccessError(MISSING_ADMIN_ACCESS, errmsg)
     self.access_cfg = new_conf
     self.save_config(message, context)
コード例 #4
0
ファイル: access.py プロジェクト: maximerobin/Ufwi
class AccessComponent(AbstractNuConfComponent):
    NAME = "access"
    VERSION = "1.0"

    REQUIRES = ('config', 'localfw' )

    CONFIG = { }

    CONFIG_DEPENDS = frozenset(('network',))

    ROLES = {
        'conf_read': set(('getConfig', 'getServices')),
        'conf_write': set(('setConfig', 'applyRules')),
    }
    ACLS = {
        'status': set(('getStatus',)),
        'network': set(('getNetconfig',)),
        'localfw': set(('open', 'clear', 'addFilterRule', 'apply', 'close')),
        # FIXME: localfw should delegate the permissions
        'ufwi_ruleset': set(('reapplyLastRuleset',)),
        '*': set(('getPorts',)),
    }

    HARDCODED_SERVICES = {
        'ping_access': [
            {'proto':'icmp', 'icmp_type': 8},      # IPv4
            {'proto':'icmpv6', 'icmpv6_type': 128}, # IPv6 (Echo Request)
        ],
        # streaming port (udp) is set in read in ufwi_rpcd configuration
        'ufwi_rpcd_access': [
         {'proto':'tcp', 'port': 8443},
         {'proto':'udp', 'port': None}],
        # streaming port (udp) is set in read in ufwi_rpcd configuration
        'snmpd': [
         {'proto':'tcp', 'port': 161},
         {'proto':'udp', 'port': 161}],
        'SSH': [
            {'proto': 'tcp', 'port': 22}],
    }

    def init(self, core):
        AbstractNuConfComponent.init(self, core)
        self.core = core

        # dict: service name => port list
        self.services = None

        # Read streaming port from the config
        port = core.config.getint('CORE', 'streaming_udp_port')
        self.HARDCODED_SERVICES['ufwi_rpcd_access'][1]['port'] = port

    def applyRules(self, save=False, already_read=False):
        if not already_read:
            self.read_config(None)
        context = Context.fromComponent(self)

        self.debug('First loading of configuration')
        defer = self.update()
#       FIXME: Check permissions?
#        defer.addCallback(lambda unused: self.checkPermissions(self.permissions))
        defer.addCallback(self._applyGetNetcfg, context)
        if save:
            defer.addCallback(self._save_config)
        return defer

    def apply_config(self, responsible, callback_arg, paths):
        return self.applyRules(already_read=True)

    def _applyGetNetcfg(self, unused, context):
        defer = self.core.callService(context, 'network', 'getNetconfig')
        defer.addCallback(self._applyUseNetCfg, context)
        return defer

    def _clearRules(self, unused, context):
        return self.core.callService(context, 'localfw', 'clear')

    def _createRules(self, unused, netcfg, context):
        defer_list = []
        for service, networks in self.access_cfg.permissions.iteritems():
            ports = self.services[service]
            for port in ports:
                for interface, network in networks:
                    protocol = port['proto']
                    ipv6 = (network.version() == 6)
                    rule = {
                        'chain': 'INPUT',
                        'decision': 'ACCEPT',
                        'ipv6': ipv6,
                        'protocol': protocol,
                        'sources': [unicode(network)],
                        'input': interface,
                    }
                    if protocol == 'icmp':
                        if ipv6:
                            # ICMP is for IPv4
                            continue
                        rule['icmp_type'] = port['icmp_type']
                    elif protocol == 'icmpv6':
                        if not ipv6:
                            # ICMPv6 is for IPv6
                            continue
                        rule['icmpv6_type'] = port['icmpv6_type']
                    elif 'port' in port:
                        rule['dport'] = port['port']
                    defer = self.core.callService(context, 'localfw', 'addFilterRule', rule)
                    defer_list.append(defer)
        return gatherResults(defer_list)

    def _applyLocalFW(self, unused, context):
        return self.core.callService(context, 'localfw', 'apply')

    def _closeLocalFW(self, result, context):
        defer = self.core.callService(context, 'localfw', 'close')
        def _finally(unused):
            return result
        defer.addBoth(_finally)
        return defer

    def _applyUseNetCfg(self, netcfg_data, context):
        netcfg = deserializeNetCfg(netcfg_data)

        # FIXME: use LocalFW wrapper
        defer = self.core.callService(context, 'localfw', 'open', LOCALFW_FILENAME)
        defer.addCallback(self._clearRules, context)
        defer.addCallback(self._createRules, netcfg, context)
        defer.addCallback(self._applyLocalFW, context)
        defer.addBoth(self._closeLocalFW, context)
        return defer

    def read_config(self, responsible, *args, **kwargs):
        if (responsible is not None) \
        and (responsible.caller_component == "access"):
            return
        try:
            serialized = self.core.config_manager.get(self.NAME)
            self.access_cfg = AccessConf.deserialize(serialized)
        except (ConfigError, DatastructureIncompatible):
            self.debug("Read config error: create new permissions")
            self.access_cfg = AccessConf()

        # force update
        self.services = None

    def _updateNetworks(self, data):
        netcfg = deserializeNetCfg(data)
        networks = set((interface.system_name, network)
            for interface, network in netcfg.iterKnownNetworks())
        networks |= set(self.access_cfg.custom_networks)
        open_networks = set((interface, network)
            for (interface, network) in networks
            if network not in CLOSED_NETWORKS)
        permissions = self.access_cfg.permissions
        for service in permissions:
            if permissions[service] == True:
                permissions[service] = open_networks
            else:
                # delete old networks
                permissions[service] &= networks

    def _updateServices(self, result, context):
        old_permissions = self.access_cfg.permissions
        network_services, local_services = result
        new_permissions = {}
        self.services = {}
        services = chain(network_services, self.HARDCODED_SERVICES.iterkeys())
        services = list(services)
        for service in services:
            self.services[service] = tuple()
            if service in old_permissions:
                new_permissions[service] = old_permissions[service]
            elif service in OPEN_BY_DEFAULT:
                # opened for all networks by default
                new_permissions[service] = True
            else:
                # new service
                new_permissions[service] = set()
        # delete also the old services
        self.access_cfg.permissions = new_permissions

        defer = self.core.callService(context, 'network', 'getNetconfig')
        defer.addCallback(self._updateNetworks)
        defer.addCallback(self._updatePorts, context)
        return defer

    def _updatePort(self, ports, service):
        self.services[service] = ports

    def _updatePorts(self, unused, context):
        defer_list = []
        for service in self.services:
            try:
                self.services[service] = self.HARDCODED_SERVICES[service]
            except KeyError:
                defer = self.core.callService(context, service, "getPorts")
                defer.addCallback(self._updatePort, service)
                defer_list.append(defer)
        return gatherResults(defer_list)

    def update(self):
        context = Context.fromComponent(self)
        defer = self.core.callService(context, 'status', 'getStatus')
        defer.addCallback(self._updateServices, context)
        return defer

    def _getServices(self, unused=None):
        return self.services

    def service_getServices(self, context):
        defer = self.update()
        defer.addCallback(self._getServices)
        return defer

    def _getConfig(self, unused):
        return self.access_cfg.serialize()

    def service_getConfig(self, context):
        defer = self.update()
        defer.addCallback(self._getConfig)
        return defer

    def save_config(self, message="Save access config", context=None):
        self.info("Saving access config")
        with self.core.config_manager.begin(self, context) as cm:
            try:
                cm.delete(self.NAME)
            except:
                pass
            cm.set(self.NAME, self.access_cfg.serialize())
            cm.commit(message)

    def _save_config(self, unused):
        self.save_config()

    def service_setConfig(self, context, message, config):
        new_conf = AccessConf.deserialize(config)
        valid, errmsg = new_conf.isValidWithMsg()
        if not valid:
           raise AccessError(MISSING_ADMIN_ACCESS, errmsg)
        self.access_cfg = new_conf
        self.save_config(message, context)

    def service_applyRules(self, context):
        return self.applyRules(save=True)