From ad5608227193a0dbba6dc6d402d9ef1f90ee9e01 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Thu, 26 Apr 2018 02:40:39 -0500 Subject: [PATCH] work on new header system --- onionr/communicator.py | 30 ++++++++++++++++++++++++++-- onionr/core.py | 44 ++++++++++++++++++++++++++++++++---------- onionr/onionr.py | 9 +++++---- onionr/onionrutils.py | 7 ++++++- 4 files changed, 73 insertions(+), 17 deletions(-) diff --git a/onionr/communicator.py b/onionr/communicator.py index 214b6a1f..42ce8b56 100755 --- a/onionr/communicator.py +++ b/onionr/communicator.py @@ -19,7 +19,7 @@ and code to operate as a daemon, getting commands from the command queue databas You should have received a copy of the GNU General Public License along with this program. If not, see . ''' -import sqlite3, requests, hmac, hashlib, time, sys, os, math, logger, urllib.parse, base64, binascii, random +import sqlite3, requests, hmac, hashlib, time, sys, os, math, logger, urllib.parse, base64, binascii, random, json import core, onionrutils, onionrcrypto, netcontroller, onionrproofs, btc, config, onionrplugins as plugins class OnionrCommunicate: @@ -254,8 +254,32 @@ class OnionrCommunicate: self.newHashes[i] += 1 logger.warn('UNSAVED BLOCK: ' + i) data = self.downloadBlock(i) + + # if block was successfull gotten (hash already verified) if data: - del self.newHashes[i] + del self.newHashes[i] # remove from probation list + + # deal with block metadata + blockContent = self._core.getData(i) + try: + blockMetadata = json.loads(self._core.getData(i)).split('}')[0] + '}' + try: + blockMetadata['sig'] + blockMetadata['id'] + except KeyError: + pass + else: + creator = self._utils.getPeerByHashId(blockMetadata['id']) + if self._crypto.edVerify(blockContent, creator): + self._core.updateBlockInfo(i, 'sig', 'true') + else: + self._core.updateBlockInfo(i, 'sig', 'false') + try: + blockMetadata['type'] + except KeyError: + pass + except json.decoder.JSONDecodeError: + pass return def downloadBlock(self, hash, peerTries=3): @@ -288,10 +312,12 @@ class OnionrCommunicate: self._core.setData(data) logger.info('Successfully obtained data for ' + hash, timestamp=True) retVal = True + ''' if data.startswith(b'-txt-'): self._core.setBlockType(hash, 'txt') if len(data) < 120: logger.debug('Block text:\n' + data.decode()) + ''' else: logger.warn("Failed to validate " + hash + " " + " hash calculated was " + digest) peerTryCount += 1 diff --git a/onionr/core.py b/onionr/core.py index 289f6c00..f293eacb 100644 --- a/onionr/core.py +++ b/onionr/core.py @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' -import sqlite3, os, sys, time, math, base64, tarfile, getpass, simplecrypt, hashlib, nacl, logger +import sqlite3, os, sys, time, math, base64, tarfile, getpass, simplecrypt, hashlib, nacl, logger, json #from Crypto.Cipher import AES #from Crypto import Random import netcontroller @@ -87,8 +87,9 @@ class Core: if not self._utils.validatePubKey(peerID): return False conn = sqlite3.connect(self.peerDB) + hashID = self._crypto.pubKeyHashID(peerID) c = conn.cursor() - t = (peerID, name, 'unknown') + t = (peerID, name, 'unknown', hashID) for i in c.execute("SELECT * FROM PEERS where id = '" + peerID + "';"): try: @@ -99,7 +100,7 @@ class Core: pass except IndexError: pass - c.execute('INSERT INTO peers (id, name, dateSeen) VALUES(?, ?, ?);', t) + c.execute('INSERT INTO peers (id, name, dateSeen, hashID) VALUES(?, ?, ?, ?);', t) conn.commit() conn.close() @@ -211,7 +212,8 @@ class Core: dateSeen not null, bytesStored int, trust int, - pubkeyExchanged int); + pubkeyExchanged int, + hashID); ''') conn.commit() conn.close() @@ -228,7 +230,7 @@ class Core: dataFound - if the data has been found for the block dataSaved - if the data has been saved for the block sig - optional signature by the author (not optional if author is specified) - author - multi-round partial scrypt hash of authors public key + author - multi-round partial sha3-256 hash of authors public key ''' if os.path.exists(self.blockDB): raise Exception("Block database already exists") @@ -466,11 +468,12 @@ class Core: bytesStored int, 5 trust int 6 pubkeyExchanged int 7 + hashID text 8 ''' conn = sqlite3.connect(self.peerDB) c = conn.cursor() command = (peer,) - infoNumbers = {'id': 0, 'name': 1, 'adders': 2, 'forwardKey': 3, 'dateSeen': 4, 'bytesStored': 5, 'trust': 6, 'pubkeyExchanged': 7} + infoNumbers = {'id': 0, 'name': 1, 'adders': 2, 'forwardKey': 3, 'dateSeen': 4, 'bytesStored': 5, 'trust': 6, 'pubkeyExchanged': 7, 'hashID': 8} info = infoNumbers[info] iterCount = 0 retVal = '' @@ -586,20 +589,41 @@ class Core: c.execute("UPDATE hashes SET dataType='" + blockType + "' WHERE hash = '" + hash + "';") conn.commit() conn.close() - return + + def updateBlockInfo(self, hash, key, data): + ''' + sets info associated with a block + ''' + + if key not in ('dateReceived', 'decrypted', 'dataType', 'dataFound', 'dataSaved', 'sig', 'author'): + return False + + conn = sqlite3.connect(self.blockDB) + c = conn.cursor() + args = (data, hash) + c.execute("UPDATE hashes SET " + key + " = ? where hash = ?;", args) + conn.commit() + conn.close() + return True def insertBlock(self, data, header='txt', sign=False): ''' Inserts a block into the network ''' - retData = '' - metadata = '-' + header + '-' - metadata = metadata.encode() try: data.decode() except AttributeError: data = data.encode() + retData = '' + metadata = {'type': header} + if sign: + signature = self._crypto.edSign(data, self._crypto.privKey, encodedResult=True) + ourID = self._crypto.pubKeyHashID() + metadata['id'] = ourID + metadata['sig'] = signature + metadata = json.dumps(metadata) + metadata = metadata.encode() if len(data) == 0: logger.error('Will not insert empty block') else: diff --git a/onionr/onionr.py b/onionr/onionr.py index 7fdc5be8..a92f2ec6 100755 --- a/onionr/onionr.py +++ b/onionr/onionr.py @@ -371,13 +371,14 @@ class Onionr: while True: - messageToAdd = '-txt-' + logger.readline('Broadcast message to network: ') + messageToAdd = logger.readline('Broadcast message to network: ') if len(messageToAdd) - 5 >= 1: break - addedHash = self.onionrCore.setData(messageToAdd) - self.onionrCore.addToBlockDB(addedHash, selfInsert=True) - self.onionrCore.setBlockType(addedHash, 'txt') + #addedHash = self.onionrCore.setData(messageToAdd) + addedHash = self.onionrCore.insertBlock(messageToAdd, header='') + #self.onionrCore.addToBlockDB(addedHash, selfInsert=True) + #self.onionrCore.setBlockType(addedHash, 'txt') logger.info("inserted your message as block: " + addedHash) return diff --git a/onionr/onionrutils.py b/onionr/onionrutils.py index af1dc440..c5159525 100644 --- a/onionr/onionrutils.py +++ b/onionr/onionrutils.py @@ -337,4 +337,9 @@ class OnionrUtils: pass except Exception as error: logger.error('Failed to open block ' + str(i) + '.', error=error) - return \ No newline at end of file + return + + def getPeerByHashId(self, hash): + ''' + Return the pubkey of the user if known from the hash + ''' \ No newline at end of file