コード例 #1
0
ファイル: bridge_client.py プロジェクト: Achilles-96/dtella
    def verifySignature(self, rsa_obj, data, sig, broadcast):
        # 0:2 = kind
        # 2:8 = neighbor ipp
        # 8:9 = hop limit
        # 9:10 = flags
        # 10:16 = source ipp
        # 16: = "the rest"

        if not rsa_obj:
            return False

        # Grab the kind, skip over the header, and get everything up
        # to but not including the signature.
        if broadcast:
            body = data[0:2] + data[10:-len(sig)]
        else:
            body = data[:-len(sig)]

        data_hash = md5(body).digest()
        sig_tuple = (bytes_to_long(sig),)

        try:
            return rsa_obj.verify(data_hash, sig_tuple)
        except:
            return False
コード例 #2
0
    def verifySignature(self, rsa_obj, data, sig, broadcast):
        # 0:2 = kind
        # 2:8 = neighbor ipp
        # 8:9 = hop limit
        # 9:10 = flags
        # 10:16 = source ipp
        # 16: = "the rest"

        if not rsa_obj:
            return False

        # Grab the kind, skip over the header, and get everything up
        # to but not including the signature.
        if broadcast:
            body = data[0:2] + data[10:-len(sig)]
        else:
            body = data[:-len(sig)]

        data_hash = md5(body).digest()
        sig_tuple = (bytes_to_long(sig), )

        try:
            return rsa_obj.verify(data_hash, sig_tuple)
        except:
            return False
コード例 #3
0
        def check_cb(src_n, src_ipp, rest):

            (pktnum, expire, sesid, uptime, flags,
             rest) = self.decodePacket('!QH4sIB+', rest)

            persist = bool(flags & core.PERSIST_BIT)

            (hashes, rest) = self.decodeString1(rest, 16)

            hashes = [h for h, in self.decodeChunkList('!16s', hashes)]

            (pubkey, signature) = self.decodeString2(rest)

            if not (expire <= 30 * 60):
                raise BadPacketError("Expire time out of range")

            # If the signed message is too old, discard it.
            if osm.bcm.signatureExpired(pktnum):
                raise BadBroadcast

            # If we've received a newer status update, then this is useless.
            if self.isOutdatedBridgeStatus(src_n, pktnum):
                raise BadBroadcast

            # Make sure public key matches a hash in DNS
            pkhash = md5(pubkey).digest()
            if pkhash not in self.main.state.dns_pkhashes:
                # Not useful to me, but still forward it
                return

            # Generate RSA object from public key
            try:
                rsa_obj = RSA.construct((bytes_to_long(pubkey), 65537L))
            except:
                return

            # Verify signature
            if not self.verifySignature(
                    rsa_obj, data, signature, broadcast=True):
                # Useless...
                raise BadBroadcast

            # Keep track of the timestamp
            osm.bcm.updateBridgeTime(pktnum)

            # Update basic status
            n = osm.refreshNodeStatus(src_ipp, None, expire, sesid, uptime,
                                      persist, '', '')

            # Update bridge-specific status
            osm.bcm.refreshBridgeNodeStatus(n,
                                            pktnum,
                                            rsa_obj,
                                            hashes,
                                            do_request=False)
コード例 #4
0
ファイル: bridge_client.py プロジェクト: Achilles-96/dtella
        def check_cb(src_n, src_ipp, rest):

            (pktnum, expire, sesid, uptime, flags, rest
             ) = self.decodePacket('!QH4sIB+', rest)

            persist = bool(flags & core.PERSIST_BIT)

            (hashes, rest
             ) = self.decodeString1(rest, 16)
            
            hashes = [h for h, in self.decodeChunkList('!16s', hashes)]

            (pubkey, signature
             ) = self.decodeString2(rest)

            if not (expire <= 30*60):
                raise BadPacketError("Expire time out of range")

            # If the signed message is too old, discard it.
            if osm.bcm.signatureExpired(pktnum):
                raise BadBroadcast

            # If we've received a newer status update, then this is useless.
            if self.isOutdatedBridgeStatus(src_n, pktnum):
                raise BadBroadcast

            # Make sure public key matches a hash in DNS
            pkhash = md5(pubkey).digest()
            if pkhash not in self.main.state.dns_pkhashes:
                # Not useful to me, but still forward it
                return

            # Generate RSA object from public key
            try:
                rsa_obj = RSA.construct((bytes_to_long(pubkey), 65537L))
            except:
                return

            # Verify signature
            if not self.verifySignature(
                rsa_obj, data, signature, broadcast=True):
                # Useless...
                raise BadBroadcast

            # Keep track of the timestamp
            osm.bcm.updateBridgeTime(pktnum)

            # Update basic status
            n = osm.refreshNodeStatus(
                src_ipp, None, expire, sesid, uptime, persist, '', '')

            # Update bridge-specific status
            osm.bcm.refreshBridgeNodeStatus(
                n, pktnum, rsa_obj, hashes, do_request=False)
コード例 #5
0
ファイル: crypto.py プロジェクト: tanmaysahay94/dtella
    def encrypt(self, data):
        # AES requires packets in blocks of 16 bytes so pad the packet with
        # its MD5 hash.  We need a minimum of 5 hash bytes.
        # There's also 1 byte at the end to store the hash length

        hlen = ((10 - len(data)) % 16) + 5

        h = md5(data).digest()[:hlen] + '\0' * (hlen - 16)

        data += h + chr(hlen)

        return self.aes.encrypt(data)
コード例 #6
0
ファイル: crypto.py プロジェクト: Achilles-96/dtella
    def encrypt(self, data):
        # AES requires packets in blocks of 16 bytes so pad the packet with
        # its MD5 hash.  We need a minimum of 5 hash bytes.
        # There's also 1 byte at the end to store the hash length
        
        hlen = ((10-len(data)) % 16) + 5

        h = md5(data).digest()[:hlen] + '\0'*(hlen-16)

        data += h + chr(hlen)

        return self.aes.encrypt(data)
コード例 #7
0
ファイル: bridge_server.py プロジェクト: Achilles-96/dtella
    def signPacket(self, packet, broadcast):
        data = ''.join(packet)

        if broadcast:
            body = data[0:2] + data[10:]
        else:
            body = data

        data_hash = md5(body).digest()

        t = time.time()
        sig, = self.rsa_obj.sign(data_hash, None)
        LOG.debug("Sign Time = %f sec" % (time.time() - t))

        packet.append(long_to_bytes(sig))
コード例 #8
0
    def signPacket(self, packet, broadcast):
        data = ''.join(packet)

        if broadcast:
            body = data[0:2] + data[10:]
        else:
            body = data

        data_hash = md5(body).digest()

        t = time.time()
        sig, = self.rsa_obj.sign(data_hash, None)
        LOG.debug("Sign Time = %f sec" % (time.time() - t))

        packet.append(long_to_bytes(sig))
コード例 #9
0
    def handleDataBlock(self, ipp, data):
        # Call this when a data block arrives from the network

        osm = self.main.osm

        bhash = md5(data).digest()
        key = (ipp, bhash)

        try:
            bdata = osm.lookup_ipp[ipp].bridge_data
            if not bdata:
                raise KeyError
        except KeyError:
            self.addUnclaimedDataBlock(key, data)
        else:
            if not bdata.addDataBlock(bhash, data):
                self.addUnclaimedDataBlock(key, data)
コード例 #10
0
ファイル: bridge_client.py プロジェクト: Achilles-96/dtella
    def handleDataBlock(self, ipp, data):
        # Call this when a data block arrives from the network

        osm = self.main.osm

        bhash = md5(data).digest()
        key = (ipp, bhash)

        try:
            bdata = osm.lookup_ipp[ipp].bridge_data
            if not bdata:
                raise KeyError
        except KeyError:
            self.addUnclaimedDataBlock(key, data)
        else:
            if not bdata.addDataBlock(bhash, data):
                self.addUnclaimedDataBlock(key, data)
コード例 #11
0
ファイル: crypto.py プロジェクト: Achilles-96/dtella
    def decrypt(self, data):
        if not (data and len(data) % 16 == 0):
            raise ValueError("Bad Length")

        data = self.aes.decrypt(data)

        hlen = ord(data[-1])

        if not (5 <= hlen < len(data)):
            raise ValueError("Bad Hash Length")

        h = data[-(hlen+1):-1][:16]
        data = data[:-(hlen+1)]

        if h != md5(data).digest()[:hlen]:
            raise ValueError("Bad Hash Value")

        return data
コード例 #12
0
ファイル: crypto.py プロジェクト: tanmaysahay94/dtella
    def decrypt(self, data):
        if not (data and len(data) % 16 == 0):
            raise ValueError("Bad Length")

        data = self.aes.decrypt(data)

        hlen = ord(data[-1])

        if not (5 <= hlen < len(data)):
            raise ValueError("Bad Hash Length")

        h = data[-(hlen + 1):-1][:16]
        data = data[:-(hlen + 1)]

        if h != md5(data).digest()[:hlen]:
            raise ValueError("Bad Hash Value")

        return data
コード例 #13
0
ファイル: crypto.py プロジェクト: Achilles-96/dtella
 def __init__(self, key):
     self.aes = AES.new(md5(key).digest())
コード例 #14
0
ファイル: crypto.py プロジェクト: tanmaysahay94/dtella
 def __init__(self, key):
     self.aes = AES.new(md5(key).digest())
コード例 #15
0
ファイル: bridge_client.py プロジェクト: Achilles-96/dtella
    def handlePacket_bY(self, ad, data):
        # Bridge Sync Reply

        osm = self.main.osm
        if not osm:
            raise BadTimingError("Not ready for bridge sync reply")

        (kind, src_ipp, pktnum, expire, sesid, uptime, flags, rest
         ) = self.decodePacket('!2s6sQH4sIB+', data)

        self.checkSource(src_ipp, ad, exempt_ip=True)

        persist = bool(flags & core.PERSIST_BIT)

        (hashes, rest
         ) = self.decodeString1(rest, 16)
        
        hashes = [h for h, in self.decodeChunkList('!16s', hashes)]

        (pubkey, rest
         ) = self.decodeString2(rest)

        c_nbs, rest = self.decodeNodeList(rest)
        u_nbs, rest = self.decodeNodeList(rest)

        signature = rest

        if not (expire <= 30*60):
            raise BadPacketError("Expire time out of range")

        class Skip(Exception):
            pass

        try:
            # If the signed message is too old, discard it.
            if osm.bcm.signatureExpired(pktnum):
                raise Skip

            # If we've received a newer status update, then this is useless.
            try:
                n = osm.lookup_ipp[src_ipp]
            except KeyError:
                pass
            else:
                if self.isOutdatedBridgeStatus(n, pktnum):
                    raise Skip

            # Make sure public key matches a hash in DNS
            pkhash = md5(pubkey).digest()
            if pkhash not in self.main.state.dns_pkhashes:
                raise Skip

            # Generate RSA object from public key
            try:
                rsa_obj = RSA.construct((bytes_to_long(pubkey), 65537L))
            except:
                raise Skip

            # Verify signature
            if not self.verifySignature(
                rsa_obj, data, signature, broadcast=False):
                raise Skip

            # Keep track of the timestamp
            osm.bcm.updateBridgeTime(pktnum)

            # Update basic status
            n = osm.refreshNodeStatus(
                src_ipp, None, expire, sesid, uptime, persist, '', '')

            # Update bridge-specific status
            osm.bcm.refreshBridgeNodeStatus(
                n, pktnum, rsa_obj, hashes, do_request=True)

        except Skip:
            pass

        # Process the sync reply
        if osm.sm:
            osm.sm.receivedSyncReply(src_ipp, c_nbs, u_nbs)
コード例 #16
0
    def handlePacket_bY(self, ad, data):
        # Bridge Sync Reply

        osm = self.main.osm
        if not osm:
            raise BadTimingError("Not ready for bridge sync reply")

        (kind, src_ipp, pktnum, expire, sesid, uptime, flags,
         rest) = self.decodePacket('!2s6sQH4sIB+', data)

        self.checkSource(src_ipp, ad, exempt_ip=True)

        persist = bool(flags & core.PERSIST_BIT)

        (hashes, rest) = self.decodeString1(rest, 16)

        hashes = [h for h, in self.decodeChunkList('!16s', hashes)]

        (pubkey, rest) = self.decodeString2(rest)

        c_nbs, rest = self.decodeNodeList(rest)
        u_nbs, rest = self.decodeNodeList(rest)

        signature = rest

        if not (expire <= 30 * 60):
            raise BadPacketError("Expire time out of range")

        class Skip(Exception):
            pass

        try:
            # If the signed message is too old, discard it.
            if osm.bcm.signatureExpired(pktnum):
                raise Skip

            # If we've received a newer status update, then this is useless.
            try:
                n = osm.lookup_ipp[src_ipp]
            except KeyError:
                pass
            else:
                if self.isOutdatedBridgeStatus(n, pktnum):
                    raise Skip

            # Make sure public key matches a hash in DNS
            pkhash = md5(pubkey).digest()
            if pkhash not in self.main.state.dns_pkhashes:
                raise Skip

            # Generate RSA object from public key
            try:
                rsa_obj = RSA.construct((bytes_to_long(pubkey), 65537L))
            except:
                raise Skip

            # Verify signature
            if not self.verifySignature(
                    rsa_obj, data, signature, broadcast=False):
                raise Skip

            # Keep track of the timestamp
            osm.bcm.updateBridgeTime(pktnum)

            # Update basic status
            n = osm.refreshNodeStatus(src_ipp, None, expire, sesid, uptime,
                                      persist, '', '')

            # Update bridge-specific status
            osm.bcm.refreshBridgeNodeStatus(n,
                                            pktnum,
                                            rsa_obj,
                                            hashes,
                                            do_request=True)

        except Skip:
            pass

        # Process the sync reply
        if osm.sm:
            osm.sm.receivedSyncReply(src_ipp, c_nbs, u_nbs)
コード例 #17
0
ファイル: unreal.py プロジェクト: pinkeshbadjatiya/dtella
 def md5(self, in_str):
     return md5(in_str).digest()
コード例 #18
0
ファイル: push_dconfig.py プロジェクト: infinity0/dtella
    def getEntries(self):
        # Build and return a dict of entries which should be sent to the
        # dynamic config store.

        def b64(arg):
            return binascii.b2a_base64(arg).rstrip()

        # Dictionary of key=value pairs to return.
        # Start out with the static entries provided in the config.
        entries = cfg.dconfig_fixed_entries.copy()

        osm = self.main.osm

        # Generate public key hash
        if cfg.private_key:
            pubkey = long_to_bytes(RSA.construct(cfg.private_key).n)
            entries['pkhash'] = b64(md5(pubkey).digest())

        # Collect IPPs for the ipcache string
        GOAL = 10
        ipps = set()

        # Initially add all the exempt IPs, without a port
        for ip in self.main.state.exempt_ips:
            ad = Ad()
            ad.ip = ip
            ad.port = 0
            ipps.add(ad.getRawIPPort())

        # Helper function to add an IPP, overriding any portless entries.
        def add_ipp(ipp):
            ipps.discard(ipp[:4] + '\0\0')
            ipps.add(ipp)

        syncd = (osm and osm.syncd)

        # Add my own IP.
        # If I'm a hidden node, then only add it if I'm not online yet.
        if (not self.main.hide_node) or (not syncd):
            if osm:
                add_ipp(osm.me.ipp)
            else:
                try:
                    add_ipp(self.main.selectMyIP())
                except ValueError:
                    pass

        # Add the IPPs of online nodes
        if syncd:
            sec = seconds()

            def n_uptime(n):
                uptime = max(0, sec - n.uptime)
                if n.persist:
                    uptime *= 1.5
                return -uptime

            # Sort nodes by uptime, highest first
            nodes = osm.nodes[:]
            nodes.sort(key=n_uptime)

            # Chop list down to the top eighth or so.
            del nodes[min(GOAL, len(nodes) // 8):]

            # Select a random sample from the best nodes.
            try:
                nodes = random.sample(nodes, GOAL)
            except ValueError:
                pass

            for n in nodes:
                add_ipp(n.ipp)
                if len(ipps) >= GOAL:
                    break

        # Add the IPPs of offline nodes (if necessary)
        if len(ipps) < GOAL:
            for when,ipp in self.main.state.getYoungestPeers(GOAL):
                add_ipp(ipp)

                if len(ipps) >= GOAL:
                    break

        ipcache = list(ipps)
        random.shuffle(ipcache)

        ipcache = '\xFF\xFF\xFF\xFF' + ''.join(ipcache)
        ipcache = b64(self.main.pk_enc.encrypt(ipcache))

        entries['ipcache'] = ipcache

        return entries
コード例 #19
0
ファイル: bridge_server.py プロジェクト: Achilles-96/dtella
def n_user(ipp):
    h = binascii.hexlify(md5(ipp).digest())[:6]
    return "dt" + h.upper()
コード例 #20
0
ファイル: bridge_server.py プロジェクト: Achilles-96/dtella
    def getStateData(self, packet):
        # All the state info common between BS and Br packets

        osm = self.main.osm
        CHECK(osm and osm.syncd)

        # Get the IRC Server, if it's ready
        ism = self.main.ism

        # Sequence number
        packet.append(self.nextPktNum())

        # Expiration time
        when = int(dcall_timeleft(self.sendState_dcall))
        packet.append(struct.pack("!H", when))

        # Session ID, uptime flags
        packet.append(osm.me.sesid)
        packet.append(struct.pack("!I", int(seconds() - osm.me.uptime)))
        packet.append(struct.pack("!B", core.PERSIST_BIT))

        chunks = []

        # Add info strings
        self.addInfoChunk(chunks)

        if ism:
            # Add the list of online nicks
            for dnick, infoindex in ism.getNicksAndInfo():
                self.addNickChunk(chunks, dnick, infoindex)

            self.addTopicChunk(
                chunks, ism.topic_whoset, ism.topic, changed=False)

            # Get bans list
            for ip, mask in ism.bans:
                self.addBanChunk(chunks, ip, mask, True)

            if ism.moderated:
                self.addModeratedChunk(chunks, True)

        chunks = ''.join(chunks)

        # Split data string into 1k blocks
        blocks = []
        for i in range(0, len(chunks), 1024):
            blocks.append(chunks[i:i+1024])

        block_hashes = [md5(b).digest() for b in blocks]

        # Add the list of block hashes
        packet.append(struct.pack("!B", len(block_hashes)))
        packet.extend(block_hashes)

        # Add the public key
        pubkey = long_to_bytes(self.rsa_obj.n)
        packet.append(struct.pack("!H", len(pubkey)))
        packet.append(pubkey)

        # Return hashes and blocks
        return block_hashes, blocks
コード例 #21
0
def n_user(ipp):
    h = binascii.hexlify(md5(ipp).digest())[:6]
    return "dt" + h.upper()
コード例 #22
0
    def getStateData(self, packet):
        # All the state info common between BS and Br packets

        osm = self.main.osm
        CHECK(osm and osm.syncd)

        # Get the IRC Server, if it's ready
        ism = self.main.ism

        # Sequence number
        packet.append(self.nextPktNum())

        # Expiration time
        when = int(dcall_timeleft(self.sendState_dcall))
        packet.append(struct.pack("!H", when))

        # Session ID, uptime flags
        packet.append(osm.me.sesid)
        packet.append(struct.pack("!I", int(seconds() - osm.me.uptime)))
        packet.append(struct.pack("!B", core.PERSIST_BIT))

        chunks = []

        # Add info strings
        self.addInfoChunk(chunks)

        if ism:
            # Add the list of online nicks
            for dnick, infoindex in ism.getNicksAndInfo():
                self.addNickChunk(chunks, dnick, infoindex)

            self.addTopicChunk(chunks,
                               ism.topic_whoset,
                               ism.topic,
                               changed=False)

            # Get bans list
            for ip, mask in ism.bans:
                self.addBanChunk(chunks, ip, mask, True)

            if ism.moderated:
                self.addModeratedChunk(chunks, True)

        chunks = ''.join(chunks)

        # Split data string into 1k blocks
        blocks = []
        for i in range(0, len(chunks), 1024):
            blocks.append(chunks[i:i + 1024])

        block_hashes = [md5(b).digest() for b in blocks]

        # Add the list of block hashes
        packet.append(struct.pack("!B", len(block_hashes)))
        packet.extend(block_hashes)

        # Add the public key
        pubkey = long_to_bytes(self.rsa_obj.n)
        packet.append(struct.pack("!H", len(pubkey)))
        packet.append(pubkey)

        # Return hashes and blocks
        return block_hashes, blocks
コード例 #23
0
ファイル: unreal.py プロジェクト: Achilles-96/dtella
 def md5(self, in_str):
     return md5(in_str).digest()
コード例 #24
0
ファイル: push_dconfig.py プロジェクト: tanmaysahay94/dtella
    def getEntries(self):
        # Build and return a dict of entries which should be sent to the
        # dynamic config store.

        def b64(arg):
            return binascii.b2a_base64(arg).rstrip()

        # Dictionary of key=value pairs to return.
        # Start out with the static entries provided in the config.
        entries = cfg.dconfig_fixed_entries.copy()

        osm = self.main.osm

        # Generate public key hash
        if cfg.private_key:
            pubkey = long_to_bytes(RSA.construct(cfg.private_key).n)
            entries['pkhash'] = b64(md5(pubkey).digest())

        # Collect IPPs for the ipcache string
        GOAL = 10
        ipps = set()

        # Initially add all the exempt IPs, without a port
        for ip in self.main.state.exempt_ips:
            ad = Ad()
            ad.ip = ip
            ad.port = 0
            ipps.add(ad.getRawIPPort())

        # Helper function to add an IPP, overriding any portless entries.
        def add_ipp(ipp):
            ipps.discard(ipp[:4] + '\0\0')
            ipps.add(ipp)

        syncd = (osm and osm.syncd)

        # Add my own IP.
        # If I'm a hidden node, then only add it if I'm not online yet.
        if (not self.main.hide_node) or (not syncd):
            if osm:
                add_ipp(osm.me.ipp)
            else:
                try:
                    add_ipp(self.main.selectMyIP().getRawIPPort())
                except ValueError:
                    pass

        # Add the IPPs of online nodes
        if syncd:
            sec = seconds()

            def n_uptime(n):
                uptime = max(0, sec - n.uptime)
                if n.persist:
                    uptime *= 1.5
                return -uptime

            # Sort nodes by uptime, highest first
            nodes = osm.nodes[:]
            nodes.sort(key=n_uptime)

            # Chop list down to the top eighth or so.
            del nodes[min(GOAL, len(nodes) // 8):]

            # Select a random sample from the best nodes.
            try:
                nodes = random.sample(nodes, GOAL)
            except ValueError:
                pass

            for n in nodes:
                add_ipp(n.ipp)
                if len(ipps) >= GOAL:
                    break

        # Add the IPPs of offline nodes (if necessary)
        if len(ipps) < GOAL:
            for when,ipp in self.main.state.getYoungestPeers(GOAL):
                add_ipp(ipp)

                if len(ipps) >= GOAL:
                    break

        ipcache = list(ipps)
        random.shuffle(ipcache)

        ipcache = '\xFF\xFF\xFF\xFF' + ''.join(ipcache)
        ipcache = b64(self.main.pk_enc.encrypt(ipcache))

        entries['ipcache'] = ipcache

        return entries