Пример #1
0
    def checkConsistency(self, loader_context=None):
        # Import InterfaceResource and FirewallResource here instead of the top
        # of the file to avoid an import loop
        from ufwi_ruleset.forward.resource.interface import InterfaceResource
        from ufwi_ruleset.forward.resource.firewall import FirewallResource

        duplicates = set()
        for item in self.items:
            if isinstance(item.network, InterfaceResource):
                raise RulesetError(
                    tr("You can not use an interface (%s) in a platform (%s)."),
                    item.network.formatID(), self.formatID())
            if isinstance(item.network, FirewallResource):
                raise RulesetError(
                    tr("You can not use the firewall object in a platform (%s)."),
                    self.formatID())

            if item.network.interface != self.interface:
                raise RulesetError(
                    tr('A platform (%s) can not contain network objects '
                       'from different interfaces (%s and %s).'),
                    self.formatID(),
                    self.interface.formatID(),
                    item.network.interface.formatID())

            key = (item.network.id, item.protocol.id)
            if key in duplicates:
                raise RulesetError(
                    tr("Duplicate item in the platform %s: (%s, %s)."),
                    self.formatID(),
                    item.network.formatID(), item.protocol.formatID())
            duplicates.add(key)
Пример #2
0
def checkIdentifier(id):
    if not isinstance(id, unicode):
        raise RulesetError(tr("Invalid identifier: type is not unicode (%s)"), unicode(type(id)))
    if not id:
        raise RulesetError(tr("Invalid identifier: empty string"))
    if not REGEX_ID.match(id):
        raise RulesetError(tr("Invalid identifier: invalid characters or length (%s)"), repr(id))
Пример #3
0
 def sendMailToAdmin_cb(self, unused, template_variables):
     template_variables['my_fqdn'] = '%s.%s' % (
         template_variables['my_hostname'],
         template_variables['my_domain'])
     jinja_env = jinja.Environment()
     template = jinja_env.from_string(self.body_template)
     rendered_body = unicode(template.render(**template_variables))
     msg = MIMEText(rendered_body.encode('utf-8'), 'plain', 'utf-8')
     msg['Subject'] = u'[EW4 %s] %s' % (
         template_variables['my_hostname'],
         unicode(template_variables['subject']))
     sender = self.config.sender_mail
     if check_mail(sender):
         msg['From'] = sender
     else:
         raise NuConfError(CONTACT_INVALID_SENDER,
                           tr("'sender' e-mail : invalid e-mail address"))
     recipient = self.config.admin_mail
     if check_mail(recipient):
         msg['To'] = recipient
     else:
         raise NuConfError(CONTACT_INVALID_RECIPIENT,
                 tr("'recipient' e-mail : invalid e-mail address"))
     defer = sendmail('127.0.0.1', sender, recipient, msg.as_string())
     defer.addCallback(self.logSuccess)
     return defer
Пример #4
0
    def loadFile(self, ruleset_context, filetype, name,
    editable=False, from_template=None, action=None, ruleset_id=0,
    filename=None, content=None):
        # Log the action
        logger = ruleset_context.logger
        text = "Load %s: %s" % (filetype, name)
        if ruleset_id == 0:
            logger.info(text)
        else:
            logger.debug(text)

        if not content:
            # Get the filename
            if not filename:
                if filetype == "library":
                    filename = LIBRARY_FILENAME
                else:
                    filename = rulesetFilename(filetype, name)

            # Parse the XML file
            try:
                with open(filename) as fp:
                    ruleset = etree.parse(fp).getroot()
            except IOError, err:
                if err.errno == ENOENT:
                    if filetype == 'template':
                        message = tr('The "%s" template does not exist. It has been deleted or renamed.')
                    else:
                        message = tr('The "%s" rule set does not exist. It has been deleted or renamed.')
                    raise RulesetError(message, name)
                else:
                    raise RulesetError(
                        tr('Unable to open file "%s" (%s): %s'),
                        basename(filename), filetype, exceptionAsUnicode(err))
Пример #5
0
    def moveAcl(self, acl, new_order, check_editable):
        # Compute rules order
        rules  = self.acls
        old_order = self.getOrder(acl)
        length = len(rules)

        # Consistency checks
        if not (0 <= new_order < length):
            if new_order < old_order:
                format = tr("Unable to move up the %s: the rule is already the first of the %s chain.")
            else:
                format = tr("Unable to move down the %s: the rule is already the last of the %s chain.")
            raise RulesetError(
                format,
                unicode(acl), unicode(self))

        if old_order < new_order:
            first = old_order
            last = new_order
        else:
            first = new_order
            last = old_order

        for order in xrange(first, last+1):
            print("check", order)
            check_editable(rules[order])

        # Move the rule
        rule = rules.pop(old_order)
        rules.insert(new_order, rule)
Пример #6
0
def iptablesSave(logger, ipv6):
    """
    Save current iptables rules into a file.
    Return the filename of the saved rules.
    Raise an IptablesError on error.
    """
    if ipv6:
        filename = 'old_rules_ipv6'
        address_type = "IPv6"
    else:
        filename = 'old_rules_ipv4'
        address_type = "IPv4"
    filename = path_join(RULESET_DIR, filename)
    logger.warning("Save %s iptables rules to %s" % (address_type, filename))
    if ipv6:
        command_str = IP6TABLES_SAVE
    else:
        command_str = IPTABLES_SAVE
    command = (command_str,)
    with open(filename, 'w') as rules:
        process, code = runCommandAsRoot(logger, command, timeout=22.5, stdout=rules)
    if code != 0:
        raise IptablesError(tr("%s command exited with code %s!"), command_str, code)
    size = getsize(filename)
    if not size:
        raise IptablesError(tr("%s command output is empty!"), command_str)
    return filename
Пример #7
0
 def create(self, conf, logger):
     dbtype = conf['dbtype']
     try:
         db_object = self.objects[dbtype]
         if isinstance(db_object, (str, unicode)):
             raise DatabaseError(tr('Unable to use %s: %s'), dbtype, toUnicode(db_object))
     except KeyError, e:
         raise DatabaseError(tr('Unsupported database type %s'), dbtype)
Пример #8
0
 def checkConsistency(self, loader_context=None):
     if self.day_to < self.day_from:
         raise RulesetError(
             tr("Invalid day range: %s..%s"),
             self.day_from, self.day_to)
     if self.hour_to <= self.hour_from:
         raise RulesetError(
             tr("Invalid hour range: %sh00..%sh59"),
             self.hour_from, (self.hour_to - 1))
Пример #9
0
 def templatize(self, object, fusion):
     object.checkEditable()
     if object.isGeneric():
         raise RulesetError(tr("The %s object is already a generic object."), object.formatID())
     if not self.ruleset.is_template:
         raise RulesetError(tr("The rule set is not a template!"))
     attr = object.getAttributes()
     object.templatize(attr)
     return self.modifyObject(object, attr, fusion)
Пример #10
0
 def _createTemplate(self, name, parent):
     if (name in self.include_templates) \
     or (self.is_template and (self.name == name)):
         raise RulesetError(
             tr('The "%s" template can not be included twice'),
             name)
     identifier = 1 + len(self.include_templates)
     if 9 < identifier:
         raise RulesetError(tr("A rule set cannot comprise more than 9 templates!"))
     return IncludeTemplate(name, parent, identifier)
Пример #11
0
def getUserGroupNumber(group):
    try:
        group = int(group)
    except ValueError:
        raise RulesetError(
            tr("Invalid user group: %s"),
            unicode(group))
    if not(MIN_GROUP <= group <= MAX_GROUP):
        raise RulesetError(tr("Invalid user group number: %s"), group)
    return group
Пример #12
0
 def loadError(self, err, when):
     message = u"[%s] %s" % (err.__class__.__name__, exceptionAsUnicode(err))
     if self.name:
         err = RulesetError(
             tr('Error while loading %s from the "%s" rule set: %s'),
             when, self.name, message)
     else:
         err = RulesetError(
             tr('Error on new rule set creation (while loading %s): %s'),
             when, message)
     reraise(err)
Пример #13
0
 def _checkUserGroup(self, require_group_name, user_group):
     if require_group_name:
         if user_group.name is None:
             raise RulesetError(
                 tr('The firewall uses user group names, but the %s user group has no name'),
                 user_group.formatID())
     else:
         if user_group.group is None:
             raise RulesetError(
                 tr('The firewall uses user group numbers, but the %s user group has no number'),
                 user_group.formatID())
Пример #14
0
 def should_run(self, responsible):
     if not self.openvpn_cfg.enabled:
         if responsible:
             responsible.feedback(tr("Explicitely disabled."))
         return False
     if not self.openvpn_cfg.client_network:
         if responsible:
             responsible.feedback(
                 tr("No client network was defined, disabling server.")
                 )
         return False
     return True
Пример #15
0
def rulesetDelete(core, filetype, name):
    """
    Delete the specified ruleset.
    """
    if (filetype == "template") and (core.getMultisiteType() == MULTISITE_SLAVE):
        raise RulesetError(tr("Can not delete a template from a slave."))

    filename = rulesetFilename(filetype, name)
    try:
        unlink(filename)
    except IOError, err:
        raise RulesetError(tr("Unable to delete the file %s (%s): %s!"), name, filetype, exceptionAsUnicode(err))
Пример #16
0
 def _match(self, rule, attributes, match_func):
     if not attributes:
         raise RulesetError(tr("Empty attribute list"))
     for attr in attributes:
         if attr not in self.MATCH_ATTRIBUTES:
             raise RulesetError(tr("Unknown rule attribute: %s"), attr)
         # TODO platform use flattenNetworkList
         objects_a = getattr(self, attr)
         objects_b = getattr(rule, attr)
         if not match_func(objects_a, objects_b):
             return False
     return True
Пример #17
0
    def build(self, request, filters):
        protos = {'tcp':   6,
                  'udp':   17,
                  'icmp':  1,
                  'igmp':  2}

        try:
            proto = protos[self.value]
            return '%s = %s' % ('ip_protocol', proto)
        except KeyError:
            raise RpcdError(tr('Protocol must be tcp or udp (is %s)'), self.value)
            raise RpcdError(tr('Unknown protocol: %s'), self.value)
Пример #18
0
    def create(self, context, data):
        "Create an anonymous session"

        client_name = getUnicode("client_name", data['client_name'], 3, 100)
        protocol_version = getUnicode("protocol_version", data['protocol_version'], 3, 100)

        # Check client name and protocol version
        if not client_name or not (3 <= len(client_name) <= 20):
            raise SessionError(SESSION_INVALID_ARG,
                tr("Invalid client name: need a string with length in 3..20"))
        if not protocol_version or not (3 <= len(protocol_version) <= 10):
            raise SessionError(SESSION_INVALID_ARG,
                tr("Invalid protocol version: need a string with length in 3..10"))

        # Check protocol version
        if protocol_version != PROTOCOL_VERSION:
            raise SessionError(SESSION_INVALID_VERSION,
                tr("Invalid protocol version: %s"),
                repr(protocol_version))

        # Only a user with no session can create a new session
        if not context.user:
            raise SessionError(SESSION_NO_USER,
                tr("Only a user can create a session!"))
        if context.hasSession():
            raise SessionError(SESSION_DUPLICATE,
                tr("You already own a session!"))


        # Fill the user context
        user = context.user
        if 'client_release' in data:
            #size between 3 and 100
            user.client_release = getUnicode('client_release', data['client_release'], 3, 100)
        user.groups = ["anonymous"]
        user.client_name = client_name
        user.protocol_version = protocol_version

        # Create the session
        cookie = self.createCookie()
        filename = b32encode(cookie).strip("=") + ".pickle"
        filename = path_join(self.path, filename)
        cookie = b64encode(cookie)
        session = Session(cookie, filename, user)

        # Register the session and write it to the disk
        self.sessions[session.cookie] = session
        context.setSession(session)
        session.save()

        # Session created
        return session.cookie
Пример #19
0
 def checkServiceCall(self, context, service_name):
     ruleset_open = self.hasRules(context)
     if service_name == "open":
         if ruleset_open:
             rules = self.getRulesFile(context)
             raise LocalFWError(
                 tr("There is already an active rule set (%s)."),
                 rules.name)
     else:
         if not ruleset_open:
             raise LocalFWError(
                 tr("You have to open a rule set to use the %s() service."),
                 service_name)
Пример #20
0
    def taskDone(self, ret):
        if isinstance(ret, Failure):
            self.setError(ret.getErrorMessage())
            self.fw.error(
                tr("Error while performing task on firewall %s: %s") % (self.fw.name, str(ret.getErrorMessage()))
            )
            self.fw.debug(
                tr("Error while applying updates to firewall %s: %s") % (self.fw.name, str(ret.getTraceback()))
            )
            return

        if self.task_stop_on_success:
            self.state = FINNISHED
            self.task.stop()
Пример #21
0
    def service_getCertificatesInfo(self, ctx):
        """
        Return information about certifiates/eky currently set, in the form of a dictionnary:
        {
            'cert'  : ['brief description', 'certificate content'],
            'key'   : ['md5 of the key', ''],
            'ca'    : ['brief description', 'CA content'],
            'crl'   : ['brief description', 'CRL content'],
        }
        """
        infos = {
            'cert' :    [tr('No certificate set'), tr('No certificate has been set yet')],
            'key' :     [tr('No key set'), ''],
            'ca' :      [tr('No CA is set'), tr('No certificate authority has been set yet')],
            'crl' :     [tr('No CRL set'), tr('No certificate revocation list has been set yet')],
        }

        # Certificate
        try:
            if isfile(self.CERT_PATH):
                cert = load_cert(self.CERT_PATH)
                infos['cert'][0] = unicode(cert.get_subject())
                infos['cert'][1] = unicode(cert.as_text())
        except Exception, error:
            infos['cert'][0] = tr('Invalid certificate')
            self.cert_logger.debug("Invalid cert : %s" % error)
Пример #22
0
 def checkRule(self, apply_rules, recursive=False):
     if not Rule.checkRule(self, apply_rules, recursive=recursive):
         return False
     if self.isForward() and (not self.config.isGateway()):
         apply_rules.error(
             tr("The firewall is configured as a local firewall: "
                "%s can not be generated."),
             unicode(self))
         return False
     if self.user_groups and (not self.ruleset.useNuFW()):
         apply_rules.warning(
             tr("Identity-based Firewall is disabled: %s will not use identity."),
             unicode(self))
     return True
Пример #23
0
 def checkXMLroot(self, root):
     if root.tag != CONFIG_ROOT_TAG:
         raise ConfigError(CONFIG_ERR_XML_READ,
             tr('XML root is not %s'), CONFIG_ROOT_TAG)
     for item in root.items():
         if item[0] == VERSION_ATTR:
             if item[1] == VERSION:
                 return
             else:
                 raise ConfigError(CONFIG_ERR_XML_READ,
                     tr('VariablesStore version expected: %s, got %s'),
                     VERSION, item[1])
     raise ConfigError(CONFIG_ERR_XML_READ,
         tr('VariablesStore version not found (expected version="%s")'),
         VERSION)
Пример #24
0
    def delete(self, identifier):
        # FIXME: Factorize into Library.delete()

        # Get the resource
        resource = self.resources[identifier]
        resource.checkEditable()

        # Get all references
        resources = [resource] + resource.getChildren(recursive=True)
        for resource in resources:
            if not resource.references:
                continue
            # FIXME: avoid unicode(object)
            references = ", ".join(unicode(ref) for ref in resource.references)
            raise RulesetError(tr('Unable to delete the "%s" network: it is used by %s!'), resource.id, references)

        # Create the action
        identifiers = [resource.id for resource in resources]
        apply_updates = Update(u"resources", "delete", *identifiers)
        unapply_updates = Update(u"resources", "create", *identifiers)
        action = Action(
            ActionHandler(apply_updates, self._deleteMany, resources),
            ActionHandler(unapply_updates, self._createMany, resources),
        )

        # Apply the action
        return self.ruleset.addAction(action)
Пример #25
0
def rulesetUpload(component, logger, filetype, input_filename, content, netcfg):

    # Extract ruleset name from the input filename
    name = basename(input_filename)
    if not name.lower().endswith(".xml"):
        raise RulesetError('File extension is not ".xml"!')
    name = name[:-4]

    # Ensure that the ruleset doesn't exist on disk
    rulesetFilename(filetype, name, check_existing=True)

    # Decode the content
    content = decodeFileContent(content)

    # Open the ruleset the check the consistency
    ruleset = Ruleset(component, logger, netcfg, read_only=True)
    ruleset.load(logger, filetype, name, content=content)
    if component.core.getMultisiteType() == MULTISITE_SLAVE:
        if exists(MULTISITE_TEMPLATE_FILENAME):
            template = MULTISITE_TEMPLATE_NAME
        else:
            template = None
        replaceTemplate(logger, ruleset, template)

    # Write the ruleset
    try:
        ruleset.save()
    except IOError, err:
        raise RulesetError(
            tr("Unable to write into the file %s (%s): %s!"),
            basename(ruleset.filename),
            ruleset.filetype,
            exceptionAsUnicode(err),
        )
Пример #26
0
def rulesetDownload(filetype, name):
    filename = rulesetFilename(filetype, name)
    try:
        with open(filename, "rb") as fp:
            content = fp.read()
    except IOError, err:
        raise RulesetError(tr('Unable to open "%s" (%s): %s!'), basename(filename), filetype, exceptionAsUnicode(err))
Пример #27
0
 def init(self, data, loader_context=None, is_modify=True):
     """
     Write the attribute values and check object consistency. The
     operation is atomic: restore old attributes on error.
     """
     previous_state = dict(self.__dict__)
     if is_modify:
         old_attr = self.getAttributes()
     try:
         data = dict(data)
         self.setAttributes(data, is_modify)
         keys = data.keys()
         if keys:
             raise RulesetError(
                 tr("Unknown attributes: %s"),
                 u', '.join(keys))
         if loader_context:
             self.onLoading(loader_context)
         if is_modify:
             self.onModify(old_attr)
         self.checkConsistency(loader_context)
         if is_modify:
             for reference in self.references:
                 reference.checkConsistency(loader_context)
     except:
         # Restore previous (valid) state on error
         self.__dict__ = previous_state
         raise
Пример #28
0
    def removeTemplate(self, name):
        template = self.include_templates[name]
        if template.parent:
            raise RulesetError(
                tr('It is not possible to delete the "%s" template, included in the "%s" template'),
                name, template.parent)
        templates = [template]
        for template in self.include_templates.itervalues():
            if template.parent != name:
                continue
            templates.append(template)
        names = [template.name for template in templates]

        updates = Updates(Update("ruleset", "update", -1))
        action = Action(
            ActionHandler(updates, self._removeTemplates, names),
            ActionHandler(updates, self._addTemplates, templates))
        action.apply()

        try:
            for library in self._libraries.itervalues():
                library.removeTemplate(action, name)
        except:
            # Rollback
            action.unapply()
            raise
        return self.addAction(action, apply=False)
Пример #29
0
def sysctlSet(logger, key, value):
    command = [SYSCTL, u"-n", u"-q", u"-w", u"%s=%s" % (key, value)]
    process, code = runCommandAsRoot(logger, command)
    if code != 0:
        raise RulesetError(
            tr("sysctl error: unable to set %s value to %s! (exit code %s)"),
            key, value, code)
Пример #30
0
def ldapRules(context, component, ruleset, rule_type, identifiers):
    logger = ContextLoggerChild(context, component)
    result = ApplyRulesResult(logger)

    if rule_type == 'acls-ipv6':
        rules = ruleset.acls_ipv6
    elif rule_type == 'acls-ipv4':
        rules = ruleset.acls_ipv4
    else:
        # NuFW (LDAP) doesn't authenticate NAT rules
        raise RulesetError(tr("LDAP doesn't support rule type: %s"), repr(rule_type))
    if identifiers:
        rules = [ rules[id] for id in identifiers ]
    else:
        rules = rules

    ldap = WriteLdapRules(logger, component.config['ldap'])
    with TemplateInstanciation(ruleset):
        rules = filterRules(result, rules)

        lines = []
        for dn, attr in ldap.createRules(rules):
            lines.append(unicode(dn))
            attrs = attr.items()
            attrs.sort(key=lambda item: item[0])
            for key, value in attrs:
                lines.append(u"  %s=%r" % (key, value))
            lines.append(u"")
        xmlrpc = result.exportXMLRPC()
        xmlrpc['ldap'] = lines
        return xmlrpc