Chan fix: initial work completed
This commit is contained in:
parent
7e07d7bc7e
commit
498928405b
|
@ -1564,15 +1564,6 @@ class MyForm(QtGui.QMainWindow):
|
||||||
"MainWindow", "Error: You must specify a From address. If you don\'t have one, go to the \'Your Identities\' tab."))
|
"MainWindow", "Error: You must specify a From address. If you don\'t have one, go to the \'Your Identities\' tab."))
|
||||||
else:
|
else:
|
||||||
toAddress = addBMIfNotPresent(toAddress)
|
toAddress = addBMIfNotPresent(toAddress)
|
||||||
try:
|
|
||||||
shared.config.get(toAddress, 'enabled')
|
|
||||||
# The toAddress is one owned by me.
|
|
||||||
if not shared.safeConfigGetBoolean(toAddress, 'chan'):
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Sending to your address"), _translate(
|
|
||||||
"MainWindow", "Error: One of the addresses to which you are sending a message, %1, is yours. Unfortunately the Bitmessage client cannot process its own messages. Please try running a second client on a different computer or within a VM.").arg(toAddress))
|
|
||||||
continue
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
if addressVersionNumber > 4 or addressVersionNumber <= 1:
|
if addressVersionNumber > 4 or addressVersionNumber <= 1:
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Address version number"), _translate(
|
QMessageBox.about(self, _translate("MainWindow", "Address version number"), _translate(
|
||||||
"MainWindow", "Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version.").arg(toAddress).arg(str(addressVersionNumber)))
|
"MainWindow", "Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version.").arg(toAddress).arg(str(addressVersionNumber)))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
doTimingAttackMitigation = True
|
doTimingAttackMitigation = False
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
|
@ -514,8 +514,9 @@ class receiveDataThread(threading.Thread):
|
||||||
# the proof of work ourselves, which this program is programmed
|
# the proof of work ourselves, which this program is programmed
|
||||||
# to not do.)
|
# to not do.)
|
||||||
sqlExecute(
|
sqlExecute(
|
||||||
'''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
'''INSERT INTO pubkeys VALUES (?,?,?,?,?)''',
|
||||||
ripe.digest(),
|
ripe.digest(),
|
||||||
|
sendersAddressVersion,
|
||||||
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + data[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + data[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
||||||
int(time.time()),
|
int(time.time()),
|
||||||
'yes')
|
'yes')
|
||||||
|
@ -655,8 +656,9 @@ class receiveDataThread(threading.Thread):
|
||||||
|
|
||||||
# Let's store the public key in case we want to reply to this
|
# Let's store the public key in case we want to reply to this
|
||||||
# person.
|
# person.
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''',
|
||||||
ripe.digest(),
|
ripe.digest(),
|
||||||
|
sendersAddressVersion,
|
||||||
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + decryptedData[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + decryptedData[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
||||||
int(time.time()),
|
int(time.time()),
|
||||||
'yes')
|
'yes')
|
||||||
|
@ -806,8 +808,9 @@ class receiveDataThread(threading.Thread):
|
||||||
|
|
||||||
# Let's store the public key in case we want to reply to this person.
|
# Let's store the public key in case we want to reply to this person.
|
||||||
sqlExecute(
|
sqlExecute(
|
||||||
'''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
'''INSERT INTO pubkeys VALUES (?,?,?,?,?)''',
|
||||||
calculatedRipe,
|
calculatedRipe,
|
||||||
|
sendersAddressVersion,
|
||||||
'\x00\x00\x00\x00\x00\x00\x00\x01' + decryptedData[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
'\x00\x00\x00\x00\x00\x00\x00\x01' + decryptedData[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
||||||
int(time.time()),
|
int(time.time()),
|
||||||
'yes')
|
'yes')
|
||||||
|
@ -1070,8 +1073,9 @@ class receiveDataThread(threading.Thread):
|
||||||
# person.
|
# person.
|
||||||
if sendersAddressVersionNumber <= 3:
|
if sendersAddressVersionNumber <= 3:
|
||||||
sqlExecute(
|
sqlExecute(
|
||||||
'''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
'''INSERT INTO pubkeys VALUES (?,?,?,?,?)''',
|
||||||
ripe.digest(),
|
ripe.digest(),
|
||||||
|
sendersAddressVersionNumber,
|
||||||
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + decryptedData[messageVersionLength:endOfThePublicKeyPosition],
|
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + decryptedData[messageVersionLength:endOfThePublicKeyPosition],
|
||||||
int(time.time()),
|
int(time.time()),
|
||||||
'yes')
|
'yes')
|
||||||
|
@ -1081,8 +1085,9 @@ class receiveDataThread(threading.Thread):
|
||||||
self.possibleNewPubkey(ripe=ripe.digest())
|
self.possibleNewPubkey(ripe=ripe.digest())
|
||||||
elif sendersAddressVersionNumber >= 4:
|
elif sendersAddressVersionNumber >= 4:
|
||||||
sqlExecute(
|
sqlExecute(
|
||||||
'''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
'''INSERT INTO pubkeys VALUES (?,?,?,?,?)''',
|
||||||
ripe.digest(),
|
ripe.digest(),
|
||||||
|
sendersAddressVersionNumber,
|
||||||
'\x00\x00\x00\x00\x00\x00\x00\x01' + decryptedData[messageVersionLength:endOfThePublicKeyPosition],
|
'\x00\x00\x00\x00\x00\x00\x00\x01' + decryptedData[messageVersionLength:endOfThePublicKeyPosition],
|
||||||
int(time.time()),
|
int(time.time()),
|
||||||
'yes')
|
'yes')
|
||||||
|
@ -1409,15 +1414,15 @@ class receiveDataThread(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
'''SELECT usedpersonally FROM pubkeys WHERE hash=? AND usedpersonally='yes' ''', ripe)
|
'''SELECT usedpersonally FROM pubkeys WHERE hash=? AND addressversion=? AND usedpersonally='yes' ''', ripe, addressVersion)
|
||||||
if queryreturn != []: # if this pubkey is already in our database and if we have used it personally:
|
if queryreturn != []: # if this pubkey is already in our database and if we have used it personally:
|
||||||
print 'We HAVE used this pubkey personally. Updating time.'
|
print 'We HAVE used this pubkey personally. Updating time.'
|
||||||
t = (ripe, data, embeddedTime, 'yes')
|
t = (ripe, addressVersion, data, embeddedTime, 'yes')
|
||||||
else:
|
else:
|
||||||
print 'We have NOT used this pubkey personally. Inserting in database.'
|
print 'We have NOT used this pubkey personally. Inserting in database.'
|
||||||
t = (ripe, data, embeddedTime, 'no')
|
t = (ripe, addressVersion, data, embeddedTime, 'no')
|
||||||
# This will also update the embeddedTime.
|
# This will also update the embeddedTime.
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
|
||||||
# shared.workerQueue.put(('newpubkey',(addressVersion,streamNumber,ripe)))
|
# shared.workerQueue.put(('newpubkey',(addressVersion,streamNumber,ripe)))
|
||||||
self.possibleNewPubkey(ripe = ripe)
|
self.possibleNewPubkey(ripe = ripe)
|
||||||
if addressVersion == 3:
|
if addressVersion == 3:
|
||||||
|
@ -1466,19 +1471,18 @@ class receiveDataThread(threading.Thread):
|
||||||
print 'publicEncryptionKey in hex:', publicEncryptionKey.encode('hex')
|
print 'publicEncryptionKey in hex:', publicEncryptionKey.encode('hex')
|
||||||
|
|
||||||
|
|
||||||
queryreturn = sqlQuery('''SELECT usedpersonally FROM pubkeys WHERE hash=? AND usedpersonally='yes' ''', ripe)
|
queryreturn = sqlQuery('''SELECT usedpersonally FROM pubkeys WHERE hash=? AND addressversion=? AND usedpersonally='yes' ''', ripe, addressVersion)
|
||||||
if queryreturn != []: # if this pubkey is already in our database and if we have used it personally:
|
if queryreturn != []: # if this pubkey is already in our database and if we have used it personally:
|
||||||
print 'We HAVE used this pubkey personally. Updating time.'
|
print 'We HAVE used this pubkey personally. Updating time.'
|
||||||
t = (ripe, data, embeddedTime, 'yes')
|
t = (ripe, addressVersion, data, embeddedTime, 'yes')
|
||||||
else:
|
else:
|
||||||
print 'We have NOT used this pubkey personally. Inserting in database.'
|
print 'We have NOT used this pubkey personally. Inserting in database.'
|
||||||
t = (ripe, data, embeddedTime, 'no')
|
t = (ripe, addressVersion, data, embeddedTime, 'no')
|
||||||
# This will also update the embeddedTime.
|
# This will also update the embeddedTime.
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
|
||||||
self.possibleNewPubkey(ripe = ripe)
|
self.possibleNewPubkey(ripe = ripe)
|
||||||
|
|
||||||
if addressVersion == 4:
|
if addressVersion == 4:
|
||||||
print 'length of v4 pubkey:', len(data)
|
|
||||||
if len(data) < 350: # sanity check.
|
if len(data) < 350: # sanity check.
|
||||||
print '(within processpubkey) payloadLength less than 350. Sanity check failed.'
|
print '(within processpubkey) payloadLength less than 350. Sanity check failed.'
|
||||||
return
|
return
|
||||||
|
@ -1554,8 +1558,8 @@ class receiveDataThread(threading.Thread):
|
||||||
print 'publicSigningKey in hex:', publicSigningKey.encode('hex')
|
print 'publicSigningKey in hex:', publicSigningKey.encode('hex')
|
||||||
print 'publicEncryptionKey in hex:', publicEncryptionKey.encode('hex')
|
print 'publicEncryptionKey in hex:', publicEncryptionKey.encode('hex')
|
||||||
|
|
||||||
t = (ripe, signedData, embeddedTime, 'yes')
|
t = (ripe, addressVersion, signedData, embeddedTime, 'yes')
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
|
||||||
|
|
||||||
fromAddress = encodeAddress(addressVersion, streamNumber, ripe)
|
fromAddress = encodeAddress(addressVersion, streamNumber, ripe)
|
||||||
# That this point we know that we have been waiting on this pubkey.
|
# That this point we know that we have been waiting on this pubkey.
|
||||||
|
|
|
@ -156,6 +156,10 @@ class singleWorker(threading.Thread):
|
||||||
# send messages to "ourselves".
|
# send messages to "ourselves".
|
||||||
def sendOutOrStoreMyV3Pubkey(self, hash):
|
def sendOutOrStoreMyV3Pubkey(self, hash):
|
||||||
myAddress = shared.myAddressesByHash[hash]
|
myAddress = shared.myAddressesByHash[hash]
|
||||||
|
if shared.safeConfigGetBoolean(myAddress, 'chan'):
|
||||||
|
with shared.printLock:
|
||||||
|
print 'This is a chan address. Not sending pubkey.'
|
||||||
|
return
|
||||||
status, addressVersionNumber, streamNumber, hash = decodeAddress(
|
status, addressVersionNumber, streamNumber, hash = decodeAddress(
|
||||||
myAddress)
|
myAddress)
|
||||||
embeddedTime = int(time.time() + random.randrange(
|
embeddedTime = int(time.time() + random.randrange(
|
||||||
|
@ -197,7 +201,6 @@ class singleWorker(threading.Thread):
|
||||||
payload += encodeVarint(len(signature))
|
payload += encodeVarint(len(signature))
|
||||||
payload += signature
|
payload += signature
|
||||||
|
|
||||||
if not shared.safeConfigGetBoolean(myAddress, 'chan'):
|
|
||||||
# Do the POW for this pubkey message
|
# Do the POW for this pubkey message
|
||||||
target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes +
|
target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes +
|
||||||
8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
|
8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
|
||||||
|
@ -219,27 +222,18 @@ class singleWorker(threading.Thread):
|
||||||
shared.broadcastToSendDataQueues((
|
shared.broadcastToSendDataQueues((
|
||||||
streamNumber, 'advertiseobject', inventoryHash))
|
streamNumber, 'advertiseobject', inventoryHash))
|
||||||
shared.UISignalQueue.put(('updateStatusBar', ''))
|
shared.UISignalQueue.put(('updateStatusBar', ''))
|
||||||
# If this is a chan address then we won't send out the pubkey over the
|
|
||||||
# network but rather will only store it in our pubkeys table so that
|
|
||||||
# we can send messages to "ourselves".
|
|
||||||
if shared.safeConfigGetBoolean(myAddress, 'chan'):
|
|
||||||
payload = '\x00' * 8 + payload # Attach a fake nonce on the front
|
|
||||||
# just so that it is in the correct format.
|
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
|
||||||
hash,
|
|
||||||
payload,
|
|
||||||
embeddedTime,
|
|
||||||
'yes')
|
|
||||||
shared.config.set(
|
shared.config.set(
|
||||||
myAddress, 'lastpubkeysendtime', str(int(time.time())))
|
myAddress, 'lastpubkeysendtime', str(int(time.time())))
|
||||||
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
||||||
shared.config.write(configfile)
|
shared.config.write(configfile)
|
||||||
|
|
||||||
# If this isn't a chan address, this function assembles the pubkey data,
|
# If this isn't a chan address, this function assembles the pubkey data,
|
||||||
# does the necessary POW and sends it out. If it *is* a chan then it
|
# does the necessary POW and sends it out.
|
||||||
# assembles the pubkey and stores is in the pubkey table so that we can
|
|
||||||
# send messages to "ourselves".
|
|
||||||
def sendOutOrStoreMyV4Pubkey(self, myAddress):
|
def sendOutOrStoreMyV4Pubkey(self, myAddress):
|
||||||
|
if shared.safeConfigGetBoolean(myAddress, 'chan'):
|
||||||
|
with shared.printLock:
|
||||||
|
print 'This is a chan address. Not sending pubkey.'
|
||||||
|
return
|
||||||
status, addressVersionNumber, streamNumber, hash = decodeAddress(
|
status, addressVersionNumber, streamNumber, hash = decodeAddress(
|
||||||
myAddress)
|
myAddress)
|
||||||
embeddedTime = int(time.time() + random.randrange(
|
embeddedTime = int(time.time() + random.randrange(
|
||||||
|
@ -284,7 +278,6 @@ class singleWorker(threading.Thread):
|
||||||
dataToEncrypt += encodeVarint(len(signature))
|
dataToEncrypt += encodeVarint(len(signature))
|
||||||
dataToEncrypt += signature
|
dataToEncrypt += signature
|
||||||
|
|
||||||
if not shared.safeConfigGetBoolean(myAddress, 'chan'):
|
|
||||||
# Let us encrypt the necessary data. We will use a hash of the data
|
# Let us encrypt the necessary data. We will use a hash of the data
|
||||||
# contained in an address as a decryption key. This way in order to
|
# contained in an address as a decryption key. This way in order to
|
||||||
# read the public keys in a pubkey message, a node must know the address
|
# read the public keys in a pubkey message, a node must know the address
|
||||||
|
@ -320,16 +313,6 @@ class singleWorker(threading.Thread):
|
||||||
shared.broadcastToSendDataQueues((
|
shared.broadcastToSendDataQueues((
|
||||||
streamNumber, 'advertiseobject', inventoryHash))
|
streamNumber, 'advertiseobject', inventoryHash))
|
||||||
shared.UISignalQueue.put(('updateStatusBar', ''))
|
shared.UISignalQueue.put(('updateStatusBar', ''))
|
||||||
# If this is a chan address then we won't send out the pubkey over the
|
|
||||||
# network but rather will only store it in our pubkeys table so that
|
|
||||||
# we can send messages to "ourselves".
|
|
||||||
if shared.safeConfigGetBoolean(myAddress, 'chan'):
|
|
||||||
|
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
|
||||||
hash,
|
|
||||||
dataToStoreInOurPubkeysTable,
|
|
||||||
embeddedTime,
|
|
||||||
'yes')
|
|
||||||
shared.config.set(
|
shared.config.set(
|
||||||
myAddress, 'lastpubkeysendtime', str(int(time.time())))
|
myAddress, 'lastpubkeysendtime', str(int(time.time())))
|
||||||
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
||||||
|
@ -369,8 +352,6 @@ class singleWorker(threading.Thread):
|
||||||
pubEncryptionKey = highlevelcrypto.privToPub(
|
pubEncryptionKey = highlevelcrypto.privToPub(
|
||||||
privEncryptionKeyHex).decode('hex')
|
privEncryptionKeyHex).decode('hex')
|
||||||
|
|
||||||
print 'embedding pubEncryptionKey:', pubEncryptionKey.encode('hex')
|
|
||||||
|
|
||||||
payload = pack('>Q', (int(time.time()) + random.randrange(
|
payload = pack('>Q', (int(time.time()) + random.randrange(
|
||||||
-300, 300))) # the current time plus or minus five minutes
|
-300, 300))) # the current time plus or minus five minutes
|
||||||
if addressVersionNumber <= 3:
|
if addressVersionNumber <= 3:
|
||||||
|
@ -382,8 +363,6 @@ class singleWorker(threading.Thread):
|
||||||
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
||||||
addressVersionNumber) + encodeVarint(streamNumber) + ripe).digest()).digest()
|
addressVersionNumber) + encodeVarint(streamNumber) + ripe).digest()).digest()
|
||||||
payload += doubleHashOfAddressData[32:] # the tag
|
payload += doubleHashOfAddressData[32:] # the tag
|
||||||
print 'embeddedTag is', doubleHashOfAddressData[32:].encode('hex')
|
|
||||||
print 'embeddedTag is', repr(doubleHashOfAddressData[32:])
|
|
||||||
|
|
||||||
if addressVersionNumber <= 3:
|
if addressVersionNumber <= 3:
|
||||||
dataToEncrypt = encodeVarint(2) # broadcast version
|
dataToEncrypt = encodeVarint(2) # broadcast version
|
||||||
|
@ -458,8 +437,11 @@ class singleWorker(threading.Thread):
|
||||||
for row in queryreturn: # For each address to which we need to send a message, check to see if we have its pubkey already.
|
for row in queryreturn: # For each address to which we need to send a message, check to see if we have its pubkey already.
|
||||||
toaddress, = row
|
toaddress, = row
|
||||||
status, toAddressVersion, toStreamNumber, toRipe = decodeAddress(toaddress)
|
status, toAddressVersion, toStreamNumber, toRipe = decodeAddress(toaddress)
|
||||||
|
# If we are sending a message to ourselves or a chan then we won't need an entry in the pubkeys table; we can calculate the needed pubkey using the private keys in our keys.dat file.
|
||||||
|
if shared.config.has_section(toaddress):
|
||||||
|
continue
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
'''SELECT hash FROM pubkeys WHERE hash=? ''', toRipe)
|
'''SELECT hash FROM pubkeys WHERE hash=? AND addressversion=?''', toRipe, toAddressVersion)
|
||||||
if queryreturn != []: # If we have the needed pubkey in the pubkey table already, set the status to doingmsgpow (we'll do it further down)
|
if queryreturn != []: # If we have the needed pubkey in the pubkey table already, set the status to doingmsgpow (we'll do it further down)
|
||||||
sqlExecute(
|
sqlExecute(
|
||||||
'''UPDATE sent SET status='doingmsgpow' WHERE toaddress=? AND status='msgqueued' ''',
|
'''UPDATE sent SET status='doingmsgpow' WHERE toaddress=? AND status='msgqueued' ''',
|
||||||
|
@ -523,6 +505,12 @@ class singleWorker(threading.Thread):
|
||||||
int(time.time()) - 2419200)
|
int(time.time()) - 2419200)
|
||||||
for row in queryreturn: # For each message we need to send..
|
for row in queryreturn: # For each message we need to send..
|
||||||
toaddress, toripe, fromaddress, subject, message, ackdata, status = row
|
toaddress, toripe, fromaddress, subject, message, ackdata, status = row
|
||||||
|
toStatus, toAddressVersionNumber, toStreamNumber, toHash = decodeAddress(
|
||||||
|
toaddress)
|
||||||
|
fromStatus, fromAddressVersionNumber, fromStreamNumber, fromHash = decodeAddress(
|
||||||
|
fromaddress)
|
||||||
|
|
||||||
|
if not shared.config.has_section(toaddress):
|
||||||
# There is a remote possibility that we may no longer have the
|
# There is a remote possibility that we may no longer have the
|
||||||
# recipient's pubkey. Let us make sure we still have it or else the
|
# recipient's pubkey. Let us make sure we still have it or else the
|
||||||
# sendMsg function will appear to freeze. This can happen if the
|
# sendMsg function will appear to freeze. This can happen if the
|
||||||
|
@ -530,15 +518,15 @@ class singleWorker(threading.Thread):
|
||||||
# then leaves their client off for a long time which could cause
|
# then leaves their client off for a long time which could cause
|
||||||
# the needed pubkey to expire and be deleted.
|
# the needed pubkey to expire and be deleted.
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
'''SELECT hash FROM pubkeys WHERE hash=? ''',
|
'''SELECT hash FROM pubkeys WHERE hash=? AND addressversion=?''',
|
||||||
toripe)
|
toripe,
|
||||||
|
toAddressVersionNumber)
|
||||||
if queryreturn == [] and toripe not in shared.neededPubkeys:
|
if queryreturn == [] and toripe not in shared.neededPubkeys:
|
||||||
# We no longer have the needed pubkey and we haven't requested
|
# We no longer have the needed pubkey and we haven't requested
|
||||||
# it.
|
# it.
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
'For some reason, the status of a message in our outbox is \'doingmsgpow\' even though we lack the pubkey. Here is the RIPE hash of the needed pubkey: %s\n' % toripe.encode('hex'))
|
'For some reason, the status of a message in our outbox is \'doingmsgpow\' even though we lack the pubkey. Here is the RIPE hash of the needed pubkey: %s\n' % toripe.encode('hex'))
|
||||||
|
|
||||||
sqlExecute(
|
sqlExecute(
|
||||||
'''UPDATE sent SET status='msgqueued' WHERE toaddress=? AND status='doingmsgpow' ''', toaddress)
|
'''UPDATE sent SET status='msgqueued' WHERE toaddress=? AND status='doingmsgpow' ''', toaddress)
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByHash', (
|
shared.UISignalQueue.put(('updateSentItemStatusByHash', (
|
||||||
|
@ -546,28 +534,25 @@ class singleWorker(threading.Thread):
|
||||||
self.requestPubKey(toaddress)
|
self.requestPubKey(toaddress)
|
||||||
continue
|
continue
|
||||||
shared.ackdataForWhichImWatching[ackdata] = 0
|
shared.ackdataForWhichImWatching[ackdata] = 0
|
||||||
toStatus, toAddressVersionNumber, toStreamNumber, toHash = decodeAddress(
|
|
||||||
toaddress)
|
|
||||||
fromStatus, fromAddressVersionNumber, fromStreamNumber, fromHash = decodeAddress(
|
|
||||||
fromaddress)
|
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||||
ackdata, tr.translateText("MainWindow", "Looking up the receiver\'s public key"))))
|
ackdata, tr.translateText("MainWindow", "Looking up the receiver\'s public key"))))
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'Found a message in our database that needs to be sent with this pubkey.'
|
print 'Sending a message. First 150 characters of message:', repr(message[:150])
|
||||||
print 'First 150 characters of message:', repr(message[:150])
|
|
||||||
|
|
||||||
|
|
||||||
# mark the pubkey as 'usedpersonally' so that we don't ever delete
|
# mark the pubkey as 'usedpersonally' so that we don't ever delete
|
||||||
# it.
|
# it.
|
||||||
sqlExecute(
|
sqlExecute(
|
||||||
'''UPDATE pubkeys SET usedpersonally='yes' WHERE hash=?''',
|
'''UPDATE pubkeys SET usedpersonally='yes' WHERE hash=? and addressversion=?''',
|
||||||
toripe)
|
toripe,
|
||||||
|
toAddressVersionNumber)
|
||||||
# Let us fetch the recipient's public key out of our database. If
|
# Let us fetch the recipient's public key out of our database. If
|
||||||
# the required proof of work difficulty is too hard then we'll
|
# the required proof of work difficulty is too hard then we'll
|
||||||
# abort.
|
# abort.
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
'SELECT transmitdata FROM pubkeys WHERE hash=?',
|
'SELECT transmitdata FROM pubkeys WHERE hash=? and addressversion=?',
|
||||||
toripe)
|
toripe,
|
||||||
|
toAddressVersionNumber)
|
||||||
if queryreturn == []:
|
if queryreturn == []:
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
|
@ -646,7 +631,28 @@ class singleWorker(threading.Thread):
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do.").arg(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte)).arg(str(float(
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do.").arg(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte)).arg(str(float(
|
||||||
requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes)).arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
|
requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes)).arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
|
||||||
continue
|
continue
|
||||||
|
else: # if we are sending a message to ourselves or a chan..
|
||||||
|
with shared.printLock:
|
||||||
|
print 'Sending a message. First 150 characters of message:', repr(message[:150])
|
||||||
|
behaviorBitfield = '\x00\x00\x00\x01'
|
||||||
|
|
||||||
|
try:
|
||||||
|
privEncryptionKeyBase58 = shared.config.get(
|
||||||
|
toaddress, 'privencryptionkey')
|
||||||
|
except Exception as err:
|
||||||
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1').arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))))
|
||||||
|
with shared.printLock:
|
||||||
|
sys.stderr.write(
|
||||||
|
'Error within sendMsg. Could not read the keys from the keys.dat file for our own address. %s\n' % err)
|
||||||
|
continue
|
||||||
|
privEncryptionKeyHex = shared.decodeWalletImportFormat(
|
||||||
|
privEncryptionKeyBase58).encode('hex')
|
||||||
|
pubEncryptionKeyBase256 = highlevelcrypto.privToPub(
|
||||||
|
privEncryptionKeyHex).decode('hex')[1:]
|
||||||
|
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
|
||||||
|
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
||||||
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||||
|
ackdata, tr.translateText("MainWindow", "Doing work necessary to send message."))))
|
||||||
|
|
||||||
embeddedTime = pack('>Q', (int(time.time()) + random.randrange(
|
embeddedTime = pack('>Q', (int(time.time()) + random.randrange(
|
||||||
-300, 300))) # the current time plus or minus five minutes. We will use this time both for our message and for the ackdata packed within our message.
|
-300, 300))) # the current time plus or minus five minutes. We will use this time both for our message and for the ackdata packed within our message.
|
||||||
|
@ -750,11 +756,11 @@ class singleWorker(threading.Thread):
|
||||||
payload += messageToTransmit
|
payload += messageToTransmit
|
||||||
if shared.safeConfigGetBoolean(toaddress, 'chan'):
|
if shared.safeConfigGetBoolean(toaddress, 'chan'):
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'Not bothering to generate ackdata because we are sending to a chan.'
|
print 'Not bothering to include ackdata because we are sending to a chan.'
|
||||||
fullAckPayload = ''
|
fullAckPayload = ''
|
||||||
elif not shared.isBitSetWithinBitfield(behaviorBitfield,31):
|
elif not shared.isBitSetWithinBitfield(behaviorBitfield,31):
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'Not bothering to generate ackdata because the receiver said that they won\'t relay it anyway.'
|
print 'Not bothering to include ackdata because the receiver said that they won\'t relay it anyway.'
|
||||||
fullAckPayload = ''
|
fullAckPayload = ''
|
||||||
else:
|
else:
|
||||||
fullAckPayload = self.generateFullAckMessage(
|
fullAckPayload = self.generateFullAckMessage(
|
||||||
|
@ -795,11 +801,11 @@ class singleWorker(threading.Thread):
|
||||||
shared.inventory[inventoryHash] = (
|
shared.inventory[inventoryHash] = (
|
||||||
objectType, toStreamNumber, encryptedPayload, int(time.time()),'')
|
objectType, toStreamNumber, encryptedPayload, int(time.time()),'')
|
||||||
shared.inventorySets[toStreamNumber].add(inventoryHash)
|
shared.inventorySets[toStreamNumber].add(inventoryHash)
|
||||||
if shared.safeConfigGetBoolean(toaddress, 'chan'):
|
if shared.config.has_section(toaddress):
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Sent on %1").arg(unicode(
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Sent on %1").arg(unicode(
|
||||||
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
|
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
|
||||||
else:
|
else:
|
||||||
# not sending to a chan
|
# not sending to a chan or one of my addresses
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Waiting on acknowledgement. Sent on %1").arg(unicode(
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Waiting on acknowledgement. Sent on %1").arg(unicode(
|
||||||
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
|
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
|
||||||
print 'Broadcasting inv for my msg(within sendmsg function):', inventoryHash.encode('hex')
|
print 'Broadcasting inv for my msg(within sendmsg function):', inventoryHash.encode('hex')
|
||||||
|
@ -808,7 +814,7 @@ class singleWorker(threading.Thread):
|
||||||
|
|
||||||
# Update the status of the message in the 'sent' table to have a
|
# Update the status of the message in the 'sent' table to have a
|
||||||
# 'msgsent' status or 'msgsentnoackexpected' status.
|
# 'msgsent' status or 'msgsentnoackexpected' status.
|
||||||
if shared.safeConfigGetBoolean(toaddress, 'chan'):
|
if not shared.config.has_section(toaddress):
|
||||||
newStatus = 'msgsentnoackexpected'
|
newStatus = 'msgsentnoackexpected'
|
||||||
else:
|
else:
|
||||||
newStatus = 'msgsent'
|
newStatus = 'msgsent'
|
||||||
|
|
|
@ -46,7 +46,7 @@ class sqlThread(threading.Thread):
|
||||||
# because we may need more flexability in the future and it doesn't
|
# because we may need more flexability in the future and it doesn't
|
||||||
# take up much more space anyway.
|
# take up much more space anyway.
|
||||||
self.cur.execute(
|
self.cur.execute(
|
||||||
'''CREATE TABLE pubkeys (hash blob, transmitdata blob, time int, usedpersonally text, UNIQUE(hash) ON CONFLICT REPLACE)''' )
|
'''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''' )
|
||||||
self.cur.execute(
|
self.cur.execute(
|
||||||
'''CREATE TABLE inventory (hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer, tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''' )
|
'''CREATE TABLE inventory (hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer, tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''' )
|
||||||
self.cur.execute(
|
self.cur.execute(
|
||||||
|
@ -57,7 +57,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','4')''')
|
self.cur.execute( '''INSERT INTO settings VALUES('version','5')''')
|
||||||
self.cur.execute( '''INSERT INTO settings VALUES('lastvacuumtime',?)''', (
|
self.cur.execute( '''INSERT INTO settings VALUES('lastvacuumtime',?)''', (
|
||||||
int(time.time()),))
|
int(time.time()),))
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
@ -253,13 +253,29 @@ class sqlThread(threading.Thread):
|
||||||
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
||||||
shared.config.write(configfile)
|
shared.config.write(configfile)
|
||||||
|
|
||||||
|
# Add a new column to the pubkeys table to store the address version.
|
||||||
|
# We're going to trash all of our pubkeys and let them be redownloaded.
|
||||||
|
item = '''SELECT value FROM settings WHERE key='version';'''
|
||||||
|
parameters = ''
|
||||||
|
self.cur.execute(item, parameters)
|
||||||
|
currentVersion = int(self.cur.fetchall()[0][0])
|
||||||
|
if currentVersion == 4:
|
||||||
|
self.cur.execute( '''DROP TABLE pubkeys''')
|
||||||
|
self.cur.execute(
|
||||||
|
'''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''' )
|
||||||
|
self.cur.execute(
|
||||||
|
'''delete from inventory where objecttype = 'pubkey';''')
|
||||||
|
item = '''update settings set value=? WHERE key='version';'''
|
||||||
|
parameters = (5,)
|
||||||
|
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? Add it right above this line!
|
# Bitmessage users? Add it right above this line!
|
||||||
|
|
||||||
try:
|
try:
|
||||||
testpayload = '\x00\x00'
|
testpayload = '\x00\x00'
|
||||||
t = ('1234', testpayload, '12345678', 'no')
|
t = ('1234', 1, testpayload, '12345678', 'no')
|
||||||
self.cur.execute( '''INSERT INTO pubkeys VALUES(?,?,?,?)''', t)
|
self.cur.execute( '''INSERT INTO pubkeys VALUES(?,?,?,?,?)''', t)
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
self.cur.execute(
|
self.cur.execute(
|
||||||
'''SELECT transmitdata FROM pubkeys WHERE hash='1234' ''')
|
'''SELECT transmitdata FROM pubkeys WHERE hash='1234' ''')
|
||||||
|
|
|
@ -469,8 +469,8 @@ def decryptAndCheckPubkeyPayload(payload, address):
|
||||||
print 'Pubkey decryption was UNsuccessful due to RIPE mismatch. This shouldn\'t have happened.'
|
print 'Pubkey decryption was UNsuccessful due to RIPE mismatch. This shouldn\'t have happened.'
|
||||||
return 'failed'
|
return 'failed'
|
||||||
|
|
||||||
t = (ripe, signedData, int(time.time()), 'yes')
|
t = (ripe, addressVersion, signedData, int(time.time()), 'yes')
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
|
||||||
return 'successful'
|
return 'successful'
|
||||||
|
|
||||||
Peer = collections.namedtuple('Peer', ['host', 'port'])
|
Peer = collections.namedtuple('Peer', ['host', 'port'])
|
||||||
|
|
Reference in New Issue
Block a user