Ejemplo n.º 1
0
    def __init__(self,
                 face,
                 onResult,
                 onError,
                 name,
                 rrtype=dns.rdatatype.FH,
                 parse_dns=True,
                 verify=True,
                 cache=None):
        self.face = face
        self.onResult = onResult
        self.onError = onError
        self.name = name
        self.rrtype = rrtype
        self.parse_dns = parse_dns
        self.verify = verify

        self.zone = ndn.Name()
        self.hint = None
        self.i = 0
        self.label_real = ndn.Name()
        self.label_logical = ndn.Name()

        self.fh_result = None
        self.fh_msg = None

        self.cachingQuery = cache
        if self.cachingQuery is None:
            raise ("CachingQuery object is required")
Ejemplo n.º 2
0
    def _onRequest(self, scope, zone, basename, interest):
        _LOG.debug(">> scope [%s], zone [%s], basename [%s], interest [%s]" %
                   (scope, zone.name, basename, interest.name))

        if self._enable_dyndns:
            if interest.name[-1] == "NDNUPDATE":
                self._dyndns._processDyNDNS(zone, basename, interest)
                return

        dataPacket = self._getRequestedData(
            zone, ndn.Name(basename[len(scope):]),
            ndn.Name(interest.name[len(scope):]))
        if dataPacket:
            if len(scope) == 0:
                self._face.put(dataPacket)
            else:
                # will sign with real key, but not sure if it is really necessary
                encapPacket = ndns.createSignedData(
                    self._ndns,
                    ndn.Name(scope).append(dataPacket.name),
                    dataPacket.toWire(),
                    dataPacket.signedInfo.freshnessSeconds, zone.default_key)
                _LOG.debug("Encapsulating into [%s]" % encapPacket.name)
                self._face.put(encapPacket)

        return
Ejemplo n.º 3
0
    def _disableZone (self, zone):
        name = zone.name

        self._face.clearInterestFilter (ndn.Name (name).append ("DNS"))

        activeScopes = []
        for scope in self._scopes + self._autoScope:
            if not scope.isPrefixOf (name):
                activeScopes.append (str (scope))
                self._face.clearInterestFilter (ndn.Name (scope).append ("\xF0.").append (name).append ("DNS"))

        _LOG.info ('<< Stop serving zone [%s] (%s)' % (name, activeScopes))
Ejemplo n.º 4
0
    def _enableZone (self, zone):
        name = zone.name

        self._face.setInterestFilter (ndn.Name (name).append ("DNS"),
                                      functools.partial (self._onRequest, ndn.Name (), zone))

        activeScopes = []
        for scope in self._scopes + self._autoScope:
            if not scope.isPrefixOf (name):
                activeScopes.append (str (scope))
                self._face.setInterestFilter (ndn.Name (scope).append ("\xF0.").append (name).append ("DNS"),
                                              functools.partial (self._onRequest, ndn.Name (scope).append ("\xF0."), zone))
        _LOG.info ('>> Start serving zone [%s] (%s)' % (name, activeScopes))
Ejemplo n.º 5
0
    def _getRequestedData (self, zone, basename, interestName):
        _LOG.debug (">> REAL: basename [%s], interest [%s]" % (basename, interestName))

        if str(interestName[-1])[0] == '\xFD':
            # allow version to be specified, but ignore it for the database lookup
            request_name = ndn.Name (interestName[:-1])
        else:
            request_name = interestName

        try:
            label = dns.name.from_text (ndns.dnsify (str (ndn.Name (request_name[len(basename):-1])))).relativize (origin = dns.name.root)
        except Exception, e:
            _LOG.debug ("Invalid request: label [%s] cannot be dnsified (%s)" % (request_name[len(basename):-1], e))
            return None
Ejemplo n.º 6
0
    def expressQueryFor(self,
                        face,
                        onResult,
                        onError,
                        zone,
                        hint,
                        label,
                        rrtype,
                        parse_dns=True,
                        limit_left=10,
                        verify=True):

        # _LOG.debug ('expressQueryFor')
        if isinstance(rrtype, str):
            rrtype = dns.rdatatype.to_text(dns.rdatatype.from_text(rrtype))
        else:
            rrtype = dns.rdatatype.to_text(rrtype)

        query = ndn.Name(zone).append("DNS")
        if len(label) > 0:
            query = query.append(label)
        query = query.append(rrtype)

        self.expressQueryForRaw(face, onResult, onError, query, zone, hint,
                                label, rrtype, parse_dns, limit_left, verify)
Ejemplo n.º 7
0
	def build_interest(self, latest):
		if self.start_with_latest:
			latest=True
			self.start_with_latest = False

		excl = ndn.ExclusionFilter()
		excl.add_any()
		excl.add_name(ndn.Name([self.latest_version]))
		# expected result should be between those two names
		excl.add_name(ndn.Name([self.last_version_marker]))
		excl.add_any()

		interest = ndn.Interest(name=self.base_name, exclude=excl, \
			minSuffixComponents=3, maxSuffixComponents=3)
		interest.childSelector = 1 if latest else 0
		return interest
Ejemplo n.º 8
0
	def __init__(self, prefix, handle):
		self.prefix = ndn.Name(prefix)
		self.handle = handle
		self.content_objects = []

		self.cleanup_time = 15 * 60 # keep responses for 15 min
		handle.setInterestFilter(self.prefix, self)
Ejemplo n.º 9
0
    def __init__(self, data_dir, scopes=[], enable_dyndns=True):
        self.data_dir = data_dir
        self._scopes = [ndn.Name(scope) for scope in scopes]

        self._zones = []
        self._autoScope = []
        self._enable_dyndns = enable_dyndns
Ejemplo n.º 10
0
    def _onNsResult(self, ns_result, ns_msg):
        ns_rrdata = random.choice(ns_msg.answer[0].items)

        # A couple of cheats, to handle names like "/ndn/ucla.edu/irl"

        # ns_target = ndnify (ns_rrdata.target.relativize (dns.name.root).to_text ())
        dns_zone = dns.name.from_text(dnsify(str(self.zone)))
        dns_ns_target = ns_rrdata.target

        if dns_ns_target.is_subdomain(dns_zone):
            ns_label = ndn.Name(
                ndnify(dns_ns_target.relativize(dns_zone).to_text()))
            self.cachingQuery.expressQueryFor(self.face,
                                              self._onFhResult,
                                              self.onError,
                                              self.zone,
                                              self.hint,
                                              ns_label,
                                              dns.rdatatype.FH,
                                              parse_dns=True,
                                              verify=self.verify)
        else:
            # ns_target = ndn.Name (ndnify (dns_ns_target.relativize (dns.name.root).to_text ()))
            # IterativeQuery.expressQuery (self.face, self._onFhResult, self.onError,
            #                              ns_target, dns.rdatatype.FH, True)

            self.onError(
                "NS record pointing outside the domain structure is currently not supported"
            )
            return
Ejemplo n.º 11
0
	def upcall(self, kind, upcallInfo):
		if kind == ndn.UPCALL_FINAL:
			# any cleanup code here (so far I never had need for
			# this call type)
			return ndn.RESULT_OK

		if kind == ndn.UPCALL_INTEREST_TIMED_OUT:
			print("Got timeout!")
			return ndn.RESULT_OK

		# make sure we're getting sane responses
		if not kind in [ndn.UPCALL_CONTENT,
						ndn.UPCALL_CONTENT_UNVERIFIED,
						ndn.UPCALL_CONTENT_BAD]:
			print("Received invalid kind type: %d" % kind)
			sys.exit(100)

		matched_comps = upcallInfo.matchedComps
		response_name = upcallInfo.ContentObject.name
		org_prefix = response_name[:matched_comps]

		assert(org_prefix == self.root)

		if matched_comps == len(response_name):
			comp = ndn.Name([upcallInfo.ContentObject.digest()])
			disp_name = ndn.Name(response_name)
		else:
			comp = response_name[matched_comps:matched_comps + 1]
			disp_name = response_name[:matched_comps + 1]

		if kind == ndn.UPCALL_CONTENT_BAD:
			print("*** VERIFICATION FAILURE *** %s" % response_name)

		print("%s [%s]" % (disp_name, \
			"verified" if kind == ndn.UPCALL_CONTENT else "unverified"))

		self.exclusions.add_name(comp)
		self.express_my_interest()

		# explore next level
		if matched_comps + 1 < len(response_name):
			new = Slurp(response_name[:matched_comps + 1], self.handle)
			new.express_my_interest()

		return ndn.RESULT_OK
Ejemplo n.º 12
0
    def _authorizeKey(self, zone, basename, keyName, seqno):
        if (keyName[-1] != "NDNCERT"):
            return False

        key_label = dns.name.from_text (ndns.dnsify (str (ndn.Name (keyName[len(basename):-1])))).\
            relativize (origin = dns.name.root)

        key = self.session.query(ndns.RRSet).with_parent(zone).filter_by(
            label=key_label.to_text(), rtype=dns.rdatatype.NDNCERT).first()
        if not key:
            _LOG.warn(
                "Key [%s] has been validated, but does not belong to the zone. Denying update"
                % keyName)
            return False

        current_key_seq = self.session.query(
            ndns.RRSet).with_parent(zone).filter_by(
                label=key_label.to_text(),
                rtype=dns.rdatatype.NDNCERTSEQ).first()

        if not current_key_seq:
            current_key_seq = ndns.RRSet(label=key_label.to_text(),
                                         zone=zone,
                                         rclass=dns.rdataclass.IN,
                                         rtype=dns.rdatatype.NDNCERTSEQ)
            rd = dns.rdtypes.IN.NDNCERTSEQ.NDNCERTSEQ(
                rdclass=dns.rdataclass.IN,
                rdtype=dns.rdatatype.NDNCERTSEQ,
                seq=ndn.Name())
            rr = ndns.RR(ttl=0, rrdata=rd, rrset=current_key_seq)

        if current_key_seq.rrs[0].dns_rrdata.seq >= seqno:
            _LOG.warn(
                "Replay attack detected, denying the update with sequence number [%s]"
                % seqno)
            return False

        updated_rr = current_key_seq.rrs[0].dns_rrdata
        updated_rr.seq = seqno
        current_key_seq.rrs[0].rrdata = updated_rr
        current_key_seq.refresh_ndndata(self.session, zone.default_key)
        self.session.commit()

        return True
Ejemplo n.º 13
0
    def _onFhResult(self, fh_result, fh_msg):
        if len(fh_msg.answer
               ) == 0 or fh_msg.answer[0].rdtype != dns.rdatatype.FH:
            self.onError(
                "Query returned a data packet, but records in answer section (should not really happen)"
            )
            return

        self.fh_result = fh_result
        self.fh_msg = fh_msg

        fh_rrdata = random.choice(fh_msg.answer[0].items)
        self.hint = fh_rrdata.hint

        self.zone = self.zone.append(self.label_real)
        self.label_real = ndn.Name()
        self.label_logical = ndn.Name()

        # next iteration or check for the result
        self._getMostSpecificNsAnswer(tryEmptyLabel=False)
Ejemplo n.º 14
0
    def expressQueryForRaw (face,
                            onResult, onError,
                            query,
                            zone = None, hint = None, label = None, rrtype = None, parse_dns = True, limit_left = 10, verify = True):
        """
        This is the most basic type of querying.  The user has to explicity
        specify the authority zone, forwarding hint, label, and resource record type1

        If ``zone``, ``label``, or ``rrtype`` are omitted or None, then they will be guessed from the query

        :param face: Face object
        :type face: ndn.Face
        :param onResult: Callback called when query returns a valid result:

            .. method:: onResult (data, dnsMessage)

                :param data: Data packet
                :type data: ndn.Data
                :param dnsMessage: if ``parse_dns`` flag is True, then fully parsed DNS message.
                                   if flag is False, then None
                :type dnsMessage: dns.Message

        :param onError: Callback called when query fails

            .. method:: onError (errorMessage)

                :param errorMessage: Error message with explanation of the error
                :type errorMessage: str

        :param query: NDN name of the query in form of ``<authority_zone>/DNS/<label(s)>/<RR-TYPE>``
        :type query: ndn.Name
        :param zone:
        :param hint:
        :param label:
        :param rrtype: RR type to query, e.g., "NS" or "FH" (default: infer from the query)
        :type rrtype: str
        :param parse_dns: Flag whether to parse DNS message or not (default True)
        :type parse_dns: bool
        """

        _LOG.debug ("expressQueryForRaw: query: %s, hint: %s" % (query, hint))

        if hint and not hint.isPrefixOf (query):
            query = ndn.Name (hint).append ("\xF0.").append (query)
        else:
            hint = None

        state = SimpleQuery (face,
                             onResult, onError,
                             query,
                             zone, hint, label, rrtype, parse_dns, limit_left, verify)
        face.expressInterest (query, state._onData, state._onTimeout)
Ejemplo n.º 15
0
	def __init__(self, base_name, callback, handle=None, version=None, latest=True):
		handle = handle or ndn.Face()

		# some constants
		self.version_marker = '\xfd'
		self.first_version_marker = self.version_marker
		self.last_version_marker = '\xfe\x00\x00\x00\x00\x00\x00'

		self.base_name = ndn.Name(base_name)
		self.callback = callback
		self.handle = handle
		self.latest_version = version or self.first_version_marker
		self.start_with_latest = latest
Ejemplo n.º 16
0
    def _getMostSpecificNsAnswer(self, tryEmptyLabel=False):
        _LOG.debug('_getMostSpecificNsAnswer [in %s for %s NS]' %
                   (self.zone, self.label_logical))
        if self.i < len(self.name):
            if not tryEmptyLabel:
                component = self.name[self.i]
                self.i += 1

                self.label_logical = ndn.Name().append(ndnify(str(component)))
                self.label_real = ndn.Name().append(component)

            self.cachingQuery.expressQueryFor(self.face,
                                              self._onMostSpecificNsAnswer,
                                              self.onError,
                                              self.zone,
                                              self.hint,
                                              self.label_logical,
                                              dns.rdatatype.NS,
                                              parse_dns=True,
                                              verify=self.verify)
        else:
            self._onNoMoreNsDelegation()
Ejemplo n.º 17
0
    def __init__(self, prefix, callback):
        self.gui_callback = callback
        self.friendly_names = {}

        self.handle = ndn.Face()
        self.chat_uri = ndn.Name(prefix)
        self.members_uri = self.chat_uri + "members"

        self.net_pull = VersionedPull(self.chat_uri, None, handle=self.handle)

        self.default_key = self.handle.getDefaultKey()
        digest = fix_digest(self.default_key.publicKeyID)
        self.friendly_names[digest] = getpass.getuser()
Ejemplo n.º 18
0
def get_certificate():
    name = request.args.get('name')
    ndn_name = ndn.Name(str(name))

    cert = mongo.db.certs.find_one({'name': str(name)})
    if cert == None:
        abort(404)

    response = make_response(cert['cert'])
    response.headers['Content-Type'] = 'application/octet-stream'
    response.headers[
        'Content-Disposition'] = 'attachment; filename=%s.ndncert' % str(
            ndn_name[-3])
    return response
Ejemplo n.º 19
0
def get_operator_for_email(email):
    # very basic pre-validation
    user, domain = email.split('@', 2)
    operator = mongo.db.operators.find_one({'site_emails': {'$in': [domain]}})
    if (operator == None):
        operator = mongo.db.operators.find_one(
            {'site_emails': {
                '$in': ['guest']
            }})

        if (operator == None):
            raise Exception("Unknown site for domain [%s]" % domain)

        # Special handling for guests
        ndn_domain = ndn.Name("/ndn/guest")
        assigned_namespace = \
            ndn.Name('/ndn/guest') \
            .append(email)
    else:
        if domain == "operators.named-data.net":
            ndn_domain = ndn.Name(str(user))
            assigned_namespace = ndn.Name(str(user))
        else:
            ndn_domain = ndnify(domain)
            assigned_namespace = \
                ndn.Name('/ndn') \
                .append(ndn_domain) \
                .append(user)

    # return various things
    return {
        'operator': operator,
        'user': user,
        'domain': domain,
        'ndn_domain': ndn_domain,
        'assigned_namespace': assigned_namespace
    }
Ejemplo n.º 20
0
    def __init__(self, prefix, nick=getpass.getuser()):
        self.handle = ndn.Face()
        self.flow = FlowController(prefix, self.handle)

        #XXX: temporary, until we allow fetching key from key storage
        self.key = self.handle.getDefaultKey()
        self.keylocator = ndn.KeyLocator(self.key)

        self.prefix = ndn.Name(prefix)
        self.members_uri = self.prefix + "members"

        member_name = self.members_uri.appendKeyID(
            fix_digest(self.key.publicKeyID))
        self.member_message = self.publish(member_name, nick)
        self.flow.put(self.member_message)
Ejemplo n.º 21
0
    def ndn_label(self):
        """
        Get label of the key name

        Note that this method makes sense only for ZSKs

        :returns: Key name minus the zone name
        :rtype: :py:class:`ndn.Name`
        """
        name = self.name
        if name[:len(self.zone.name)] == self.zone.name:
            return ndn.Name(name[len(self.zone.name) + 1:-1])
        else:
            raise KeyException(
                "Key does not belong to the zone (KSK should be stored in the parent zone!)"
            )
Ejemplo n.º 22
0
    def _getRequestedData(self, zone, basename, interestName):
        _LOG.debug(">> REAL: basename [%s], interest [%s]" %
                   (basename, interestName))

        if str(interestName[-1])[0] == '\xFD':
            # allow version to be specified, but ignore it for the database lookup
            request_name = ndn.Name(interestName[:-1])
        else:
            request_name = interestName

        try:
            rrtype = dns.rdatatype.from_text(str(request_name[-1]))
        except Exception, e:
            _LOG.debug(
                "Invalid request: unknown or unrecognized RR type [%s] (%s)" %
                (request_name[-1], e))
            return None
Ejemplo n.º 23
0
    def label(self):
        """
        Get DNS label of the key name

        Note that this method makes sense only for ZSKs.  For KSKs, use :py:attr:`parent_label`.

        :returns: DNS formatted string of key name minus the zone name
        :rtype: str
        """

        name = self.name
        if name[:len(self.zone.name)] == self.zone.name:
            return dnsify(str(ndn.Name(name[len(self.zone.name) + 1:-1])))
        else:
            raise KeyException(
                "Key does not belong to the zone (KSK should be stored in the parent zone!)"
            )
Ejemplo n.º 24
0
def main(args):
	if len(sys.argv) != 2:
		usage()

	name = ndn.Name(sys.argv[1])
	data = ndnb_enumerate(generate_names())

	key = ndn.Face.getDefaultKey()
	name = name.append('\xc1.E.be').appendKeyID(key).appendVersion()

	wrapper = Wrapper(name, key)
	sgmtr = segmenter(data, wrapper)

	handle = ndn.Face()
	for seg in sgmtr:
		handle.put(seg)

	return 0
Ejemplo n.º 25
0
	def publish(name, content):
		key = ndn.Face.getDefaultKey()
		keylocator = ndn.KeyLocator(key)

		# Name
		co_name = ndn.Name(name).appendSegment(0)

		# SignedInfo
		si = ndn.SignedInfo()
		si.type = ndn.CONTENT_DATA
		si.finalBlockID = ndn.Name.num2seg(0)
		si.publisherPublicKeyDigest = key.publicKeyID
		si.keyLocator = keylocator

		# ContentObject
		co = ndn.ContentObject()
		co.content = content
		co.name = co_name
		co.signedInfo = si

		co.sign(key)
		return co
Ejemplo n.º 26
0
    def parent_label(self):
        """
        Get DNS label of the key, seen from the parent zone

        Note that this method makes sense only KSKs.  For ZSKs use :py:attr:`label`.

        :returns: DNS formatted string of key name minus the parent's zone name
        :rtype: str
        """

        if self.key_type != "KSK":
            raise KeyException(
                "Key.parent_label makes sense only for KSK keys")

        if self.parent_zone is None:
            raise KeyException(
                "Parent zone is not set (key is stored outside NDNS)")

        name = self.name
        if name[:len(self.parent_zone)] == self.parent_zone:
            return dnsify(str(ndn.Name(name[len(self.parent_zone) + 1:-1])))
        else:
            raise KeyException("Key does not belong to the parent zone")
Ejemplo n.º 27
0
def get_candidates():
    keyLocator = request.form['keyLocator']
    timestamp = request.form['timestamp']
    signature = request.form['signature']

    query = \
        ndn.Name('/cert-requests/get') \
        .append(keyLocator) \
        .append(timestamp) \
        .append(base64.b64decode(signature))

    operator = mongo.db.operators.find_one({'site_prefix': keyLocator})
    if operator == None:
        abort(403)

    # do verification

    requests = mongo.db.requests.find({'operator_id': str(operator['_id'])})
    output = []
    for req in requests:
        output.append(req)

    # return json.dumps (output)
    return json.dumps(output, default=json_util.default)
Ejemplo n.º 28
0
    def verifyAsync(self, face, dataPacket, onVerify, limit_left=10):
        """
        onVerify: callback <void, dataPacket, status>
        """

        if limit_left <= 0:
            onVerify(dataPacket, False)
            return

        if len(self.anchors) == 0:
            onVerify(dataPacket, False)
            return

        if not face:
            face = ndn.Face()
            face.defer_verification(True)

        data_name = dataPacket.name
        key_name = dataPacket.signedInfo.keyLocator.keyName

        try:
            [key_data, ttl] = self.trustedCache[str(data_name)]
            if time.time() > ttl:
                del self.trustedCache[str(data_name)]
                raise KeyError()

            onVerify(dataPacket, True)
            return
        except KeyError:
            pass

        _LOG.debug("%s data [%s] signed by [%s]" %
                   ('--' * (11 - limit_left), data_name, key_name))

        anchor = self.authorize_by_anchor(data_name, key_name)
        if anchor:
            verified = dataPacket.verify_signature(anchor)
            if verified:
                _LOG.info("%s anchor OKs [%s] (**[%s]**)" %
                          ('--' * (11 - limit_left), data_name, key_name))
            else:
                _LOG.info("%s anchor FAILs [%s]" %
                          ('--' * (11 - limit_left), data_name))
            onVerify(dataPacket, verified)
            return

        if not self.authorize_by_rule(data_name, key_name):
            onVerify(dataPacket, False)
            return

        try:
            [key, ttl] = self.trustedCache[str(key_name)]
            if time.time() > ttl:
                del self.trustedCache[str(key_name)]
                raise KeyError()

            _LOG.info("%s Using cached trusted version of key [%s]" %
                      ('--' * (11 - limit_left), key_name))

            onVerify(dataPacket, dataPacket.verify_signature(key))
            return
        except KeyError:
            zone = ndn.Name()
            for comp in key_name:
                if comp == "DNS":
                    break
                zone = zone.append(comp)

            nextLevelProcessor = NextLevelProcessor(face, self, dataPacket,
                                                    onVerify, limit_left,
                                                    key_name)

            if comp != "DNS":
                face.expressInterest(key_name, nextLevelProcessor.onData,
                                     nextLevelProcessor.onTimeout)
            elif len(zone) == 0:
                self.cachingQuery.expressQueryForRaw(
                    face,
                    nextLevelProcessor.onKeyData,
                    nextLevelProcessor.onError,
                    key_name,
                    hint=None,
                    parse_dns=False,
                    limit_left=limit_left - 1)  #, verify = False)
            else:
                self.cachingQuery.expressQueryForZoneFh(
                    face,
                    nextLevelProcessor.onHintData,
                    nextLevelProcessor.onError,
                    zone,
                    verify=True)
Ejemplo n.º 29
0
def generate_names():
	names = ["/Hello", "/World", "/This", "/is", "/an", "/enumeration", "/example"]
	return map(lambda x: ndn.Name(x), names)
Ejemplo n.º 30
0
def extract_cert_name(name):
    # remove two last components and remove "KEY" keyword at any position
    return ndn.Name(
        [component for component in name[:-2] if str(component) != 'KEY'])