Fix #748 - Check hash of sig instead of message contents #783

Merged
Atheros1 merged 2 commits from master into master 2015-02-22 01:44:00 +01:00
4 changed files with 46 additions and 29 deletions
Showing only changes of commit 95c939a2a0 - Show all commits

View File

@ -427,6 +427,7 @@ class objectProcessor(threading.Thread):
logger.debug('As a matter of intellectual curiosity, here is the Bitcoin address associated with the keys owned by the other person: %s ..and here is the testnet address: %s. The other person must take their private signing key from Bitmessage and import it into Bitcoin (or a service like Blockchain.info) for it to be of any use. Do not use this unless you know what you are doing.' % logger.debug('As a matter of intellectual curiosity, here is the Bitcoin address associated with the keys owned by the other person: %s ..and here is the testnet address: %s. The other person must take their private signing key from Bitmessage and import it into Bitcoin (or a service like Blockchain.info) for it to be of any use. Do not use this unless you know what you are doing.' %
(helper_bitcoin.calculateBitcoinAddressFromPubkey(pubSigningKey), helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey)) (helper_bitcoin.calculateBitcoinAddressFromPubkey(pubSigningKey), helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey))
) )
sigHash = hashlib.sha512(hashlib.sha512(signature).digest()).digest()[32:] # Used to detect and ignore duplicate messages in our inbox
# calculate the fromRipe. # calculate the fromRipe.
sha = hashlib.new('sha512') sha = hashlib.new('sha512')
@ -503,13 +504,13 @@ class objectProcessor(threading.Thread):
body = 'Unknown encoding type.\n\n' + repr(message) body = 'Unknown encoding type.\n\n' + repr(message)
subject = '' subject = ''
# Let us make sure that we haven't already received this message # Let us make sure that we haven't already received this message
if helper_inbox.isMessageAlreadyInInbox(toAddress, fromAddress, subject, body, messageEncodingType): if helper_inbox.isMessageAlreadyInInbox(sigHash):
logger.info('This msg is already in our inbox. Ignoring it.') logger.info('This msg is already in our inbox. Ignoring it.')
blockMessage = True blockMessage = True
if not blockMessage: if not blockMessage:
if messageEncodingType != 0: if messageEncodingType != 0:
t = (inventoryHash, toAddress, fromAddress, subject, int( t = (inventoryHash, toAddress, fromAddress, subject, int(
time.time()), body, 'inbox', messageEncodingType, 0) time.time()), body, 'inbox', messageEncodingType, 0, sigHash)
helper_inbox.insert(t) helper_inbox.insert(t)
shared.UISignalQueue.put(('displayNewInboxMessage', ( shared.UISignalQueue.put(('displayNewInboxMessage', (
@ -701,6 +702,7 @@ class objectProcessor(threading.Thread):
logger.debug('ECDSA verify failed') logger.debug('ECDSA verify failed')
return return
logger.debug('ECDSA verify passed') logger.debug('ECDSA verify passed')
sigHash = hashlib.sha512(hashlib.sha512(signature).digest()).digest()[32:] # Used to detect and ignore duplicate messages in our inbox
fromAddress = encodeAddress( fromAddress = encodeAddress(
sendersAddressVersion, sendersStream, calculatedRipe) sendersAddressVersion, sendersStream, calculatedRipe)
@ -735,33 +737,33 @@ class objectProcessor(threading.Thread):
subject = '' subject = ''
elif messageEncodingType == 0: elif messageEncodingType == 0:
logger.info('messageEncodingType == 0. Doing nothing with the message.') logger.info('messageEncodingType == 0. Doing nothing with the message.')
return
else: else:
body = 'Unknown encoding type.\n\n' + repr(message) body = 'Unknown encoding type.\n\n' + repr(message)
subject = '' subject = ''
toAddress = '[Broadcast subscribers]' toAddress = '[Broadcast subscribers]'
if messageEncodingType != 0: if helper_inbox.isMessageAlreadyInInbox(sigHash):
if helper_inbox.isMessageAlreadyInInbox(toAddress, fromAddress, subject, body, messageEncodingType): logger.info('This broadcast is already in our inbox. Ignoring it.')
logger.info('This broadcast is already in our inbox. Ignoring it.') return
else: t = (inventoryHash, toAddress, fromAddress, subject, int(
t = (inventoryHash, toAddress, fromAddress, subject, int( time.time()), body, 'inbox', messageEncodingType, 0, sigHash)
time.time()), body, 'inbox', messageEncodingType, 0) helper_inbox.insert(t)
helper_inbox.insert(t)
shared.UISignalQueue.put(('displayNewInboxMessage', ( shared.UISignalQueue.put(('displayNewInboxMessage', (
inventoryHash, toAddress, fromAddress, subject, body))) inventoryHash, toAddress, fromAddress, subject, body)))
# If we are behaving as an API then we might need to run an # If we are behaving as an API then we might need to run an
# outside command to let some program know that a new message # outside command to let some program know that a new message
# has arrived. # has arrived.
if shared.safeConfigGetBoolean('bitmessagesettings', 'apienabled'): if shared.safeConfigGetBoolean('bitmessagesettings', 'apienabled'):
try: try:
apiNotifyPath = shared.config.get( apiNotifyPath = shared.config.get(
'bitmessagesettings', 'apinotifypath') 'bitmessagesettings', 'apinotifypath')
except: except:
apiNotifyPath = '' apiNotifyPath = ''
if apiNotifyPath != '': if apiNotifyPath != '':
call([apiNotifyPath, "newBroadcast"]) call([apiNotifyPath, "newBroadcast"])
# Display timing data # Display timing data
logger.info('Time spent processing this interesting broadcast: %s' % (time.time() - messageProcessingStartTime,)) logger.info('Time spent processing this interesting broadcast: %s' % (time.time() - messageProcessingStartTime,))

View File

@ -821,8 +821,9 @@ class singleWorker(threading.Thread):
# If we are sending to ourselves or a chan, let's put the message in # If we are sending to ourselves or a chan, let's put the message in
# our own inbox. # our own inbox.
if shared.config.has_section(toaddress): if shared.config.has_section(toaddress):
sigHash = hashlib.sha512(hashlib.sha512(signature).digest()).digest()[32:] # Used to detect and ignore duplicate messages in our inbox
t = (inventoryHash, toaddress, fromaddress, subject, int( t = (inventoryHash, toaddress, fromaddress, subject, int(
time.time()), message, 'inbox', 2, 0) time.time()), message, 'inbox', 2, 0, sigHash)
helper_inbox.insert(t) helper_inbox.insert(t)
shared.UISignalQueue.put(('displayNewInboxMessage', ( shared.UISignalQueue.put(('displayNewInboxMessage', (

View File

@ -28,7 +28,7 @@ class sqlThread(threading.Thread):
try: try:
self.cur.execute( self.cur.execute(
'''CREATE TABLE inbox (msgid blob, toaddress text, fromaddress text, subject text, received text, message text, folder text, encodingtype int, read bool, UNIQUE(msgid) ON CONFLICT REPLACE)''' ) '''CREATE TABLE inbox (msgid blob, toaddress text, fromaddress text, subject text, received text, message text, folder text, encodingtype int, read bool, sighash blob, UNIQUE(msgid) ON CONFLICT REPLACE)''' )
self.cur.execute( self.cur.execute(
'''CREATE TABLE sent (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text, ackdata blob, lastactiontime integer, status text, pubkeyretrynumber integer, msgretrynumber integer, folder text, encodingtype int)''' ) '''CREATE TABLE sent (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text, ackdata blob, lastactiontime integer, status text, pubkeyretrynumber integer, msgretrynumber integer, folder text, encodingtype int)''' )
self.cur.execute( self.cur.execute(
@ -61,7 +61,7 @@ class sqlThread(threading.Thread):
'''INSERT INTO subscriptions VALUES('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''') '''INSERT INTO subscriptions VALUES('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''')
self.cur.execute( self.cur.execute(
'''CREATE TABLE settings (key blob, value blob, UNIQUE(key) ON CONFLICT REPLACE)''' ) '''CREATE TABLE settings (key blob, value blob, UNIQUE(key) ON CONFLICT REPLACE)''' )
self.cur.execute( '''INSERT INTO settings VALUES('version','8')''') self.cur.execute( '''INSERT INTO settings VALUES('version','9')''')
self.cur.execute( '''INSERT INTO settings VALUES('lastvacuumtime',?)''', ( self.cur.execute( '''INSERT INTO settings VALUES('lastvacuumtime',?)''', (
int(time.time()),)) int(time.time()),))
self.cur.execute( self.cur.execute(
@ -361,6 +361,20 @@ class sqlThread(threading.Thread):
self.cur.execute(query, parameters) self.cur.execute(query, parameters)
logger.debug('Finished clearing currently held pubkeys.') logger.debug('Finished clearing currently held pubkeys.')
# Add a new column to the inbox table to store the hash of the message signature.
# We'll use this as temporary message UUID in order to detect duplicates.
item = '''SELECT value FROM settings WHERE key='version';'''
parameters = ''
self.cur.execute(item, parameters)
currentVersion = int(self.cur.fetchall()[0][0])
if currentVersion == 8:
logger.debug('In messages.dat database, adding sighash field to the inbox table.')
item = '''ALTER TABLE inbox ADD sighash blob DEFAULT '' '''
parameters = ''
self.cur.execute(item, parameters)
item = '''update settings set value=? WHERE key='version';'''
parameters = (9,)
self.cur.execute(item, parameters)
# Are you hoping to add a new option to the keys.dat file of existing # Are you hoping to add a new option to the keys.dat file of existing
# Bitmessage users or modify the SQLite database? Add it right above this line! # Bitmessage users or modify the SQLite database? Add it right above this line!

View File

@ -2,14 +2,14 @@ from helper_sql import *
import shared import shared
def insert(t): def insert(t):
sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?)''', *t) sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *t)
shared.UISignalQueue.put(('changedInboxUnread', None)) shared.UISignalQueue.put(('changedInboxUnread', None))
def trash(msgid): def trash(msgid):
sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=?''', msgid) sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=?''', msgid)
shared.UISignalQueue.put(('removeInboxRowByMsgid',msgid)) shared.UISignalQueue.put(('removeInboxRowByMsgid',msgid))
def isMessageAlreadyInInbox(toAddress, fromAddress, subject, body, encodingType): def isMessageAlreadyInInbox(sigHash):
queryReturn = sqlQuery( queryReturn = sqlQuery(
'''SELECT COUNT(*) FROM inbox WHERE toaddress=? AND fromaddress=? AND subject=? AND message=? AND encodingtype=? ''', toAddress, fromAddress, subject, body, encodingType) '''SELECT COUNT(*) FROM inbox WHERE sighash=?''', sigHash)
return queryReturn[0][0] != 0 return queryReturn[0][0] != 0