Exemple #1
0
    def test_sign(self):
        ann = {"key1": "value1"}
        sk_s, vk_s = keyutil.make_keypair()
        sk, ignored = keyutil.parse_privkey(sk_s)
        ann_t = sign_to_foolscap(ann, sk)
        (msg, sig, key) = ann_t
        self.failUnlessEqual(type(msg), type("".encode("utf-8")))  # bytes
        self.failUnlessEqual(simplejson.loads(msg.decode("utf-8")), ann)
        self.failUnless(sig.startswith("v0-"))
        self.failUnless(key.startswith("v0-"))
        (ann2, key2) = unsign_from_foolscap(ann_t)
        self.failUnlessEqual(ann2, ann)
        self.failUnlessEqual("pub-" + key2, vk_s)

        # bad signature
        bad_ann = {"key1": "value2"}
        bad_msg = simplejson.dumps(bad_ann).encode("utf-8")
        self.failUnlessRaises(keyutil.BadSignatureError, unsign_from_foolscap,
                              (bad_msg, sig, key))
        # sneaky bad signature should be ignored
        (ann2, key2) = unsign_from_foolscap((bad_msg, None, key))
        self.failUnlessEqual(key2, None)
        self.failUnlessEqual(ann2, bad_ann)

        # unrecognized signatures
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (bad_msg, "v999-sig", key))
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (bad_msg, sig, "v999-key"))
    def test_sign(self):
        ann = {"key1": "value1"}
        sk_s,vk_s = keyutil.make_keypair()
        sk,ignored = keyutil.parse_privkey(sk_s)
        ann_t = sign_to_foolscap(ann, sk)
        (msg, sig, key) = ann_t
        self.failUnlessEqual(type(msg), type("".encode("utf-8"))) # bytes
        self.failUnlessEqual(simplejson.loads(msg.decode("utf-8")), ann)
        self.failUnless(sig.startswith("v0-"))
        self.failUnless(key.startswith("v0-"))
        (ann2,key2) = unsign_from_foolscap(ann_t)
        self.failUnlessEqual(ann2, ann)
        self.failUnlessEqual("pub-"+key2, vk_s)

        # bad signature
        bad_ann = {"key1": "value2"}
        bad_msg = simplejson.dumps(bad_ann).encode("utf-8")
        self.failUnlessRaises(keyutil.BadSignatureError,
                              unsign_from_foolscap, (bad_msg,sig,key))
        # sneaky bad signature should be ignored
        (ann2,key2) = unsign_from_foolscap( (bad_msg,None,key) )
        self.failUnlessEqual(key2, None)
        self.failUnlessEqual(ann2, bad_ann)

        # unrecognized signatures
        self.failUnlessRaises(UnknownKeyError,
                              unsign_from_foolscap, (bad_msg,"v999-sig",key))
        self.failUnlessRaises(UnknownKeyError,
                              unsign_from_foolscap, (bad_msg,sig,"v999-key"))
Exemple #3
0
    def test_sign(self):
        ann = {"key1": "value1"}
        private_key, public_key = ed25519.create_signing_keypair()
        public_key_str = ed25519.string_from_verifying_key(public_key)
        ann_t = sign_to_foolscap(ann, private_key)
        (msg, sig, key) = ann_t
        self.failUnlessEqual(type(msg), type("".encode("utf-8")))  # bytes
        self.failUnlessEqual(json.loads(msg.decode("utf-8")), ann)
        self.failUnless(sig.startswith("v0-"))
        self.failUnless(key.startswith("v0-"))
        (ann2, key2) = unsign_from_foolscap(ann_t)
        self.failUnlessEqual(ann2, ann)
        self.failUnlessEqual("pub-" + key2, public_key_str)

        # not signed
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (msg, None, key))
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (msg, sig, None))
        # bad signature
        bad_ann = {"key1": "value2"}
        bad_msg = json.dumps(bad_ann).encode("utf-8")
        self.failUnlessRaises(BadSignature, unsign_from_foolscap,
                              (bad_msg, sig, key))

        # unrecognized signatures
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (bad_msg, "v999-sig", key))
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (bad_msg, sig, "v999-key"))
Exemple #4
0
    def _publish(self, ann_t, canary, lp):
        self._debug_counts["inbound_message"] += 1
        self.log("introducer: announcement published: %s" % (ann_t, ),
                 umid="wKHgCw")
        ann, key = unsign_from_foolscap(ann_t)  # might raise BadSignature
        service_name = str(ann["service-name"])

        index = (service_name, key)
        old = self._announcements.get(index)
        if old:
            (old_ann_t, canary, old_ann, timestamp) = old
            if old_ann == ann:
                self.log("but we already knew it, ignoring",
                         level=log.NOISY,
                         umid="myxzLw")
                self._debug_counts["inbound_duplicate"] += 1
                return
            else:
                if "seqnum" in old_ann:
                    # must beat previous sequence number to replace
                    if ("seqnum" not in ann
                            or not isinstance(ann["seqnum"], (int, long))):
                        self.log("not replacing old ann, no valid seqnum",
                                 level=log.NOISY,
                                 umid="ySbaVw")
                        self._debug_counts["inbound_no_seqnum"] += 1
                        return
                    if ann["seqnum"] <= old_ann["seqnum"]:
                        self.log("not replacing old ann, new seqnum is too old"
                                 " (%s <= %s) (replay attack?)" %
                                 (ann["seqnum"], old_ann["seqnum"]),
                                 level=log.UNUSUAL,
                                 umid="sX7yqQ")
                        self._debug_counts["inbound_old_replay"] += 1
                        return
                    # ok, seqnum is newer, allow replacement
                self.log("old announcement being updated",
                         level=log.NOISY,
                         umid="304r9g")
                self._debug_counts["inbound_update"] += 1
        self._announcements[index] = (ann_t, canary, ann, time.time())
        #if canary:
        #    canary.notifyOnDisconnect ...
        # use a CanaryWatcher? with cw.is_connected()?
        # actually we just want foolscap to give rref.is_connected(), since
        # this is only for the status display

        for s in self._subscribers.get(service_name, []):
            self._debug_counts["outbound_message"] += 1
            self._debug_counts["outbound_announcements"] += 1
            self._debug_outstanding += 1
            d = s.callRemote("announce_v2", set([ann_t]))
            d.addBoth(self._debug_retired)
            d.addErrback(log.err,
                         format="subscriber errored on announcement %(ann)s",
                         ann=ann_t,
                         facility="tahoe.introducer",
                         level=log.UNUSUAL,
                         umid="jfGMXQ")
Exemple #5
0
    def _publish(self, ann_t, canary, lp):
        self._debug_counts["inbound_message"] += 1
        self.log("introducer: announcement published: %s" % (ann_t,), umid="wKHgCw")
        ann, key = unsign_from_foolscap(ann_t)  # might raise BadSignatureError
        index = make_index(ann, key)

        service_name = str(ann["service-name"])
        if service_name == "stub_client":  # for_v1
            self._attach_stub_client(ann, lp)
            return

        old = self._announcements.get(index)
        if old:
            (old_ann_t, canary, old_ann, timestamp) = old
            if old_ann == ann:
                self.log("but we already knew it, ignoring", level=log.NOISY, umid="myxzLw")
                self._debug_counts["inbound_duplicate"] += 1
                return
            else:
                if "seqnum" in old_ann:
                    # must beat previous sequence number to replace
                    if "seqnum" not in ann:
                        self.log("not replacing old ann, no seqnum", level=log.NOISY, umid="ySbaVw")
                        self._debug_counts["inbound_no_seqnum"] += 1
                        return
                    if ann["seqnum"] <= old_ann["seqnum"]:
                        self.log(
                            "not replacing old ann, new seqnum is too old"
                            " (%s <= %s) (replay attack?)" % (ann["seqnum"], old_ann["seqnum"]),
                            level=log.UNUSUAL,
                            umid="sX7yqQ",
                        )
                        self._debug_counts["inbound_old_replay"] += 1
                        return
                    # ok, seqnum is newer, allow replacement
                self.log("old announcement being updated", level=log.NOISY, umid="304r9g")
                self._debug_counts["inbound_update"] += 1
        self._announcements[index] = (ann_t, canary, ann, time.time())
        # if canary:
        #    canary.notifyOnDisconnect ...
        # use a CanaryWatcher? with cw.is_connected()?
        # actually we just want foolscap to give rref.is_connected(), since
        # this is only for the status display

        for s in self._subscribers.get(service_name, []):
            self._debug_counts["outbound_message"] += 1
            self._debug_counts["outbound_announcements"] += 1
            self._debug_outstanding += 1
            d = s.callRemote("announce_v2", set([ann_t]))
            d.addBoth(self._debug_retired)
            d.addErrback(
                log.err,
                format="subscriber errored on announcement %(ann)s",
                ann=ann_t,
                facility="tahoe.introducer",
                level=log.UNUSUAL,
                umid="jfGMXQ",
            )
Exemple #6
0
    def got_announcements(self, announcements, lp=None):
        self._debug_counts["inbound_message"] += 1
        for ann_t in announcements:
            try:
                # this might raise UnknownKeyError or bad-sig error
                ann, key_s = unsign_from_foolscap(ann_t)
                # key is "v0-base32abc123"
            except BadSignatureError:
                self.log("bad signature on inbound announcement: %s" % (ann_t,),
                         parent=lp, level=log.WEIRD, umid="ZAU15Q")
                # process other announcements that arrived with the bad one
                continue

            self._process_announcement(ann, key_s)
Exemple #7
0
    def got_announcements(self, announcements, lp=None):
        self._debug_counts["inbound_message"] += 1
        for ann_t in announcements:
            try:
                # this might raise UnknownKeyError or bad-sig error
                ann, key_s = unsign_from_foolscap(ann_t)
                # key is "v0-base32abc123"
                precondition(isinstance(key_s, str), key_s)
            except BadSignatureError:
                self.log("bad signature on inbound announcement: %s" % (ann_t,),
                         parent=lp, level=log.WEIRD, umid="ZAU15Q")
                # process other announcements that arrived with the bad one
                continue

            self._process_announcement(ann, key_s)
Exemple #8
0
    def _publish(self, ann_t, canary, lp):
        self._debug_counts["inbound_message"] += 1
        self.log("introducer: announcement published: %s" % (ann_t, ),
                 umid="wKHgCw")
        ann, key = unsign_from_foolscap(ann_t)  # might raise BadSignatureError
        index = make_index(ann, key)

        service_name = str(ann["service-name"])
        if service_name == "stub_client":  # for_v1
            self._attach_stub_client(ann, lp)
            return

        old = self._announcements.get(index)
        if old:
            (old_ann_t, canary, old_ann, timestamp) = old
            if old_ann == ann:
                self.log("but we already knew it, ignoring",
                         level=log.NOISY,
                         umid="myxzLw")
                self._debug_counts["inbound_duplicate"] += 1
                return
            else:
                self.log("old announcement being updated",
                         level=log.NOISY,
                         umid="304r9g")
                self._debug_counts["inbound_update"] += 1
        self._announcements[index] = (ann_t, canary, ann, time.time())
        #if canary:
        #    canary.notifyOnDisconnect ...
        # use a CanaryWatcher? with cw.is_connected()?
        # actually we just want foolscap to give rref.is_connected(), since
        # this is only for the status display

        for s in self._subscribers.get(service_name, []):
            self._debug_counts["outbound_message"] += 1
            self._debug_counts["outbound_announcements"] += 1
            self._debug_outstanding += 1
            d = s.callRemote("announce_v2", set([ann_t]))
            d.addBoth(self._debug_retired)
            d.addErrback(log.err,
                         format="subscriber errored on announcement %(ann)s",
                         ann=ann_t,
                         facility="tahoe.introducer",
                         level=log.UNUSUAL,
                         umid="jfGMXQ")