Esempio n. 1
0
    def _findMatchingRule(self, objName, matchType):
        """
        Search the configuration file for the first rule that matches the data
        or signed interest name. In the case of interests, the name to match
        should exclude the timestamp, nonce, and signature components.
        :param Name objName: The name to be matched.
        :param string matchType: The rule type to match, "data" or "interest".
        """
        rules = self.config["validator/rule"]
        for r in rules:
            if r['for'][0].getValue() == matchType:
                passed = True
                try:
                    filters = r['filter']
                except KeyError:
                    # no filters means we pass!
                    return r
                else:
                    for f in filters:
                        # don't check the type - it can only be name for now
                        # we need to see if this is a regex or a relation
                        try:
                            regex = f['regex'][0].getValue()
                        except KeyError:
                            matchRelation = f['relation'][0].getValue()
                            matchUri = f['name'][0].getValue()
                            matchName = Name(matchUri)
                            passed = self._matchesRelation(
                                objName, matchName, matchRelation)
                        else:
                            passed = NdnRegexMatcher.match(regex,
                                                           objName) is not None
                        if not passed:
                            break
                    if passed:
                        return r

        return None
Esempio n. 2
0
    def doesMatch(self, name):
        """
        Check if the given name matches this filter. Match if name starts with
        this filter's prefix. If this filter has the optional regexFilter then
        the remaining components match the regexFilter regular expression.
        For example, the following InterestFilter:

           InterestFilter("/hello", "<world><>+")

        will match all Interests, whose name has the prefix `/hello` which is
        followed by a component `world` and has at least one more component
        after it. Examples:

           /hello/world/!
           /hello/world/x/y/z

        Note that the regular expression will need to match all remaining
        components (e.g., there are implicit heading `^` and trailing `$`
        symbols in the regular expression).

        :param Name name: The name to check against this filter.
        :return: True if name matches this filter, otherwise False.
        :rtype: bool
        """
        if len(name) < len(self._prefix):
            return False

        if self.hasRegexFilter():
            # Perform a prefix match and regular expression match for the
            # remaining components.
            if not self._prefix.match(name):
                return False

            return None != NdnRegexMatcher.match(
              self._regexFilterPattern, name.getSubName(len(self._prefix)))
        else:
            # Just perform a prefix match.
            return self._prefix.match(name)
    def _findMatchingRule(self, objName, matchType):
        """
        Search the configuration file for the first rule that matches the data
        or signed interest name. In the case of interests, the name to match
        should exclude the timestamp, nonce, and signature components.
        :param Name objName: The name to be matched.
        :param string matchType: The rule type to match, "data" or "interest".
        """
        rules = self.config["validator/rule"]
        for r in rules:
            if r['for'][0].getValue() == matchType:
                passed = True
                try:
                    filters = r['filter']
                except KeyError:
                    # no filters means we pass!
                    return r
                else:
                    for f in filters:
                        # don't check the type - it can only be name for now
                        # we need to see if this is a regex or a relation
                        try:
                            regex = f['regex'][0].getValue()
                        except KeyError:
                            matchRelation = f['relation'][0].getValue()
                            matchUri = f['name'][0].getValue()
                            matchName = Name(matchUri)
                            passed = self._matchesRelation(objName, matchName, matchRelation)
                        else:
                            passed =  NdnRegexMatcher.match(regex, objName) is not None
                        if not passed:
                            break
                    if passed:
                        return r

        return None
Esempio n. 4
0
    def _checkSignatureMatch(self, signatureName, objectName, rule,
                             failureReason):
        """
        Once a rule is found to match data or a signed interest, the name in the
        KeyLocator must satisfy the condition in the 'checker' section of the rule,
        else the data or interest is rejected.

        :param Name signatureName: The certificate name from the KeyLocator .
        :param Name objectName: The name of the data packet or interest. In the
          case of signed interests, this excludes the timestamp, nonce and signature
          components.
        :param BoostInfoTree rule: The rule from the configuration file that matches
          the data or interest.
        :param Array<str> failureReason: If verification fails, set
          failureReason[0] to the failure reason string.
        :return: True if matches.
        :rtype: bool

        """
        checker = rule['checker'][0]
        checkerType = checker['type'][0].getValue()
        if checkerType == 'fixed-signer':
            signerInfo = checker['signer'][0]
            signerType = signerInfo['type'][0].getValue()
            if signerType == 'file':
                cert = self._lookupCertificate(
                    signerInfo['file-name'][0].getValue(), True)
                if cert is None:
                    failureReason[0] = (
                        "Can't find fixed-signer certificate file: " +
                        signerInfo['file-name'][0].getValue())
                    return False
            elif signerType == 'base64':
                cert = self._lookupCertificate(
                    signerInfo['base64-string'][0].getValue(), False)
                if cert is None:
                    failureReason[0] = (
                        "Can't find fixed-signer certificate base64: " +
                        signerInfo['base64-string'][0].getValue())
                    return False
            else:
                failureReason[0] = ("Unrecognized fixed-signer signerType: " +
                                    signerType)
                return False

            if cert.getName().equals(signatureName):
                return True
            else:
                failureReason[0] = ("fixed-signer cert name \"" +
                                    cert.getName().toUri() +
                                    "\" does not equal signatureName \"" +
                                    signatureName.toUri() + "\"")
                return False
        elif checkerType == 'hierarchical':
            # this just means the data/interest name has the signing identity as a prefix
            # that means everything before 'ksk-?' in the key name
            identityRegex = '^([^<KEY>]*)<KEY>(<>*)<ksk-.+><ID-CERT>'
            identityMatch = NdnRegexMatcher.match(identityRegex, signatureName)
            if identityMatch is not None:
                identityPrefix = Name(identityMatch.group(1)).append(
                    Name(identityMatch.group(2)))
                if self._matchesRelation(objectName, identityPrefix,
                                         'is-prefix-of'):
                    return True
                else:
                    failureReason[0] = ("The hierarchical objectName \"" +
                                        objectName.toUri() +
                                        "\" is not a prefix of \"" +
                                        identityPrefix.toUri() + "\"")
                    return False
            else:
                failureReason[0] = ("The hierarchical identityRegex \"" +
                                    identityRegex +
                                    "\" does not match signatureName \"" +
                                    signatureName.toUri() + "\"")
                return False
        elif checkerType == 'customized':
            keyLocatorInfo = checker['key-locator'][0]
            # not checking type - only name is supported

            # is this a simple relation?
            try:
                relationType = keyLocatorInfo['relation'][0].getValue()
            except KeyError:
                pass
            else:
                matchName = Name(keyLocatorInfo['name'][0].getValue())
                if self._matchesRelation(signatureName, matchName,
                                         relationType):
                    return True
                else:
                    failureReason[0] = ("The custom signatureName \"" +
                                        signatureName.toUri() +
                                        "\" does not match matchName \"" +
                                        matchName.toUri() +
                                        "\" using relation " + relationType)
                    return False

            # is this a simple regex?
            try:
                keyRegex = keyLocatorInfo['regex'][0].getValue()
            except KeyError:
                pass
            else:
                if NdnRegexMatcher.match(keyRegex, signatureName) is not None:
                    return True
                else:
                    failureReason[0] = (
                        "The custom signatureName \"" + signatureName.toUri() +
                        "\" does not regex match simpleKeyRegex \"" +
                        keyRegex + "\"")
                    return False

            # is this a hyper-relation?
            try:
                hyperRelation = keyLocatorInfo['hyper-relation'][0]
            except KeyError:
                pass
            else:
                keyRegex = hyperRelation.getFirstValue('k-regex')
                keyExpansion = hyperRelation.getFirstValue('k-expand')
                nameRegex = hyperRelation.getFirstValue('p-regex')
                nameExpansion = hyperRelation.getFirstValue('p-expand')
                relationType = hyperRelation.getFirstValue('h-relation')
                if (keyRegex != None and keyExpansion != None
                        and nameRegex != None and nameExpansion != None
                        and relationType != None):
                    keyMatch = NdnRegexMatcher.match(keyRegex, signatureName)
                    if keyMatch == None:
                        failureReason[0] = (
                            "The custom hyper-relation signatureName \"" +
                            signatureName.toUri() +
                            "\" does not match the keyRegex \"" + keyRegex +
                            "\"")
                        return False
                    keyMatchPrefix = keyMatch.expand(keyExpansion)

                    nameMatch = NdnRegexMatcher.match(nameRegex, objectName)
                    if nameMatch == None:
                        failureReason[0] = (
                            "The custom hyper-relation objectName \"" +
                            objectName.toUri() +
                            "\" does not match the nameRegex \"" + nameRegex +
                            "\"")
                        return False
                    nameMatchStr = nameMatch.expand(nameExpansion)

                    if self._matchesRelation(Name(nameMatchStr),
                                             Name(keyMatchPrefix),
                                             relationType):
                        return True
                    else:
                        failureReason[0] = (
                            "The custom hyper-relation nameMatch \"" +
                            nameMatchStr +
                            "\" does not match the keyMatchPrefix \"" +
                            keyMatchPrefix + "\" using relation " +
                            relationType)
                        return False

        failureReason[0] = "Unrecognized checkerType: " + checkerType
        return False
    def _checkSignatureMatch(self, signatureName, objectName, rule):
        """
        Once a rule is found to match data or a signed interest, the name in the
        KeyLocator must satisfy the condition in the 'checker' section of the rule,
        else the data or interest is rejected.

        :param Name signatureName: The certificate name from the KeyLocator .
        :param Name objectName: The name of the data packet or interest. In the
          case of signed interests, this excludes the timestamp, nonce and signature
          components.
        :param BoostInfoTree rule: The rule from the configuration file that matches
          the data or interest.

        """
        checker = rule['checker'][0]
        checkerType = checker['type'][0].getValue()
        if checkerType == 'fixed-signer':
            signerInfo = checker['signer'][0]
            signerType = signerInfo['type'][0].getValue()
            if signerType == 'file':
                cert = self._lookupCertificate(signerInfo['file-name'][0].getValue(), True)
            elif signerType == 'base64':
                cert = self._lookupCertificate(signerInfo['base64-string'][0].getValue(), False)
            else:
                return False
            if cert is None:
                return False
            else:
                return cert.getName().equals(signatureName)
        elif checkerType == 'hierarchical':
            # this just means the data/interest name has the signing identity as a prefix
            # that means everything before 'ksk-?' in the key name
            identityRegex = '^([^<KEY>]*)<KEY>(<>*)<ksk-.+><ID-CERT>'
            identityMatch = NdnRegexMatcher.match(identityRegex, signatureName)
            if identityMatch is not None:
                identityPrefix = Name(identityMatch.group(1)).append(Name(identityMatch.group(2)))
                return self._matchesRelation(objectName, identityPrefix, 'is-prefix-of')
            else:
                return False
        elif checkerType == 'customized':
            keyLocatorInfo = checker['key-locator'][0]
            # not checking type - only name is supported

            # is this a simple relation?
            try:
                relationType = keyLocatorInfo['relation'][0].getValue()
            except KeyError:
                pass
            else:
                matchName = Name(keyLocatorInfo['name'][0].getValue())
                return self._matchesRelation(signatureName, matchName, relationType)

            # is this a simple regex?
            try:
                keyRegex = keyLocatorInfo['regex'][0].getValue()
            except KeyError:
                pass
            else:
                return NdnRegexMatcher.match(keyRegex, signatureName) is not None

            # is this a hyper-relation?
            try:
                hyperRelation = keyLocatorInfo['hyper-relation'][0]
            except KeyError:
                pass
            else:
                try:
                    keyRegex = hyperRelation['k-regex'][0].getValue()
                    keyMatch = NdnRegexMatcher.match(keyRegex, signatureName)
                    keyExpansion = hyperRelation['k-expand'][0].getValue()
                    keyMatchPrefix = keyMatch.expand(keyExpansion)

                    nameRegex = hyperRelation['p-regex'][0].getValue()
                    nameMatch = NdnRegexMatcher.match(nameRegex, objectName)
                    nameExpansion = hyperRelation['p-expand'][0].getValue()
                    nameMatchStr = nameMatch.expand(nameExpansion)

                    relationType = hyperRelation['h-relation'][0].getValue()

                    return self._matchesRelation(Name(nameMatchStr), Name(keyMatchPrefix), relationType)
                except:
                    pass

        # unknown type
        return False
Esempio n. 6
0
    def _checkSignatureMatch(self, signatureName, objectName, rule):
        """
        Once a rule is found to match data or a signed interest, the name in the
        KeyLocator must satisfy the condition in the 'checker' section of the rule,
        else the data or interest is rejected.

        :param Name signatureName: The certificate name from the KeyLocator .
        :param Name objectName: The name of the data packet or interest. In the
          case of signed interests, this excludes the timestamp, nonce and signature
          components.
        :param BoostInfoTree rule: The rule from the configuration file that matches
          the data or interest.

        """
        checker = rule['checker'][0]
        checkerType = checker['type'][0].getValue()
        if checkerType == 'fixed-signer':
            signerInfo = checker['signer'][0]
            signerType = signerInfo['type'][0].getValue()
            if signerType == 'file':
                cert = self._lookupCertificate(
                    signerInfo['file-name'][0].getValue(), True)
            elif signerType == 'base64':
                cert = self._lookupCertificate(
                    signerInfo['base64-string'][0].getValue(), False)
            else:
                return False
            if cert is None:
                return False
            else:
                return cert.getName().equals(signatureName)
        elif checkerType == 'hierarchical':
            # this just means the data/interest name has the signing identity as a prefix
            # that means everything before 'ksk-?' in the key name
            identityRegex = '^([^<KEY>]*)<KEY>(<>*)<ksk-.+><ID-CERT>'
            identityMatch = NdnRegexMatcher.match(identityRegex, signatureName)
            if identityMatch is not None:
                identityPrefix = Name(identityMatch.group(1)).append(
                    Name(identityMatch.group(2)))
                return self._matchesRelation(objectName, identityPrefix,
                                             'is-prefix-of')
            else:
                return False
        elif checkerType == 'customized':
            keyLocatorInfo = checker['key-locator'][0]
            # not checking type - only name is supported

            # is this a simple relation?
            try:
                relationType = keyLocatorInfo['relation'][0].getValue()
            except KeyError:
                pass
            else:
                matchName = Name(keyLocatorInfo['name'][0].getValue())
                return self._matchesRelation(signatureName, matchName,
                                             relationType)

            # is this a simple regex?
            try:
                keyRegex = keyLocatorInfo['regex'][0].getValue()
            except KeyError:
                pass
            else:
                return NdnRegexMatcher.match(keyRegex,
                                             signatureName) is not None

            # is this a hyper-relation?
            try:
                hyperRelation = keyLocatorInfo['hyper-relation'][0]
            except KeyError:
                pass
            else:
                try:
                    keyRegex = hyperRelation['k-regex'][0].getValue()
                    keyMatch = NdnRegexMatcher.match(keyRegex, signatureName)
                    keyExpansion = hyperRelation['k-expand'][0].getValue()
                    keyMatchPrefix = keyMatch.expand(keyExpansion)

                    nameRegex = hyperRelation['p-regex'][0].getValue()
                    nameMatch = NdnRegexMatcher.match(nameRegex, objectName)
                    nameExpansion = hyperRelation['p-expand'][0].getValue()
                    nameMatchStr = nameMatch.expand(nameExpansion)

                    relationType = hyperRelation['h-relation'][0].getValue()

                    return self._matchesRelation(Name(nameMatchStr),
                                                 Name(keyMatchPrefix),
                                                 relationType)
                except:
                    pass

        # unknown type
        return False
Esempio n. 7
0
    def _checkSignatureMatch(self, signatureName, objectName, rule, failureReason):
        """
        Once a rule is found to match data or a signed interest, the name in the
        KeyLocator must satisfy the condition in the 'checker' section of the rule,
        else the data or interest is rejected.

        :param Name signatureName: The certificate name from the KeyLocator .
        :param Name objectName: The name of the data packet or interest. In the
          case of signed interests, this excludes the timestamp, nonce and signature
          components.
        :param BoostInfoTree rule: The rule from the configuration file that matches
          the data or interest.
        :param Array<str> failureReason: If verification fails, set
          failureReason[0] to the failure reason string.
        :return: True if matches.
        :rtype: bool

        """
        checker = rule['checker'][0]
        checkerType = checker['type'][0].getValue()
        if checkerType == 'fixed-signer':
            signerInfo = checker['signer'][0]
            signerType = signerInfo['type'][0].getValue()
            if signerType == 'file':
                cert = self._lookupCertificate(signerInfo['file-name'][0].getValue(), True)
                if cert is None:
                    failureReason[0] = (
                      "Can't find fixed-signer certificate file: " +
                      signerInfo['file-name'][0].getValue())
                    return False
            elif signerType == 'base64':
                cert = self._lookupCertificate(signerInfo['base64-string'][0].getValue(), False)
                if cert is None:
                    failureReason[0] = (
                      "Can't find fixed-signer certificate base64: " +
                      signerInfo['base64-string'][0].getValue())
                    return False
            else:
                failureReason[0] = ("Unrecognized fixed-signer signerType: " +
                  signerType)
                return False

            if cert.getName().equals(signatureName):
                return True
            else:
                failureReason[0] = ("fixed-signer cert name \"" +
                  cert.getName().toUri() + "\" does not equal signatureName \"" +
                  signatureName.toUri() + "\"")
                return False
        elif checkerType == 'hierarchical':
            # this just means the data/interest name has the signing identity as a prefix
            # that means everything before 'ksk-?' in the key name
            identityRegex = '^([^<KEY>]*)<KEY>(<>*)<ksk-.+><ID-CERT>'
            identityMatch = NdnRegexMatcher.match(identityRegex, signatureName)
            if identityMatch is not None:
                identityPrefix = Name(identityMatch.group(1)).append(Name(identityMatch.group(2)))
                if self._matchesRelation(objectName, identityPrefix, 'is-prefix-of'):
                    return True
                else:
                    failureReason[0] = ("The hierarchical objectName \"" +
                      objectName.toUri() + "\" is not a prefix of \"" +
                      identityPrefix.toUri() + "\"")
                    return False
            else:
                failureReason[0] = ("The hierarchical identityRegex \"" +
                  identityRegex + "\" does not match signatureName \"" +
                  signatureName.toUri() + "\"")
                return False
        elif checkerType == 'customized':
            keyLocatorInfo = checker['key-locator'][0]
            # not checking type - only name is supported

            # is this a simple relation?
            try:
                relationType = keyLocatorInfo['relation'][0].getValue()
            except KeyError:
                pass
            else:
                matchName = Name(keyLocatorInfo['name'][0].getValue())
                if self._matchesRelation(signatureName, matchName, relationType):
                    return True
                else:
                    failureReason[0] = ("The custom signatureName \"" +
                      signatureName.toUri() + "\" does not match matchName \"" +
                      matchName.toUri() + "\" using relation " + relationType)
                    return False

            # is this a simple regex?
            try:
                keyRegex = keyLocatorInfo['regex'][0].getValue()
            except KeyError:
                pass
            else:
                if NdnRegexMatcher.match(keyRegex, signatureName) is not None:
                    return True
                else:
                    failureReason[0] = ("The custom signatureName \"" +
                      signatureName.toUri() +
                      "\" does not regex match simpleKeyRegex \"" + keyRegex +
                      "\"")
                    return False

            # is this a hyper-relation?
            try:
                hyperRelation = keyLocatorInfo['hyper-relation'][0]
            except KeyError:
                pass
            else:
                keyRegex = hyperRelation.getFirstValue('k-regex')
                keyExpansion = hyperRelation.getFirstValue('k-expand')
                nameRegex = hyperRelation.getFirstValue('p-regex')
                nameExpansion = hyperRelation.getFirstValue('p-expand')
                relationType = hyperRelation.getFirstValue('h-relation')
                if (keyRegex != None and keyExpansion != None and
                      nameRegex != None and nameExpansion != None and
                      relationType != None):
                    keyMatch = NdnRegexMatcher.match(keyRegex, signatureName)
                    if keyMatch == None:
                        failureReason[0] = (
                          "The custom hyper-relation signatureName \"" +
                          signatureName.toUri() +
                          "\" does not match the keyRegex \"" + keyRegex + "\"")
                        return False
                    keyMatchPrefix = keyMatch.expand(keyExpansion)

                    nameMatch = NdnRegexMatcher.match(nameRegex, objectName)
                    if nameMatch == None:
                        failureReason[0] = (
                          "The custom hyper-relation objectName \"" +
                          objectName.toUri() +
                          "\" does not match the nameRegex \"" + nameRegex + "\"")
                        return False
                    nameMatchStr = nameMatch.expand(nameExpansion)

                    if self._matchesRelation(
                          Name(nameMatchStr), Name(keyMatchPrefix), relationType):
                        return True
                    else:
                        failureReason[0] = (
                          "The custom hyper-relation nameMatch \"" +
                          nameMatchStr + "\" does not match the keyMatchPrefix \"" +
                          keyMatchPrefix + "\" using relation " + relationType)
                        return False
    
        failureReason[0] = "Unrecognized checkerType: " + checkerType
        return False