Beispiel #1
1
    def _set_tag(self, tag, value):
        assert isinstance(tag, unicode)
        assert tag in [u"store", u"ignore", u"drop"]
        assert isinstance(value, bool)
        if __debug__: dprint(tag, " -> ", value)
        if value:
            if tag in self._tags:
                # the tag is already set
                return False
            self._tags.append(tag)

        else:
            if not tag in self._tags:
                # the tag isn't there to begin with
                return False
            self._tags.remove(tag)

        # todo: at some point we may want to optimize this.  for now this is a feature that will
        # probably not be used often hence we leave it like this.
        with DispersyDatabase.get_instance() as database:
            tags = list(database.execute(u"SELECT key, value FROM tag"))
            int_tags = [0, 0] + [key for key, value in tags if value in self._tags]
            reduced = reduce(lambda a, b: a | b, int_tags)
            database.execute(u"UPDATE user SET tags = ? WHERE public_key = ?", (reduced, buffer(self._public_key),))
        return True
Beispiel #2
0
    def __init__(self, public_key, private_key=None, sync_with_database=True):
        assert isinstance(public_key, str)
        assert not public_key.startswith("-----BEGIN")
        assert isinstance(private_key, (type(None), str))
        assert private_key is None or not private_key.startswith("-----BEGIN")
        assert isinstance(sync_with_database, bool)

        if sync_with_database:
            if private_key is None:
                # get private key
                database = DispersyDatabase.get_instance()
                try:
                    private_key = str(database.execute(u"SELECT private_key FROM key WHERE public_key == ? LIMIT 1", (buffer(public_key),)).next()[0])
                except StopIteration:
                    pass

            else:
                # set private key
                database = DispersyDatabase.get_instance()
                database.execute(u"INSERT OR IGNORE INTO key(public_key, private_key) VALUES(?, ?)", (buffer(public_key), buffer(private_key)))

        if private_key is None:
            raise ValueError("The private key is unavailable")

        super(PrivateMember, self).__init__(public_key, ec_from_private_bin(private_key), sync_with_database)
        self._private_key = private_key
Beispiel #3
0
    def __init__(self, mid):
        assert isinstance(mid, str)
        assert len(mid) == 20
        self._mid = mid

        assert DispersyDatabase.has_instance(), "DispersyDatabase has not yet been created"
        database = DispersyDatabase.get_instance()

        if __debug__:
            # may only create a DummyMember when the public key is not available
            try:
                public_key, = database.execute(
                    u"SELECT public_key FROM member WHERE mid = ? LIMIT 1", (buffer(mid),)
                ).next()
                assert public_key is None
            except StopIteration:
                pass

        try:
            database_id, tags = database.execute(
                u"SELECT id, tags FROM member WHERE mid = ? LIMIT 1", (buffer(mid),)
            ).next()
        except StopIteration:
            database.execute(u"INSERT INTO member (mid) VALUES (?)", (buffer(mid),))
            database_id = database.last_insert_rowid
            tags = u""

        self._database_id = database_id
        self._mid = mid
Beispiel #4
0
    def update(self):
        """
        Update tags from the database.
        """
        execute = DispersyDatabase.get_instance().execute

        # set tags
        try:
            tags, = execute(u"SELECT tags FROM member WHERE id = ?", (self._database_id,)).next()
        except StopIteration:
            assert False, "should never occur"
        else:
            self._tags = [tag for tag in tags.split(",") if tag]
            if __debug__:
                assert len(set(self._tags)) == len(self._tags), ("there are duplicate tags", self._tags)
                for tag in self._tags:
                    assert tag in (u"store", u"ignore", u"blacklist"), tag

        for community_database_id, in execute(u"""
SELECT DISTINCT sync.community
FROM sync
JOIN meta_message ON meta_message.id = sync.meta_message
WHERE meta_message.name = \"dispersy-identity\" AND sync.member = ?
""", (self._database_id, )):
            self._communities.add(community_database_id)
Beispiel #5
0
 def members(self):
     # TODO we should not just trust this information, a member can put any address in their
     # dispersy-identity message.  The database should contain a column with a 'verified' flag.
     # This flag is only set when a handshake was successfull.
     return [Member.get_instance(str(public_key))
             for public_key,
             in list(DispersyDatabase.get_instance().execute(u"SELECT public_key FROM user WHERE host = ? AND port = ? -- AND verified = 1", (unicode(self._address[0]), self._address[1])))]
    def __init__(self, public_key, private_key = None, sync_with_database = True):
        if sync_with_database:
            if private_key is None:
                database = DispersyDatabase.get_instance()
                try:
                    private_key = str(database.execute(u'SELECT private_key FROM key WHERE public_key == ? LIMIT 1', (buffer(public_key),)).next()[0])
                except StopIteration:
                    pass

            else:
                database = DispersyDatabase.get_instance()
                database.execute(u'INSERT OR IGNORE INTO key(public_key, private_key) VALUES(?, ?)', (buffer(public_key), buffer(private_key)))
        if private_key is None:
            raise ValueError('The private key is unavailable')
        super(PrivateMember, self).__init__(public_key, ec_from_private_bin(private_key), sync_with_database)
        self._private_key = private_key
Beispiel #7
0
    def __init__(self, community, dispersy_version, community_version):
        """
        COMMUNITY instance that this conversion belongs to.
        DISPERSY_VERSION is the dispersy conversion identifier (on the wire version; must be one byte).
        COMMUNIY_VERSION is the community conversion identifier (on the wire version; must be one byte).

        COMMUNIY_VERSION may not be '\x00' or '\xff'.  '\x00' is used by the DefaultConversion until
        a proper conversion instance can be made for the Community.  '\xff' is reserved for when
        more than one byte is needed as a version indicator.
        """
        if __debug__: from community import Community
        assert isinstance(community, Community), type(community)
        assert isinstance(dispersy_version, str), type(dispersy_version)
        assert len(dispersy_version) == 1, dispersy_version
        assert isinstance(community_version, str), type(community_version)
        assert len(community_version) == 1, community_version

        # the dispersy database
        self._dispersy_database = DispersyDatabase.get_instance()

        # the community that this conversion belongs to.
        self._community = community

        # the messages that this instance can handle, and that this instance produces, is identified
        # by _prefix.
        self._prefix = dispersy_version + community_version + community.cid
        assert len(self._prefix) == 22 # when this assumption changes, we need to ensure the
Beispiel #8
0
    def __init__(self, public_key, private_key = None, sync_with_database = True):
        if sync_with_database:
            if private_key is None:
                database = DispersyDatabase.get_instance()
                try:
                    private_key = str(database.execute(u'SELECT private_key FROM key WHERE public_key == ? LIMIT 1', (buffer(public_key),)).next()[0])
                except StopIteration:
                    pass

            else:
                database = DispersyDatabase.get_instance()
                database.execute(u'INSERT OR IGNORE INTO key(public_key, private_key) VALUES(?, ?)', (buffer(public_key), buffer(private_key)))
        if private_key is None:
            raise ValueError('The private key is unavailable')
        super(PrivateMember, self).__init__(public_key, ec_from_private_bin(private_key), sync_with_database)
        self._private_key = private_key
Beispiel #9
0
    def __init__(self, mid):
        assert isinstance(mid, str)
        assert len(mid) == 20
        self._mid = mid

        assert DispersyDatabase.has_instance(), "DispersyDatabase has not yet been created"
        database = DispersyDatabase.get_instance()

        try:
            database_id, = database.execute(u"SELECT id FROM member WHERE mid = ? LIMIT 1", (buffer(mid),)).next()
        except StopIteration:
            database.execute(u"INSERT INTO member (mid) VALUES (?)", (buffer(mid),))
            database_id = database.last_insert_rowid

        self._database_id = database_id
        self._mid = mid
Beispiel #10
0
    def __init__(self, public_key, ec=None, sync_with_database=True):
        """
        Create a new Member instance.  Member instances must be reated or retrieved using
        has_instance or get_instance.

        PUBLIC_KEY must be a string giving the public EC key in DER format.  EC is an optional EC
        object (given when created from private key).
        """
        assert isinstance(public_key, str)
        assert not public_key.startswith("-----BEGIN")
        assert isinstance(sync_with_database, bool)
        self._public_key = public_key
        if ec is None:
            self._ec = ec_from_public_bin(public_key)
        else:
            self._ec = ec

        self._signature_length = ec_signature_length(self._ec)
        self._mid = sha1(public_key).digest()

        self._database_id = -1
        self._address = ("", -1)
        self._tags = []

        # sync with database
        if sync_with_database:
            if not self.update():
                database = DispersyDatabase.get_instance()
                database.execute(u"INSERT INTO user(mid, public_key) VALUES(?, ?)", (buffer(self._mid), buffer(self._public_key)))
                self._database_id = database.last_insert_rowid
Beispiel #11
0
    def __init__(self, mid):
        assert isinstance(mid, str)
        assert len(mid) == 20
        self._mid = mid

        assert DispersyDatabase.has_instance(
        ), "DispersyDatabase has not yet been created"
        database = DispersyDatabase.get_instance()

        try:
            database_id, = database.execute(
                u"SELECT id FROM member WHERE mid = ? LIMIT 1",
                (buffer(mid), )).next()
        except StopIteration:
            database.execute(u"INSERT INTO member (mid) VALUES (?)",
                             (buffer(mid), ))
            database_id = database.last_insert_rowid

        self._database_id = database_id
        self._mid = mid
Beispiel #12
0
 def update(self):
     try:
         execute = DispersyDatabase.get_instance().execute
         self._database_id, host, port, tags = execute(u'SELECT id, host, port, tags FROM user WHERE public_key = ? LIMIT 1', (buffer(self._public_key),)).next()
         self._address = (str(host), port)
         self._tags = []
         if tags:
             self._tags = list(execute(u'SELECT key FROM tag WHERE value & ?', (tags,)))
         return True
     except StopIteration:
         return False
 def update(self):
     try:
         execute = DispersyDatabase.get_instance().execute
         self._database_id, host, port, tags = execute(u'SELECT id, host, port, tags FROM user WHERE public_key = ? LIMIT 1', (buffer(self._public_key),)).next()
         self._address = (str(host), port)
         self._tags = []
         if tags:
             self._tags = list(execute(u'SELECT key FROM tag WHERE value & ?', (tags,)))
         return True
     except StopIteration:
         return False
Beispiel #14
0
 def _set_tag(self, tag, value):
     if value:
         if tag in self._tags:
             return False
         self._tags.append(tag)
     else:
         if tag not in self._tags:
             return False
         self._tags.remove(tag)
     with DispersyDatabase.get_instance() as execute:
         tags = list(execute(u'SELECT key, value FROM tag'))
         int_tags = [0, 0] + [ key for key, value in tags if value in self._tags ]
         reduced = reduce(lambda a, b: a | b, int_tags)
         execute(u'UPDATE user SET tags = ? WHERE public_key = ?', (reduced, buffer(self._public_key)))
     return True
 def _set_tag(self, tag, value):
     if value:
         if tag in self._tags:
             return False
         self._tags.append(tag)
     else:
         if tag not in self._tags:
             return False
         self._tags.remove(tag)
     with DispersyDatabase.get_instance() as execute:
         tags = list(execute(u'SELECT key, value FROM tag'))
         int_tags = [0, 0] + [ key for key, value in tags if value in self._tags ]
         reduced = reduce(lambda a, b: a | b, int_tags)
         execute(u'UPDATE user SET tags = ? WHERE public_key = ?', (reduced, buffer(self._public_key)))
     return True
Beispiel #16
0
 def __init__(self, public_key, ec = None, sync_with_database = True):
     self._public_key = public_key
     if ec is None:
         self._ec = ec_from_public_bin(public_key)
     else:
         self._ec = ec
     self._signature_length = ec_signature_length(self._ec)
     self._mid = sha1(public_key).digest()
     self._database_id = -1
     self._address = ('', -1)
     self._tags = []
     if sync_with_database:
         if not self.update():
             database = DispersyDatabase.get_instance()
             database.execute(u'INSERT INTO user(mid, public_key) VALUES(?, ?)', (buffer(self._mid), buffer(self._public_key)))
             self._database_id = database.last_insert_rowid
 def __init__(self, public_key, ec = None, sync_with_database = True):
     self._public_key = public_key
     if ec is None:
         self._ec = ec_from_public_bin(public_key)
     else:
         self._ec = ec
     self._signature_length = ec_signature_length(self._ec)
     self._mid = sha1(public_key).digest()
     self._database_id = -1
     self._address = ('', -1)
     self._tags = []
     if sync_with_database:
         if not self.update():
             database = DispersyDatabase.get_instance()
             database.execute(u'INSERT INTO user(mid, public_key) VALUES(?, ?)', (buffer(self._mid), buffer(self._public_key)))
             self._database_id = database.last_insert_rowid
Beispiel #18
0
    def _set_tag(self, tag, value):
        assert isinstance(tag, unicode)
        assert tag in [u"store", u"ignore", u"blacklist"]
        assert isinstance(value, bool)
        if __debug__: dprint(tag, " -> ", value)
        if value:
            if tag in self._tags:
                # the tag is already set
                return False
            self._tags.append(tag)

        else:
            if not tag in self._tags:
                # the tag isn't there to begin with
                return False
            self._tags.remove(tag)

        execute = DispersyDatabase.get_instance().execute
        execute(u"UPDATE member SET tags = ? WHERE id = ?", (u",".join(sorted(self._tags)), self._database_id))
        return True
Beispiel #19
0
    def __init__(self, public_key, private_key=""):
        """
        Create a new Member instance.
        """
        assert isinstance(public_key, str)
        assert isinstance(private_key, str)
        assert ec_check_public_bin(public_key), public_key.encode("HEX")
        assert private_key == "" or ec_check_private_bin(private_key), private_key.encode("HEX")

        if not hasattr(self, "_public_key"):
            assert DispersyDatabase.has_instance(), "DispersyDatabase has not yet been created"
            database = DispersyDatabase.get_instance()

            try:
                database_id, mid, tags, private_key_from_db = database.execute(
                    u"SELECT m.id, m.mid, m.tags, p.private_key FROM member AS m LEFT OUTER JOIN private_key AS p ON p.member = m.id WHERE m.public_key = ? LIMIT 1",
                    (buffer(public_key),),
                ).next()

            except StopIteration:
                mid = sha1(public_key).digest()
                private_key_from_db = None
                try:
                    database_id, tags = database.execute(
                        u"SELECT id, tags FROM member WHERE mid = ? LIMIT 1", (buffer(mid),)
                    ).next()

                except StopIteration:
                    database.execute(
                        u"INSERT INTO member (mid, public_key) VALUES (?, ?)", (buffer(mid), buffer(public_key))
                    )
                    database_id = database.last_insert_rowid
                    tags = u""

                else:
                    database.execute(
                        u"UPDATE member SET public_key = ? WHERE id = ?", (buffer(public_key), database_id)
                    )

            else:
                mid = str(mid)
                private_key_from_db = str(private_key_from_db) if private_key_from_db else ""
                assert private_key_from_db == "" or ec_check_private_bin(
                    private_key_from_db
                ), private_key_from_db.encode("HEX")

            if private_key_from_db:
                private_key = private_key_from_db
            elif private_key:
                database.execute(
                    u"INSERT INTO private_key (member, private_key) VALUES (?, ?)", (database_id, buffer(private_key))
                )

            self._database = database
            self._database_id = database_id
            self._mid = mid
            self._public_key = public_key
            self._private_key = private_key
            self._ec = ec_from_private_bin(private_key) if private_key else ec_from_public_bin(public_key)
            self._signature_length = ec_signature_length(self._ec)
            self._tags = [tag for tag in tags.split(",") if tag]
            self._has_identity = set()

            if __debug__:
                assert len(set(self._tags)) == len(self._tags), ("there are duplicate tags", self._tags)
                for tag in self._tags:
                    assert tag in (u"store", u"ignore", u"blacklist"), tag

            if __debug__:
                dprint(
                    "mid:",
                    self._mid.encode("HEX"),
                    " db:",
                    self._database_id,
                    " public:",
                    bool(self._public_key),
                    " private:",
                    bool(self._private_key),
                )
Beispiel #20
0
    def __init__(self, public_key, private_key=""):
        """
        Create a new Member instance.
        """
        assert isinstance(public_key, str)
        assert isinstance(private_key, str)
        assert ec_check_public_bin(public_key), public_key.encode("HEX")
        assert private_key == "" or ec_check_private_bin(
            private_key), private_key.encode("HEX")

        if not hasattr(self, "_public_key"):
            assert DispersyDatabase.has_instance(
            ), "DispersyDatabase has not yet been created"
            database = DispersyDatabase.get_instance()

            try:
                database_id, mid, tags, private_key_from_db = database.execute(
                    u"SELECT m.id, m.mid, m.tags, p.private_key FROM member AS m LEFT OUTER JOIN private_key AS p ON p.member = m.id WHERE m.public_key = ? LIMIT 1",
                    (buffer(public_key), )).next()

            except StopIteration:
                mid = sha1(public_key).digest()
                private_key_from_db = None
                try:
                    database_id, tags = database.execute(
                        u"SELECT id, tags FROM member WHERE mid = ? LIMIT 1",
                        (buffer(mid), )).next()

                except StopIteration:
                    database.execute(
                        u"INSERT INTO member (mid, public_key) VALUES (?, ?)",
                        (buffer(mid), buffer(public_key)))
                    database_id = database.last_insert_rowid
                    tags = u""

                else:
                    database.execute(
                        u"UPDATE member SET public_key = ? WHERE id = ?",
                        (buffer(public_key), database_id))

            else:
                mid = str(mid)
                private_key_from_db = str(
                    private_key_from_db) if private_key_from_db else ""
                assert private_key_from_db == "" or ec_check_private_bin(
                    private_key_from_db), private_key_from_db.encode("HEX")

            if private_key_from_db:
                private_key = private_key_from_db
            elif private_key:
                database.execute(
                    u"INSERT INTO private_key (member, private_key) VALUES (?, ?)",
                    (database_id, buffer(private_key)))

            self._database = database
            self._database_id = database_id
            self._mid = mid
            self._public_key = public_key
            self._private_key = private_key
            self._ec = ec_from_private_bin(
                private_key) if private_key else ec_from_public_bin(public_key)
            self._signature_length = ec_signature_length(self._ec)
            self._tags = [tag for tag in tags.split(",") if tag]
            self._has_identity = set()

            if __debug__:
                assert len(set(self._tags)) == len(
                    self._tags), ("there are duplicate tags", self._tags)
                for tag in self._tags:
                    assert tag in (u"store", u"ignore", u"blacklist"), tag

            if __debug__:
                dprint("mid:", self._mid.encode("HEX"),
                       " db:", self._database_id, " public:",
                       bool(self._public_key), " private:",
                       bool(self._private_key))
Beispiel #21
0
    def __init__(self, public_key, private_key="", sync_with_database=True, public_key_available=True):
        """
        Create a new Member instance.  Member instances must be reated or retrieved using
        has_instance or get_instance.

        To create a Member instance we either need a public_key or a mid.  If only the mid is
        available it must be given as the public_key parameter and public_key_available must be
        False.  In this case the member will be unable to verify or sign data.

        Also not that it is possible, however unlikely, that someone is able to find another member
        with the same mid.  This will cause conflicts until the public_key is available.
        """
        assert isinstance(public_key, str)
        assert isinstance(private_key, str)
        assert isinstance(sync_with_database, bool)
        assert isinstance(public_key_available, bool)
        assert (public_key_available and len(public_key) > 0 and not public_key.startswith("-----BEGIN")) or \
               (not public_key_available and len(public_key) == 20), (len(public_key), public_key_available, public_key.encode("HEX"))
        assert (public_key_available and len(private_key) > 0 and not private_key.startswith("-----BEGIN")) or len(private_key) == 0

        assert DispersyDatabase.has_instance(), "DispersyDatabase has not yet been created"
        database = DispersyDatabase.get_instance()

        if hasattr(self, "_database_id"):
            #
            # singleton already exists.  we may have received a public or private key now, so update
            # those in the database is needed
            #
            if __debug__: dprint("continue with existing singleton", force=1)

            if public_key_available:
                assert self._public_key == "" or self._public_key == public_key
                assert self._private_key == "" or self._private_key == private_key

                if not self._public_key:
                    assert public_key
                    assert ec_check_public_bin(public_key), public_key.encode("HEX")
                    self._public_key = public_key
                    if sync_with_database:
                        database.execute(u"UPDATE member SET public_key = ? WHERE id = ?", (buffer(public_key), self._database_id))

                if not self._private_key and private_key:
                    assert private_key
                    assert ec_check_private_bin(private_key), private_key.encode("HEX")
                    self._private_key = private_key
                    if sync_with_database:
                        database.execute(u"UPDATE private_key SET private_key = ? WHERE member = ?", (buffer(private_key), self._database_id))

                self._ec = ec_from_private_bin(self._private_key) if self._private_key else ec_from_public_bin(self._public_key)
                self._signature_length = ec_signature_length(self._ec)

            else:
                # we have nothing new
                pass

        else:
            #
            # singleton did not exist.  we make a new one
            #
            if public_key_available:
                assert public_key
                assert ec_check_public_bin(public_key), public_key.encode("HEX")
                assert not private_key or ec_check_private_bin(private_key), private_key.encode("HEX")
                self._public_key = public_key
                self._private_key = private_key
                self._mid = sha1(public_key).digest()
                self._database_id = -1
                self._communities = set()
                self._tags = []

                if sync_with_database:
                    try:
                        self._database_id, private_key = database.execute(u"SELECT m.id, p.private_key FROM member AS m LEFT OUTER JOIN private_key AS p ON p.member = m.id WHERE m.public_key = ? LIMIT 1",
                                                                 (buffer(self._public_key),)).next()
                    except StopIteration:
                        # TODO check if there is a member already in the database where we only had
                        # the MID

                        database.execute(u"INSERT INTO member(mid, public_key) VALUES(?, ?)", (buffer(self._mid), buffer(self._public_key)))
                        self._database_id = database.last_insert_rowid

                        if self._private_key:
                            database.execute(u"INSERT INTO private_key(member, private_key) VALUES(?, ?)", (self._database_id, buffer(self._private_key)))

                    else:
                        if not self._private_key and private_key:
                            self._private_key = str(private_key)

                self._ec = ec_from_private_bin(self._private_key) if self._private_key else ec_from_public_bin(self._public_key)
                self._signature_length = ec_signature_length(self._ec)

            else:
                assert len(public_key) == 20, public_key.encode("HEX")
                self._public_key = ""
                self._private_key = ""
                self._mid = public_key
                self._database_id = -1
                self._communities = set()
                self._tags = []

                if sync_with_database:
                    try:
                        # # TODO do something smart to select the right mid (multiple can exist...)
                        self._database_id, = database.execute(u"SELECT id FROM member WHERE mid = ? LIMIT 1",
                                                              (buffer(self._mid),)).next()
                    except StopIteration:
                        database.execute(u"INSERT INTO member(mid) VALUES(?)", (buffer(self._mid),))
                        self._database_id = database.last_insert_rowid

                self._ec = None
                self._signature_length = 0

        if sync_with_database:
            self.update()

        if __debug__: dprint("mid:", self._mid.encode("HEX"), " db:", self._database_id, " public:", bool(self._public_key), " private:", bool(self._private_key), " from-public:", public_key_available)