commit
d53304756e
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
||||||
APP=pybitmessage
|
APP=pybitmessage
|
||||||
VERSION=0.4.0
|
VERSION=0.4.1
|
||||||
RELEASE=1
|
RELEASE=1
|
||||||
ARCH_TYPE=`uname -m`
|
ARCH_TYPE=`uname -m`
|
||||||
PREFIX?=/usr/local
|
PREFIX?=/usr/local
|
||||||
|
|
4
arch.sh
4
arch.sh
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
GIT_APP=PyBitmessage
|
GIT_APP=PyBitmessage
|
||||||
APP=pybitmessage
|
APP=pybitmessage
|
||||||
PREV_VERSION=0.4.0
|
PREV_VERSION=0.4.1
|
||||||
VERSION=0.4.0
|
VERSION=0.4.1
|
||||||
RELEASE=1
|
RELEASE=1
|
||||||
ARCH_TYPE=any
|
ARCH_TYPE=any
|
||||||
CURRDIR=`pwd`
|
CURRDIR=`pwd`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Maintainer: Bob Mottram (4096 bits) <bob@robotics.uk.to>
|
# Maintainer: Bob Mottram (4096 bits) <bob@robotics.uk.to>
|
||||||
pkgname=pybitmessage
|
pkgname=pybitmessage
|
||||||
pkgver=0.4.0
|
pkgver=0.4.1
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide "non-content" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs."
|
pkgdesc="Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide "non-content" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs."
|
||||||
arch=('any')
|
arch=('any')
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
APP=pybitmessage
|
APP=pybitmessage
|
||||||
PREV_VERSION=0.4.0
|
PREV_VERSION=0.4.1
|
||||||
VERSION=0.4.0
|
VERSION=0.4.1
|
||||||
RELEASE=1
|
RELEASE=1
|
||||||
ARCH_TYPE=all
|
ARCH_TYPE=all
|
||||||
DIR=${APP}-${VERSION}
|
DIR=${APP}-${VERSION}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
APP=pybitmessage
|
APP=pybitmessage
|
||||||
PREV_VERSION=0.4.0
|
PREV_VERSION=0.4.1
|
||||||
VERSION=0.4.0
|
VERSION=0.4.1
|
||||||
RELEASE=1
|
RELEASE=1
|
||||||
SOURCEDIR=.
|
SOURCEDIR=.
|
||||||
ARCH_TYPE=`uname -m`
|
ARCH_TYPE=`uname -m`
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
rm -f Makefile rpmpackage/*.spec
|
rm -f Makefile rpmpackage/*.spec
|
||||||
|
|
||||||
packagemonkey -n "PyBitmessage" --version "0.4.0" --dir "." -l "mit" \
|
packagemonkey -n "PyBitmessage" --version "0.4.1" --dir "." -l "mit" \
|
||||||
-e "Bob Mottram (4096 bits) <bob@robotics.uk.to>" \
|
-e "Bob Mottram (4096 bits) <bob@robotics.uk.to>" \
|
||||||
--brief "Send encrypted messages" \
|
--brief "Send encrypted messages" \
|
||||||
--desc "Bitmessage is a P2P communications protocol used to send " \
|
--desc "Bitmessage is a P2P communications protocol used to send " \
|
||||||
|
|
4
puppy.sh
4
puppy.sh
|
@ -1,8 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
APP=pybitmessage
|
APP=pybitmessage
|
||||||
PREV_VERSION=0.4.0
|
PREV_VERSION=0.4.1
|
||||||
VERSION=0.4.0
|
VERSION=0.4.1
|
||||||
RELEASE=1
|
RELEASE=1
|
||||||
BUILDDIR=~/petbuild
|
BUILDDIR=~/petbuild
|
||||||
CURRDIR=`pwd`
|
CURRDIR=`pwd`
|
||||||
|
|
4
rpm.sh
4
rpm.sh
|
@ -1,8 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
APP=pybitmessage
|
APP=pybitmessage
|
||||||
PREV_VERSION=0.4.0
|
PREV_VERSION=0.4.1
|
||||||
VERSION=0.4.0
|
VERSION=0.4.1
|
||||||
RELEASE=1
|
RELEASE=1
|
||||||
SOURCEDIR=.
|
SOURCEDIR=.
|
||||||
ARCH_TYPE=`uname -m`
|
ARCH_TYPE=`uname -m`
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
Name: pybitmessage
|
Name: pybitmessage
|
||||||
Version: 0.4.0
|
Version: 0.4.1
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Send encrypted messages
|
Summary: Send encrypted messages
|
||||||
License: MIT
|
License: MIT
|
||||||
|
|
4
slack.sh
4
slack.sh
|
@ -1,8 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
APP=pybitmessage
|
APP=pybitmessage
|
||||||
PREV_VERSION=0.4.0
|
PREV_VERSION=0.4.1
|
||||||
VERSION=0.4.0
|
VERSION=0.4.1
|
||||||
RELEASE=1
|
RELEASE=1
|
||||||
ARCH_TYPE=`uname -m`
|
ARCH_TYPE=`uname -m`
|
||||||
BUILDDIR=~/slackbuild
|
BUILDDIR=~/slackbuild
|
||||||
|
|
|
@ -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,7 +1,7 @@
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
name = "Bitmessage"
|
name = "Bitmessage"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
mainscript = ["bitmessagemain.py"]
|
mainscript = ["bitmessagemain.py"]
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -3,6 +3,7 @@ import shared
|
||||||
import time
|
import time
|
||||||
from time import strftime, localtime, gmtime
|
from time import strftime, localtime, gmtime
|
||||||
import random
|
import random
|
||||||
|
from subprocess import call # used when the API must execute an outside program
|
||||||
from addresses import *
|
from addresses import *
|
||||||
import highlevelcrypto
|
import highlevelcrypto
|
||||||
import proofofwork
|
import proofofwork
|
||||||
|
@ -11,6 +12,7 @@ from class_addressGenerator import pointMult
|
||||||
import tr
|
import tr
|
||||||
from debug import logger
|
from debug import logger
|
||||||
from helper_sql import *
|
from helper_sql import *
|
||||||
|
import helper_inbox
|
||||||
|
|
||||||
# This thread, of which there is only one, does the heavy lifting:
|
# This thread, of which there is only one, does the heavy lifting:
|
||||||
# calculating POWs.
|
# calculating POWs.
|
||||||
|
@ -156,6 +158,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,49 +203,39 @@ 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)
|
print '(For pubkey message) Doing proof of work...'
|
||||||
print '(For pubkey message) Doing proof of work...'
|
initialHash = hashlib.sha512(payload).digest()
|
||||||
initialHash = hashlib.sha512(payload).digest()
|
trialValue, nonce = proofofwork.run(target, initialHash)
|
||||||
trialValue, nonce = proofofwork.run(target, initialHash)
|
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
|
||||||
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
|
|
||||||
|
|
||||||
payload = pack('>Q', nonce) + payload
|
payload = pack('>Q', nonce) + payload
|
||||||
inventoryHash = calculateInventoryHash(payload)
|
inventoryHash = calculateInventoryHash(payload)
|
||||||
objectType = 'pubkey'
|
objectType = 'pubkey'
|
||||||
shared.inventory[inventoryHash] = (
|
shared.inventory[inventoryHash] = (
|
||||||
objectType, streamNumber, payload, embeddedTime,'')
|
objectType, streamNumber, payload, embeddedTime,'')
|
||||||
shared.inventorySets[streamNumber].add(inventoryHash)
|
shared.inventorySets[streamNumber].add(inventoryHash)
|
||||||
|
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'broadcasting inv with hash:', inventoryHash.encode('hex')
|
print 'broadcasting inv with hash:', inventoryHash.encode('hex')
|
||||||
|
|
||||||
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,52 +280,41 @@ 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
|
# first. We'll also tag, unencrypted, the pubkey with part of the hash
|
||||||
# first. We'll also tag, unencrypted, the pubkey with part of the hash
|
# so that nodes know which pubkey object to try to decrypt when they
|
||||||
# so that nodes know which pubkey object to try to decrypt when they
|
# want to send a message.
|
||||||
# want to send a message.
|
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
||||||
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()
|
||||||
addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()
|
payload += doubleHashOfAddressData[32:] # the tag
|
||||||
payload += doubleHashOfAddressData[32:] # the tag
|
privEncryptionKey = doubleHashOfAddressData[:32]
|
||||||
privEncryptionKey = doubleHashOfAddressData[:32]
|
pubEncryptionKey = pointMult(privEncryptionKey)
|
||||||
pubEncryptionKey = pointMult(privEncryptionKey)
|
payload += highlevelcrypto.encrypt(
|
||||||
payload += highlevelcrypto.encrypt(
|
dataToEncrypt, pubEncryptionKey.encode('hex'))
|
||||||
dataToEncrypt, pubEncryptionKey.encode('hex'))
|
|
||||||
|
|
||||||
# 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)
|
||||||
print '(For pubkey message) Doing proof of work...'
|
print '(For pubkey message) Doing proof of work...'
|
||||||
initialHash = hashlib.sha512(payload).digest()
|
initialHash = hashlib.sha512(payload).digest()
|
||||||
trialValue, nonce = proofofwork.run(target, initialHash)
|
trialValue, nonce = proofofwork.run(target, initialHash)
|
||||||
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
|
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
|
||||||
|
|
||||||
payload = pack('>Q', nonce) + payload
|
payload = pack('>Q', nonce) + payload
|
||||||
inventoryHash = calculateInventoryHash(payload)
|
inventoryHash = calculateInventoryHash(payload)
|
||||||
objectType = 'pubkey'
|
objectType = 'pubkey'
|
||||||
shared.inventory[inventoryHash] = (
|
shared.inventory[inventoryHash] = (
|
||||||
objectType, streamNumber, payload, embeddedTime, doubleHashOfAddressData[32:])
|
objectType, streamNumber, payload, embeddedTime, doubleHashOfAddressData[32:])
|
||||||
shared.inventorySets[streamNumber].add(inventoryHash)
|
shared.inventorySets[streamNumber].add(inventoryHash)
|
||||||
|
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'broadcasting inv with hash:', inventoryHash.encode('hex')
|
print 'broadcasting inv with hash:', inventoryHash.encode('hex')
|
||||||
|
|
||||||
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 +354,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 +365,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 +439,14 @@ 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):
|
||||||
|
sqlExecute(
|
||||||
|
'''UPDATE sent SET status='doingmsgpow' WHERE toaddress=? AND status='msgqueued' ''',
|
||||||
|
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,130 +510,154 @@ 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
|
||||||
# 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
|
|
||||||
# sendMsg function will appear to freeze. This can happen if the
|
|
||||||
# user sends a message but doesn't let the POW function finish,
|
|
||||||
# then leaves their client off for a long time which could cause
|
|
||||||
# the needed pubkey to expire and be deleted.
|
|
||||||
queryreturn = sqlQuery(
|
|
||||||
'''SELECT hash FROM pubkeys WHERE hash=? ''',
|
|
||||||
toripe)
|
|
||||||
if queryreturn == [] and toripe not in shared.neededPubkeys:
|
|
||||||
# We no longer have the needed pubkey and we haven't requested
|
|
||||||
# it.
|
|
||||||
with shared.printLock:
|
|
||||||
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'))
|
|
||||||
|
|
||||||
sqlExecute(
|
|
||||||
'''UPDATE sent SET status='msgqueued' WHERE toaddress=? AND status='doingmsgpow' ''', toaddress)
|
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByHash', (
|
|
||||||
toripe, tr.translateText("MainWindow",'Sending a request for the recipient\'s encryption key.'))))
|
|
||||||
self.requestPubKey(toaddress)
|
|
||||||
continue
|
|
||||||
shared.ackdataForWhichImWatching[ackdata] = 0
|
|
||||||
toStatus, toAddressVersionNumber, toStreamNumber, toHash = decodeAddress(
|
toStatus, toAddressVersionNumber, toStreamNumber, toHash = decodeAddress(
|
||||||
toaddress)
|
toaddress)
|
||||||
fromStatus, fromAddressVersionNumber, fromStreamNumber, fromHash = decodeAddress(
|
fromStatus, fromAddressVersionNumber, fromStreamNumber, fromHash = decodeAddress(
|
||||||
fromaddress)
|
fromaddress)
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
|
||||||
ackdata, tr.translateText("MainWindow", "Looking up the receiver\'s public key"))))
|
|
||||||
with shared.printLock:
|
|
||||||
print 'Found a message in our database that needs to be sent with this pubkey.'
|
|
||||||
print 'First 150 characters of message:', repr(message[:150])
|
|
||||||
|
|
||||||
|
if not shared.config.has_section(toaddress):
|
||||||
# mark the pubkey as 'usedpersonally' so that we don't ever delete
|
# There is a remote possibility that we may no longer have the
|
||||||
# it.
|
# recipient's pubkey. Let us make sure we still have it or else the
|
||||||
sqlExecute(
|
# sendMsg function will appear to freeze. This can happen if the
|
||||||
'''UPDATE pubkeys SET usedpersonally='yes' WHERE hash=?''',
|
# user sends a message but doesn't let the POW function finish,
|
||||||
toripe)
|
# then leaves their client off for a long time which could cause
|
||||||
# Let us fetch the recipient's public key out of our database. If
|
# the needed pubkey to expire and be deleted.
|
||||||
# the required proof of work difficulty is too hard then we'll
|
queryreturn = sqlQuery(
|
||||||
# abort.
|
'''SELECT hash FROM pubkeys WHERE hash=? AND addressversion=?''',
|
||||||
queryreturn = sqlQuery(
|
toripe,
|
||||||
'SELECT transmitdata FROM pubkeys WHERE hash=?',
|
toAddressVersionNumber)
|
||||||
toripe)
|
if queryreturn == [] and toripe not in shared.neededPubkeys:
|
||||||
if queryreturn == []:
|
# We no longer have the needed pubkey and we haven't requested
|
||||||
with shared.printLock:
|
# it.
|
||||||
sys.stderr.write(
|
with shared.printLock:
|
||||||
'(within sendMsg) The needed pubkey was not found. This should never happen. Aborting send.\n')
|
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'))
|
||||||
return
|
sqlExecute(
|
||||||
for row in queryreturn:
|
'''UPDATE sent SET status='doingpubkeypow' WHERE toaddress=? AND status='doingmsgpow' ''', toaddress)
|
||||||
pubkeyPayload, = row
|
shared.UISignalQueue.put(('updateSentItemStatusByHash', (
|
||||||
|
toripe, tr.translateText("MainWindow",'Sending a request for the recipient\'s encryption key.'))))
|
||||||
# The pubkey message is stored the way we originally received it
|
self.requestPubKey(toaddress)
|
||||||
# which means that we need to read beyond things like the nonce and
|
|
||||||
# time to get to the actual public keys.
|
|
||||||
if toAddressVersionNumber <= 3:
|
|
||||||
readPosition = 8 # to bypass the nonce
|
|
||||||
elif toAddressVersionNumber >= 4:
|
|
||||||
readPosition = 0 # the nonce is not included here so we don't need to skip over it.
|
|
||||||
pubkeyEmbeddedTime, = unpack(
|
|
||||||
'>I', pubkeyPayload[readPosition:readPosition + 4])
|
|
||||||
# This section is used for the transition from 32 bit time to 64
|
|
||||||
# bit time in the protocol.
|
|
||||||
if pubkeyEmbeddedTime == 0:
|
|
||||||
pubkeyEmbeddedTime, = unpack(
|
|
||||||
'>Q', pubkeyPayload[readPosition:readPosition + 8])
|
|
||||||
readPosition += 8
|
|
||||||
else:
|
|
||||||
readPosition += 4
|
|
||||||
readPosition += 1 # to bypass the address version whose length is definitely 1
|
|
||||||
streamNumber, streamNumberLength = decodeVarint(
|
|
||||||
pubkeyPayload[readPosition:readPosition + 10])
|
|
||||||
readPosition += streamNumberLength
|
|
||||||
behaviorBitfield = pubkeyPayload[readPosition:readPosition + 4]
|
|
||||||
# Mobile users may ask us to include their address's RIPE hash on a message
|
|
||||||
# unencrypted. Before we actually do it the sending human must check a box
|
|
||||||
# in the settings menu to allow it.
|
|
||||||
if shared.isBitSetWithinBitfield(behaviorBitfield,30): # if receiver is a mobile device who expects that their address RIPE is included unencrypted on the front of the message..
|
|
||||||
if not shared.safeConfigGetBoolean('bitmessagesettings','willinglysendtomobile'): # if we are Not willing to include the receiver's RIPE hash on the message..
|
|
||||||
logger.info('The receiver is a mobile user but the sender (you) has not selected that you are willing to send to mobiles. Aborting send.')
|
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1').arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))))
|
|
||||||
# if the human changes their setting and then sends another message or restarts their client, this one will send at that time.
|
|
||||||
continue
|
continue
|
||||||
readPosition += 4 # to bypass the bitfield of behaviors
|
shared.ackdataForWhichImWatching[ackdata] = 0
|
||||||
# pubSigningKeyBase256 =
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||||
# pubkeyPayload[readPosition:readPosition+64] #We don't use this
|
ackdata, tr.translateText("MainWindow", "Looking up the receiver\'s public key"))))
|
||||||
# key for anything here.
|
with shared.printLock:
|
||||||
readPosition += 64
|
print 'Sending a message. First 150 characters of message:', repr(message[:150])
|
||||||
pubEncryptionKeyBase256 = pubkeyPayload[
|
|
||||||
readPosition:readPosition + 64]
|
|
||||||
readPosition += 64
|
# mark the pubkey as 'usedpersonally' so that we don't ever delete
|
||||||
|
# it.
|
||||||
# Let us fetch the amount of work required by the recipient.
|
sqlExecute(
|
||||||
if toAddressVersionNumber == 2:
|
'''UPDATE pubkeys SET usedpersonally='yes' WHERE hash=? and addressversion=?''',
|
||||||
|
toripe,
|
||||||
|
toAddressVersionNumber)
|
||||||
|
# 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
|
||||||
|
# abort.
|
||||||
|
queryreturn = sqlQuery(
|
||||||
|
'SELECT transmitdata FROM pubkeys WHERE hash=? and addressversion=?',
|
||||||
|
toripe,
|
||||||
|
toAddressVersionNumber)
|
||||||
|
if queryreturn == []:
|
||||||
|
with shared.printLock:
|
||||||
|
sys.stderr.write(
|
||||||
|
'(within sendMsg) The needed pubkey was not found. This should never happen. Aborting send.\n')
|
||||||
|
|
||||||
|
return
|
||||||
|
for row in queryreturn:
|
||||||
|
pubkeyPayload, = row
|
||||||
|
|
||||||
|
# The pubkey message is stored the way we originally received it
|
||||||
|
# which means that we need to read beyond things like the nonce and
|
||||||
|
# time to get to the actual public keys.
|
||||||
|
if toAddressVersionNumber <= 3:
|
||||||
|
readPosition = 8 # to bypass the nonce
|
||||||
|
elif toAddressVersionNumber >= 4:
|
||||||
|
readPosition = 0 # the nonce is not included here so we don't need to skip over it.
|
||||||
|
pubkeyEmbeddedTime, = unpack(
|
||||||
|
'>I', pubkeyPayload[readPosition:readPosition + 4])
|
||||||
|
# This section is used for the transition from 32 bit time to 64
|
||||||
|
# bit time in the protocol.
|
||||||
|
if pubkeyEmbeddedTime == 0:
|
||||||
|
pubkeyEmbeddedTime, = unpack(
|
||||||
|
'>Q', pubkeyPayload[readPosition:readPosition + 8])
|
||||||
|
readPosition += 8
|
||||||
|
else:
|
||||||
|
readPosition += 4
|
||||||
|
readPosition += 1 # to bypass the address version whose length is definitely 1
|
||||||
|
streamNumber, streamNumberLength = decodeVarint(
|
||||||
|
pubkeyPayload[readPosition:readPosition + 10])
|
||||||
|
readPosition += streamNumberLength
|
||||||
|
behaviorBitfield = pubkeyPayload[readPosition:readPosition + 4]
|
||||||
|
# Mobile users may ask us to include their address's RIPE hash on a message
|
||||||
|
# unencrypted. Before we actually do it the sending human must check a box
|
||||||
|
# in the settings menu to allow it.
|
||||||
|
if shared.isBitSetWithinBitfield(behaviorBitfield,30): # if receiver is a mobile device who expects that their address RIPE is included unencrypted on the front of the message..
|
||||||
|
if not shared.safeConfigGetBoolean('bitmessagesettings','willinglysendtomobile'): # if we are Not willing to include the receiver's RIPE hash on the message..
|
||||||
|
logger.info('The receiver is a mobile user but the sender (you) has not selected that you are willing to send to mobiles. Aborting send.')
|
||||||
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1').arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))))
|
||||||
|
# if the human changes their setting and then sends another message or restarts their client, this one will send at that time.
|
||||||
|
continue
|
||||||
|
readPosition += 4 # to bypass the bitfield of behaviors
|
||||||
|
# pubSigningKeyBase256 =
|
||||||
|
# pubkeyPayload[readPosition:readPosition+64] #We don't use this
|
||||||
|
# key for anything here.
|
||||||
|
readPosition += 64
|
||||||
|
pubEncryptionKeyBase256 = pubkeyPayload[
|
||||||
|
readPosition:readPosition + 64]
|
||||||
|
readPosition += 64
|
||||||
|
|
||||||
|
# Let us fetch the amount of work required by the recipient.
|
||||||
|
if toAddressVersionNumber == 2:
|
||||||
|
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
|
||||||
|
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
||||||
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||||
|
ackdata, tr.translateText("MainWindow", "Doing work necessary to send message.\nThere is no required difficulty for version 2 addresses like this."))))
|
||||||
|
elif toAddressVersionNumber >= 3:
|
||||||
|
requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = decodeVarint(
|
||||||
|
pubkeyPayload[readPosition:readPosition + 10])
|
||||||
|
readPosition += varintLength
|
||||||
|
requiredPayloadLengthExtraBytes, varintLength = decodeVarint(
|
||||||
|
pubkeyPayload[readPosition:readPosition + 10])
|
||||||
|
readPosition += varintLength
|
||||||
|
if requiredAverageProofOfWorkNonceTrialsPerByte < shared.networkDefaultProofOfWorkNonceTrialsPerByte: # We still have to meet a minimum POW difficulty regardless of what they say is allowed in order to get our message to propagate through the network.
|
||||||
|
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
|
||||||
|
if requiredPayloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
|
||||||
|
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
||||||
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Doing work necessary to send message.\nReceiver\'s required difficulty: %1 and %2").arg(str(float(
|
||||||
|
requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte)).arg(str(float(requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes)))))
|
||||||
|
if status != 'forcepow':
|
||||||
|
if (requiredAverageProofOfWorkNonceTrialsPerByte > shared.config.getint('bitmessagesettings', 'maxacceptablenoncetrialsperbyte') and shared.config.getint('bitmessagesettings', 'maxacceptablenoncetrialsperbyte') != 0) or (requiredPayloadLengthExtraBytes > shared.config.getint('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') and shared.config.getint('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') != 0):
|
||||||
|
# The demanded difficulty is more than we are willing
|
||||||
|
# to do.
|
||||||
|
sqlExecute(
|
||||||
|
'''UPDATE sent SET status='toodifficult' WHERE ackdata=? ''',
|
||||||
|
ackdata)
|
||||||
|
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')))))
|
||||||
|
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
|
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
|
||||||
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||||
ackdata, tr.translateText("MainWindow", "Doing work necessary to send message.\nThere is no required difficulty for version 2 addresses like this."))))
|
ackdata, tr.translateText("MainWindow", "Doing work necessary to send message."))))
|
||||||
elif toAddressVersionNumber >= 3:
|
|
||||||
requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = decodeVarint(
|
|
||||||
pubkeyPayload[readPosition:readPosition + 10])
|
|
||||||
readPosition += varintLength
|
|
||||||
requiredPayloadLengthExtraBytes, varintLength = decodeVarint(
|
|
||||||
pubkeyPayload[readPosition:readPosition + 10])
|
|
||||||
readPosition += varintLength
|
|
||||||
if requiredAverageProofOfWorkNonceTrialsPerByte < shared.networkDefaultProofOfWorkNonceTrialsPerByte: # We still have to meet a minimum POW difficulty regardless of what they say is allowed in order to get our message to propagate through the network.
|
|
||||||
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
|
|
||||||
if requiredPayloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
|
|
||||||
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
|
||||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Doing work necessary to send message.\nReceiver\'s required difficulty: %1 and %2").arg(str(float(
|
|
||||||
requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte)).arg(str(float(requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes)))))
|
|
||||||
if status != 'forcepow':
|
|
||||||
if (requiredAverageProofOfWorkNonceTrialsPerByte > shared.config.getint('bitmessagesettings', 'maxacceptablenoncetrialsperbyte') and shared.config.getint('bitmessagesettings', 'maxacceptablenoncetrialsperbyte') != 0) or (requiredPayloadLengthExtraBytes > shared.config.getint('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') and shared.config.getint('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') != 0):
|
|
||||||
# The demanded difficulty is more than we are willing
|
|
||||||
# to do.
|
|
||||||
sqlExecute(
|
|
||||||
'''UPDATE sent SET status='toodifficult' WHERE ackdata=? ''',
|
|
||||||
ackdata)
|
|
||||||
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')))))
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
||||||
|
@ -748,13 +759,13 @@ class singleWorker(threading.Thread):
|
||||||
subject + '\n' + 'Body:' + message
|
subject + '\n' + 'Body:' + message
|
||||||
payload += encodeVarint(len(messageToTransmit))
|
payload += encodeVarint(len(messageToTransmit))
|
||||||
payload += messageToTransmit
|
payload += messageToTransmit
|
||||||
if shared.safeConfigGetBoolean(toaddress, 'chan'):
|
if shared.config.has_section(toaddress):
|
||||||
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 ourselves or 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,26 +806,48 @@ 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')
|
||||||
shared.broadcastToSendDataQueues((
|
shared.broadcastToSendDataQueues((
|
||||||
streamNumber, 'advertiseobject', inventoryHash))
|
toStreamNumber, 'advertiseobject', inventoryHash))
|
||||||
|
|
||||||
# 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'
|
||||||
sqlExecute('''UPDATE sent SET msgid=?, status=? WHERE ackdata=?''',
|
sqlExecute('''UPDATE sent SET msgid=?, status=? WHERE ackdata=?''',
|
||||||
inventoryHash,newStatus,ackdata)
|
inventoryHash,newStatus,ackdata)
|
||||||
|
|
||||||
|
# If we are sending to ourselves or a chan, let's put the message in
|
||||||
|
# our own inbox.
|
||||||
|
if shared.config.has_section(toaddress):
|
||||||
|
t = (inventoryHash, toaddress, fromaddress, subject, int(
|
||||||
|
time.time()), message, 'inbox', 2, 0)
|
||||||
|
helper_inbox.insert(t)
|
||||||
|
|
||||||
|
shared.UISignalQueue.put(('displayNewInboxMessage', (
|
||||||
|
inventoryHash, toaddress, fromaddress, subject, message)))
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# has arrived.
|
||||||
|
if shared.safeConfigGetBoolean('bitmessagesettings', 'apienabled'):
|
||||||
|
try:
|
||||||
|
apiNotifyPath = shared.config.get(
|
||||||
|
'bitmessagesettings', 'apinotifypath')
|
||||||
|
except:
|
||||||
|
apiNotifyPath = ''
|
||||||
|
if apiNotifyPath != '':
|
||||||
|
call([apiNotifyPath, "newMessage"])
|
||||||
|
|
||||||
def requestPubKey(self, toAddress):
|
def requestPubKey(self, toAddress):
|
||||||
toStatus, addressVersionNumber, streamNumber, ripe = decodeAddress(
|
toStatus, addressVersionNumber, streamNumber, ripe = decodeAddress(
|
||||||
toAddress)
|
toAddress)
|
||||||
|
|
|
@ -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' ''')
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
softwareVersion = '0.4.0'
|
softwareVersion = '0.4.1'
|
||||||
verbose = 1
|
verbose = 1
|
||||||
maximumAgeOfAnObjectThatIAmWillingToAccept = 216000 # Equals two days and 12 hours.
|
maximumAgeOfAnObjectThatIAmWillingToAccept = 216000 # Equals two days and 12 hours.
|
||||||
lengthOfTimeToLeaveObjectsInInventory = 237600 # Equals two days and 18 hours. This should be longer than maximumAgeOfAnObjectThatIAmWillingToAccept so that we don't process messages twice.
|
lengthOfTimeToLeaveObjectsInInventory = 237600 # Equals two days and 18 hours. This should be longer than maximumAgeOfAnObjectThatIAmWillingToAccept so that we don't process messages twice.
|
||||||
|
@ -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'])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user