From 2b17991ee4c9b33a69e3b51ff0a4abb0ae501f9e Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 29 Jul 2013 22:19:15 +0100 Subject: [PATCH 1/8] -aChanged version to 0.3.5 --- .../{pybitmessage-0.3.4-1.ebuild => pybitmessage-0.3.5-1.ebuild} | 0 puppypackage/pybitmessage-0.3.4.pet.specs | 1 - puppypackage/pybitmessage-0.3.5.pet.specs | 1 + 3 files changed, 1 insertion(+), 1 deletion(-) rename ebuildpackage/{pybitmessage-0.3.4-1.ebuild => pybitmessage-0.3.5-1.ebuild} (100%) delete mode 100644 puppypackage/pybitmessage-0.3.4.pet.specs create mode 100644 puppypackage/pybitmessage-0.3.5.pet.specs diff --git a/ebuildpackage/pybitmessage-0.3.4-1.ebuild b/ebuildpackage/pybitmessage-0.3.5-1.ebuild similarity index 100% rename from ebuildpackage/pybitmessage-0.3.4-1.ebuild rename to ebuildpackage/pybitmessage-0.3.5-1.ebuild diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs deleted file mode 100644 index aac180a9..00000000 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ /dev/null @@ -1 +0,0 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|5.8M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| diff --git a/puppypackage/pybitmessage-0.3.5.pet.specs b/puppypackage/pybitmessage-0.3.5.pet.specs new file mode 100644 index 00000000..939294e4 --- /dev/null +++ b/puppypackage/pybitmessage-0.3.5.pet.specs @@ -0,0 +1 @@ +pybitmessage-0.3.5-1|PyBitmessage|0.3.5|1|Internet;mailnews;|7.2M||pybitmessage-0.3.5-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| From 97df9e04f13c8450e62d97f0fe50d1264f39488b Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 29 Jul 2013 22:22:17 +0100 Subject: [PATCH 2/8] Changed version to 0.3.5 --- arch.sh | 4 ++-- archpackage/PKGBUILD | 2 +- debian.sh | 2 +- debian/changelog | 28 ++++++++++++++++++++++++++++ debian/rules | 0 ebuild.sh | 4 ++-- generate.sh | 2 +- puppy.sh | 4 ++-- rpm.sh | 4 ++-- rpmpackage/pybitmessage.spec | 27 ++++++++++++++++++++++++++- slack.sh | 4 ++-- 11 files changed, 67 insertions(+), 14 deletions(-) mode change 100644 => 100755 debian.sh mode change 100644 => 100755 debian/rules diff --git a/arch.sh b/arch.sh index 77332d09..0ccc45b3 100755 --- a/arch.sh +++ b/arch.sh @@ -1,8 +1,8 @@ #!/bin/bash APP=pybitmessage -PREV_VERSION=0.3.4 -VERSION=0.3.4 +PREV_VERSION=0.3.5 +VERSION=0.3.5 RELEASE=1 ARCH_TYPE=`uname -m` CURRDIR=`pwd` diff --git a/archpackage/PKGBUILD b/archpackage/PKGBUILD index e36c1a11..efbf33e2 100644 --- a/archpackage/PKGBUILD +++ b/archpackage/PKGBUILD @@ -1,6 +1,6 @@ # Maintainer: Bob Mottram (4096 bits) pkgname=pybitmessage -pkgver=0.3.4 +pkgver=0.3.5 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." arch=('i686' 'x86_64') diff --git a/debian.sh b/debian.sh old mode 100644 new mode 100755 index 2d924251..a4d6882e --- a/debian.sh +++ b/debian.sh @@ -2,7 +2,7 @@ APP=pybitmessage PREV_VERSION=0.3.4 -VERSION=0.3.4 +VERSION=0.3.5 RELEASE=1 ARCH_TYPE=`uname -m` DIR=${APP}-${VERSION} diff --git a/debian/changelog b/debian/changelog index b6e8adbf..711f6488 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,31 @@ +pybitmessage (0.3.5-1) raring; urgency=low + + * Inbox message retrieval API functions now also returns read status + * Added right-click option to mark a message as unread + * Prompt user to connect at first startup + * Install into /usr/local by default + * Add a missing rm -f to the uninstall task. + * Use system text color for enabled addresses instead of black + * Added support for Chans + * Start storing msgid in sent table + * Optionally play sounds on connection/disconnection or when messages arrive + * Adding configuration option to listen for connections when using SOCKS + * Added packaging for multiple distros (Arch, Puppy, Slack, etc.) + * Added Russian translation + * Added search support in the UI + * Added 'make uninstall' + * To improve OSX support, use PKCS5_PBKDF2_HMAC_SHA1 if PKCS5_PBKDF2_HMAC is unavailable + * Added better warnings for OSX users who are using old versions of Python + * Repaired debian packaging + * Altered Makefile to avoid needing to chase changes + * Added logger module + * Added bgWorker class for background tasks + * Added use of gevent module + * On not-Windows: Fix insecure keyfile permissions + * Fix 100% CPU usage issue + + -- Bob Mottram (4096 bits) Mon, 29 July 2013 22:11:00 +0100 + pybitmessage (0.3.4-1) raring; urgency=low * Switched addr, msg, broadcast, and getpubkey message types diff --git a/debian/rules b/debian/rules old mode 100644 new mode 100755 diff --git a/ebuild.sh b/ebuild.sh index 1a3d16e0..ed7f1903 100755 --- a/ebuild.sh +++ b/ebuild.sh @@ -1,8 +1,8 @@ #!/bin/bash APP=pybitmessage -PREV_VERSION=0.3.4 -VERSION=0.3.4 +PREV_VERSION=0.3.5 +VERSION=0.3.5 RELEASE=1 SOURCEDIR=. ARCH_TYPE=`uname -m` diff --git a/generate.sh b/generate.sh index 173e3c79..d21f4d83 100755 --- a/generate.sh +++ b/generate.sh @@ -4,4 +4,4 @@ rm -f Makefile rpmpackage/*.spec -packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "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." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs, gst123" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip, gst123" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl, gst123" --suggestsarch "python2-gevent" --pythonversion 2 --dependsebuild "dev-libs/openssl, dev-python/PyQt4[${PYTHON_USEDEP}]" --buildebuild "\${PYTHON_DEPS}" --pythonreq "sqlite" --repository "https://github.com/Bitmessage/PyBitmessage.git" +packagemonkey -n "PyBitmessage" --version "0.3.5" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "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." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs, gst123" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip, gst123" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl, gst123" --suggestsarch "python2-gevent" --pythonversion 2 --dependsebuild "dev-libs/openssl, dev-python/PyQt4[${PYTHON_USEDEP}]" --buildebuild "\${PYTHON_DEPS}" --pythonreq "sqlite" --repository "https://github.com/Bitmessage/PyBitmessage.git" diff --git a/puppy.sh b/puppy.sh index efe1d7da..5f2fcae0 100755 --- a/puppy.sh +++ b/puppy.sh @@ -1,8 +1,8 @@ #!/bin/bash APP=pybitmessage -PREV_VERSION=0.3.4 -VERSION=0.3.4 +PREV_VERSION=0.3.5 +VERSION=0.3.5 RELEASE=1 BUILDDIR=~/petbuild CURRDIR=`pwd` diff --git a/rpm.sh b/rpm.sh index 8269ed9c..09064280 100755 --- a/rpm.sh +++ b/rpm.sh @@ -1,8 +1,8 @@ #!/bin/bash APP=pybitmessage -PREV_VERSION=0.3.4 -VERSION=0.3.4 +PREV_VERSION=0.3.5 +VERSION=0.3.5 RELEASE=1 SOURCEDIR=. ARCH_TYPE=`uname -m` diff --git a/rpmpackage/pybitmessage.spec b/rpmpackage/pybitmessage.spec index 9c12661a..b15bd586 100644 --- a/rpmpackage/pybitmessage.spec +++ b/rpmpackage/pybitmessage.spec @@ -1,5 +1,5 @@ Name: pybitmessage -Version: 0.3.4 +Version: 0.3.5 Release: 1%{?dist} Summary: Send encrypted messages License: MIT @@ -68,6 +68,31 @@ make install -B DESTDIR=%{buildroot} PREFIX=/usr %attr(644,root,root) /usr/share/icons/hicolor/24x24/apps/%{name}.png %changelog +* Mon Jul 29 2013 Bob Mottram (4096 bits) - 0.3.5-1 +- Inbox message retrieval API functions now also returns read status +- Added right-click option to mark a message as unread +- Prompt user to connect at first startup +- Install into /usr/local by default +- Add a missing rm -f to the uninstall task. +- Use system text color for enabled addresses instead of black +- Added support for Chans +- Start storing msgid in sent table +- Optionally play sounds on connection/disconnection or when messages arrive +- Adding configuration option to listen for connections when using SOCKS +- Added packaging for multiple distros (Arch, Puppy, Slack, etc.) +- Added Russian translation +- Added search support in the UI +- Added 'make uninstall' +- To improve OSX support, use PKCS5_PBKDF2_HMAC_SHA1 if PKCS5_PBKDF2_HMAC is unavailable +- Added better warnings for OSX users who are using old versions of Python +- Repaired debian packaging +- Altered Makefile to avoid needing to chase changes +- Added logger module +- Added bgWorker class for background tasks +- Added use of gevent module +- On not-Windows: Fix insecure keyfile permissions +- Fix 100% CPU usage issue + * Sun Jun 30 2013 Bob Mottram (4096 bits) - 0.3.4-1 - Switched addr, msg, broadcast, and getpubkey message types to 8 byte time. Last remaining type is pubkey. diff --git a/slack.sh b/slack.sh index 5d826e0b..112488c0 100755 --- a/slack.sh +++ b/slack.sh @@ -1,8 +1,8 @@ #!/bin/bash APP=pybitmessage -PREV_VERSION=0.3.4 -VERSION=0.3.4 +PREV_VERSION=0.3.5 +VERSION=0.3.5 RELEASE=1 ARCH_TYPE=`uname -m` BUILDDIR=~/slackbuild From 29be0d55db7909af160730fff43e71e001d53b2d Mon Sep 17 00:00:00 2001 From: gnumac Date: Tue, 30 Jul 2013 00:24:04 +0000 Subject: [PATCH 3/8] Update build_osx.py --- src/build_osx.py | 86 +++++++----------------------------------------- 1 file changed, 11 insertions(+), 75 deletions(-) diff --git a/src/build_osx.py b/src/build_osx.py index dd3d7259..901d1ca6 100644 --- a/src/build_osx.py +++ b/src/build_osx.py @@ -1,80 +1,16 @@ -""" -py2app/py2exe build script for Bitmessage - -Usage (Mac OS X): - python setup.py py2app - -Usage (Windows): - python setup.py py2exe -""" - -import sys, os, shutil, re -from setuptools import setup # @UnresolvedImport - +from setuptools import setup name = "Bitmessage" -mainscript = 'bitmessagemain.py' -version = "0.3.5" - -if sys.platform == 'darwin': - extra_options = dict( - setup_requires=['py2app'], - app=[mainscript], - options=dict(py2app=dict(argv_emulation=True, - includes = ['PyQt4.QtCore','PyQt4.QtGui', 'sip', 'sqlite3'], - packages = ['bitmessageqt'], - frameworks = ['/usr/local/opt/openssl/lib/libcrypto.dylib'], - iconfile='images/bitmessage.icns', - resources=["images"])), - ) -elif sys.platform == 'win32': - extra_options = dict( - setup_requires=['py2exe'], - app=[mainscript], - ) -else: - extra_options = dict( - # Normally unix-like platforms will use "setup.py install" - # and install the main script as such - scripts=[mainscript], - ) +version = "0.3.4" +mainscript = ["bitmessagemain.py"] setup( - name = name, - version = version, - **extra_options + name = name, + version = version, + app = mainscript, + setup_requires = ["py2app"], + options = dict(py2app=dict( + resources = ["images"], + iconfile = "images/bitmessage.icns" + )) ) -from distutils import dir_util -import glob - -if sys.platform == 'darwin': - resource = "dist/" + name + ".app/Contents/Resources/" - framework = "dist/" + name + ".app/Contents/Frameworks/" - - # The pyElliptive module only works with hardcoded libcrypto paths so rename it so it can actually find it. - libs = glob.glob(framework + "libcrypto*.dylib") - for lib in libs: - os.rename(lib, framework + "libcrypto.dylib") - break - - # Try to locate qt_menu - # Let's try the port version first! - if os.path.isfile("/opt/local/lib/Resources/qt_menu.nib"): - qt_menu_location = "/opt/local/lib/Resources/qt_menu.nib" - else: - # No dice? Then let's try the brew version - qt_menu_location = os.popen("find /usr/local/Cellar -name qt_menu.nib | tail -n 1").read() - qt_menu_location = re.sub('\n','', qt_menu_location) - - if(len(qt_menu_location) == 0): - print "Sorry couldn't find your qt_menu.nib this probably won't work" - else: - print "Found your qib: " + qt_menu_location - - # Need to include a copy of qt_menu.nib - shutil.copytree(qt_menu_location, resource + "qt_menu.nib") - # Need to touch qt.conf to avoid loading 2 sets of Qt libraries - fname = resource + "qt.conf" - with file(fname, 'a'): - os.utime(fname, None) - From fbbc65738055b7f61aab89e0715bb09ef531c593 Mon Sep 17 00:00:00 2001 From: "Grant T. Olson" Date: Tue, 30 Jul 2013 19:41:40 -0400 Subject: [PATCH 4/8] Add listSubscriptions method to API --- src/bitmessagemain.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index 51b9a82d..add370a0 100644 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -677,6 +677,23 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): shared.UISignalQueue.put(('rerenderInboxFromLabels', '')) shared.UISignalQueue.put(('rerenderSubscriptions', '')) return 'Deleted subscription if it existed.' + elif method == 'listSubscriptions': + if len(params) != 0: + return "API Error 0000: I don't accept parameters!" + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put('''SELECT label, address, enabled FROM subscriptions''') + shared.sqlSubmitQueue.put('') + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + data = '{"subscriptions":[' + for row in queryreturn: + label, address, enabled = row + label = shared.fixPotentiallyInvalidUTF8Data(label) + if len(data) > 20: + data += ',' + data += json.dumps({'label':label.encode('base64'), 'address': address, 'enabled': enabled == 1}, indent=4, separators=(',',': ')) + data += ']}' + return data elif method == 'clientStatus': return '{ "networkConnections" : "%s" }' % str(len(shared.connectedHostsList)) else: From 8c0450ce3959cdf17461cf4dcbe2557bccc3d2c9 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Tue, 30 Jul 2013 19:53:09 -0400 Subject: [PATCH 5/8] having parameters here doesn't hurt anything --- src/bitmessagemain.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index add370a0..3fc5a3ee 100644 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -678,8 +678,6 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): shared.UISignalQueue.put(('rerenderSubscriptions', '')) return 'Deleted subscription if it existed.' elif method == 'listSubscriptions': - if len(params) != 0: - return "API Error 0000: I don't accept parameters!" shared.sqlLock.acquire() shared.sqlSubmitQueue.put('''SELECT label, address, enabled FROM subscriptions''') shared.sqlSubmitQueue.put('') From cddfe2c44fb10cda3093e3c45be1e7dfe2323734 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Wed, 31 Jul 2013 12:08:56 -0400 Subject: [PATCH 6/8] Only return one item for certain API commands --- src/bitmessagemain.py | 8 ++++---- src/class_singleWorker.py | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index add370a0..1811141e 100644 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -341,8 +341,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): subject = shared.fixPotentiallyInvalidUTF8Data(subject) message = shared.fixPotentiallyInvalidUTF8Data(message) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received, 'read': read}, indent=4, separators=(',', ': ')) - data += ']}' - return data + data += ']}' + return data elif method == 'getAllSentMessages': shared.sqlLock.acquire() shared.sqlSubmitQueue.put('''SELECT msgid, toaddress, fromaddress, subject, lastactiontime, message, encodingtype, status, ackdata FROM sent where folder='sent' ORDER BY lastactiontime''') @@ -395,8 +395,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): subject = shared.fixPotentiallyInvalidUTF8Data(subject) message = shared.fixPotentiallyInvalidUTF8Data(message) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': ')) - data += ']}' - return data + data += ']}' + return data elif method == 'getSentMessagesByAddress' or method == 'getSentMessagesBySender': if len(params) == 0: return 'API Error 0000: I need parameters!' diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index 2ba34eeb..2db7b587 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -414,7 +414,8 @@ class singleWorker(threading.Thread): objectType = 'broadcast' shared.inventory[inventoryHash] = ( objectType, streamNumber, payload, int(time.time())) - print 'sending inv (within sendBroadcast function)' + with shared.printLock: + print 'sending inv (within sendBroadcast function) for object:', inventoryHash.encode('hex') shared.broadcastToSendDataQueues(( streamNumber, 'sendinv', inventoryHash)) From c424885734c349ecb0ce1ee9f42a7800fb925293 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Wed, 31 Jul 2013 12:36:51 -0400 Subject: [PATCH 7/8] Update statuses of sent broadcasts seperately even if all sent data is identical for two messages --- src/class_singleWorker.py | 252 ++++++++++++++------------------------ 1 file changed, 89 insertions(+), 163 deletions(-) diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index 2db7b587..56f23859 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -271,173 +271,99 @@ class singleWorker(threading.Thread): fromaddress, subject, body, ackdata = row status, addressVersionNumber, streamNumber, ripe = decodeAddress( fromaddress) - """if addressVersionNumber == 2 and int(time.time()) < shared.encryptedBroadcastSwitchoverTime: - # We need to convert our private keys to public keys in order - # to include them. - try: - privSigningKeyBase58 = shared.config.get( - fromaddress, 'privsigningkey') - privEncryptionKeyBase58 = shared.config.get( - fromaddress, 'privencryptionkey') - except: - shared.UISignalQueue.put(('updateSentItemStatusByAckdata', ( - ackdata, tr.translateText("MainWindow", "Error! Could not find sender address (your address) in the keys.dat file.")))) - continue - - privSigningKeyHex = shared.decodeWalletImportFormat( - privSigningKeyBase58).encode('hex') - privEncryptionKeyHex = shared.decodeWalletImportFormat( - privEncryptionKeyBase58).encode('hex') - - pubSigningKey = highlevelcrypto.privToPub(privSigningKeyHex).decode( - 'hex') # At this time these pubkeys are 65 bytes long because they include the encoding byte which we won't be sending in the broadcast message. - pubEncryptionKey = highlevelcrypto.privToPub( - privEncryptionKeyHex).decode('hex') - - payload = pack('>Q', (int(time.time()) + random.randrange( - -300, 300))) # the current time plus or minus five minutes - payload += encodeVarint(1) # broadcast version - payload += encodeVarint(addressVersionNumber) - payload += encodeVarint(streamNumber) - payload += '\x00\x00\x00\x01' # behavior bitfield - payload += pubSigningKey[1:] - payload += pubEncryptionKey[1:] - payload += ripe - payload += '\x02' # message encoding type - payload += encodeVarint(len( - 'Subject:' + subject + '\n' + 'Body:' + body)) # Type 2 is simple UTF-8 message encoding. - payload += 'Subject:' + subject + '\n' + 'Body:' + body - - signature = highlevelcrypto.sign(payload, privSigningKeyHex) - payload += encodeVarint(len(signature)) - payload += signature - - target = 2 ** 64 / ((len( - payload) + shared.networkDefaultPayloadLengthExtraBytes + 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) - print '(For broadcast message) Doing proof of work...' - shared.UISignalQueue.put(('updateSentItemStatusByAckdata', ( - ackdata, tr.translateText("MainWindow", "Doing work necessary to send broadcast...")))) - initialHash = hashlib.sha512(payload).digest() - trialValue, nonce = proofofwork.run(target, initialHash) - print '(For broadcast message) Found proof of work', trialValue, 'Nonce:', nonce - - payload = pack('>Q', nonce) + payload - - inventoryHash = calculateInventoryHash(payload) - objectType = 'broadcast' - shared.inventory[inventoryHash] = ( - objectType, streamNumber, payload, int(time.time())) - print 'Broadcasting inv for my broadcast (within sendBroadcast function):', inventoryHash.encode('hex') - shared.broadcastToSendDataQueues(( - streamNumber, 'sendinv', inventoryHash)) - - shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Broadcast sent on %1").arg(unicode( - strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) - - # Update the status of the message in the 'sent' table to have - # a 'broadcastsent' status - shared.sqlLock.acquire() - t = ('broadcastsent', int( - time.time()), fromaddress, subject, body, 'broadcastqueued') - shared.sqlSubmitQueue.put( - 'UPDATE sent SET status=?, lastactiontime=? WHERE fromaddress=? AND subject=? AND message=? AND status=?') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlSubmitQueue.put('commit') - shared.sqlLock.release()""" - if addressVersionNumber == 2 or addressVersionNumber == 3: - # We need to convert our private keys to public keys in order - # to include them. - try: - privSigningKeyBase58 = shared.config.get( - fromaddress, 'privsigningkey') - privEncryptionKeyBase58 = shared.config.get( - fromaddress, 'privencryptionkey') - except: - shared.UISignalQueue.put(('updateSentItemStatusByAckdata', ( - ackdata, tr.translateText("MainWindow", "Error! Could not find sender address (your address) in the keys.dat file.")))) - continue - - privSigningKeyHex = shared.decodeWalletImportFormat( - privSigningKeyBase58).encode('hex') - privEncryptionKeyHex = shared.decodeWalletImportFormat( - privEncryptionKeyBase58).encode('hex') - - pubSigningKey = highlevelcrypto.privToPub(privSigningKeyHex).decode( - 'hex') # At this time these pubkeys are 65 bytes long because they include the encoding byte which we won't be sending in the broadcast message. - pubEncryptionKey = highlevelcrypto.privToPub( - privEncryptionKeyHex).decode('hex') - - payload = pack('>Q', (int(time.time()) + random.randrange( - -300, 300))) # the current time plus or minus five minutes - payload += encodeVarint(2) # broadcast version - payload += encodeVarint(streamNumber) - - dataToEncrypt = encodeVarint(2) # broadcast version - dataToEncrypt += encodeVarint(addressVersionNumber) - dataToEncrypt += encodeVarint(streamNumber) - dataToEncrypt += '\x00\x00\x00\x01' # behavior bitfield - dataToEncrypt += pubSigningKey[1:] - dataToEncrypt += pubEncryptionKey[1:] - if addressVersionNumber >= 3: - dataToEncrypt += encodeVarint(shared.config.getint(fromaddress,'noncetrialsperbyte')) - dataToEncrypt += encodeVarint(shared.config.getint(fromaddress,'payloadlengthextrabytes')) - dataToEncrypt += '\x02' # message encoding type - dataToEncrypt += encodeVarint(len('Subject:' + subject + '\n' + 'Body:' + body)) #Type 2 is simple UTF-8 message encoding per the documentation on the wiki. - dataToEncrypt += 'Subject:' + subject + '\n' + 'Body:' + body - signature = highlevelcrypto.sign( - dataToEncrypt, privSigningKeyHex) - dataToEncrypt += encodeVarint(len(signature)) - dataToEncrypt += signature - - # Encrypt the broadcast with the information contained in the broadcaster's address. Anyone who knows the address can generate - # the private encryption key to decrypt the broadcast. This provides virtually no privacy; its purpose is to keep questionable - # and illegal content from flowing through the Internet connections and being stored on the disk of 3rd parties. - privEncryptionKey = hashlib.sha512(encodeVarint( - addressVersionNumber) + encodeVarint(streamNumber) + ripe).digest()[:32] - pubEncryptionKey = pointMult(privEncryptionKey) - payload += highlevelcrypto.encrypt( - dataToEncrypt, pubEncryptionKey.encode('hex')) - - target = 2 ** 64 / ((len( - payload) + shared.networkDefaultPayloadLengthExtraBytes + 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) - print '(For broadcast message) Doing proof of work...' - shared.UISignalQueue.put(('updateSentItemStatusByAckdata', ( - ackdata, tr.translateText("MainWindow", "Doing work necessary to send broadcast...")))) - initialHash = hashlib.sha512(payload).digest() - trialValue, nonce = proofofwork.run(target, initialHash) - print '(For broadcast message) Found proof of work', trialValue, 'Nonce:', nonce - - payload = pack('>Q', nonce) + payload - - inventoryHash = calculateInventoryHash(payload) - objectType = 'broadcast' - shared.inventory[inventoryHash] = ( - objectType, streamNumber, payload, int(time.time())) - with shared.printLock: - print 'sending inv (within sendBroadcast function) for object:', inventoryHash.encode('hex') - shared.broadcastToSendDataQueues(( - streamNumber, 'sendinv', inventoryHash)) - - shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Broadcast sent on %1").arg(unicode( - strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) - - # Update the status of the message in the 'sent' table to have - # a 'broadcastsent' status - shared.sqlLock.acquire() - t = (inventoryHash,'broadcastsent', int( - time.time()), fromaddress, subject, body, 'broadcastqueued') - shared.sqlSubmitQueue.put( - 'UPDATE sent SET msgid=?, status=?, lastactiontime=? WHERE fromaddress=? AND subject=? AND message=? AND status=?') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlSubmitQueue.put('commit') - shared.sqlLock.release() - else: + if addressVersionNumber <= 1: with shared.printLock: sys.stderr.write( 'Error: In the singleWorker thread, the sendBroadcast function doesn\'t understand the address version.\n') + return + # We need to convert our private keys to public keys in order + # to include them. + try: + privSigningKeyBase58 = shared.config.get( + fromaddress, 'privsigningkey') + privEncryptionKeyBase58 = shared.config.get( + fromaddress, 'privencryptionkey') + except: + shared.UISignalQueue.put(('updateSentItemStatusByAckdata', ( + ackdata, tr.translateText("MainWindow", "Error! Could not find sender address (your address) in the keys.dat file.")))) + continue + privSigningKeyHex = shared.decodeWalletImportFormat( + privSigningKeyBase58).encode('hex') + privEncryptionKeyHex = shared.decodeWalletImportFormat( + privEncryptionKeyBase58).encode('hex') + + pubSigningKey = highlevelcrypto.privToPub(privSigningKeyHex).decode( + 'hex') # At this time these pubkeys are 65 bytes long because they include the encoding byte which we won't be sending in the broadcast message. + pubEncryptionKey = highlevelcrypto.privToPub( + privEncryptionKeyHex).decode('hex') + + payload = pack('>Q', (int(time.time()) + random.randrange( + -300, 300))) # the current time plus or minus five minutes + payload += encodeVarint(2) # broadcast version + payload += encodeVarint(streamNumber) + + dataToEncrypt = encodeVarint(2) # broadcast version + dataToEncrypt += encodeVarint(addressVersionNumber) + dataToEncrypt += encodeVarint(streamNumber) + dataToEncrypt += '\x00\x00\x00\x01' # behavior bitfield + dataToEncrypt += pubSigningKey[1:] + dataToEncrypt += pubEncryptionKey[1:] + if addressVersionNumber >= 3: + dataToEncrypt += encodeVarint(shared.config.getint(fromaddress,'noncetrialsperbyte')) + dataToEncrypt += encodeVarint(shared.config.getint(fromaddress,'payloadlengthextrabytes')) + dataToEncrypt += '\x02' # message encoding type + dataToEncrypt += encodeVarint(len('Subject:' + subject + '\n' + 'Body:' + body)) #Type 2 is simple UTF-8 message encoding per the documentation on the wiki. + dataToEncrypt += 'Subject:' + subject + '\n' + 'Body:' + body + signature = highlevelcrypto.sign( + dataToEncrypt, privSigningKeyHex) + dataToEncrypt += encodeVarint(len(signature)) + dataToEncrypt += signature + + # Encrypt the broadcast with the information contained in the broadcaster's address. Anyone who knows the address can generate + # the private encryption key to decrypt the broadcast. This provides virtually no privacy; its purpose is to keep questionable + # and illegal content from flowing through the Internet connections and being stored on the disk of 3rd parties. + privEncryptionKey = hashlib.sha512(encodeVarint( + addressVersionNumber) + encodeVarint(streamNumber) + ripe).digest()[:32] + pubEncryptionKey = pointMult(privEncryptionKey) + payload += highlevelcrypto.encrypt( + dataToEncrypt, pubEncryptionKey.encode('hex')) + + target = 2 ** 64 / ((len( + payload) + shared.networkDefaultPayloadLengthExtraBytes + 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) + print '(For broadcast message) Doing proof of work...' + shared.UISignalQueue.put(('updateSentItemStatusByAckdata', ( + ackdata, tr.translateText("MainWindow", "Doing work necessary to send broadcast...")))) + initialHash = hashlib.sha512(payload).digest() + trialValue, nonce = proofofwork.run(target, initialHash) + print '(For broadcast message) Found proof of work', trialValue, 'Nonce:', nonce + + payload = pack('>Q', nonce) + payload + + inventoryHash = calculateInventoryHash(payload) + objectType = 'broadcast' + shared.inventory[inventoryHash] = ( + objectType, streamNumber, payload, int(time.time())) + with shared.printLock: + print 'sending inv (within sendBroadcast function) for object:', inventoryHash.encode('hex') + shared.broadcastToSendDataQueues(( + streamNumber, 'sendinv', inventoryHash)) + + shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Broadcast sent on %1").arg(unicode( + strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) + + # Update the status of the message in the 'sent' table to have + # a 'broadcastsent' status + shared.sqlLock.acquire() + t = (inventoryHash,'broadcastsent', int( + time.time()), ackdata) + shared.sqlSubmitQueue.put( + 'UPDATE sent SET msgid=?, status=?, lastactiontime=? WHERE ackdata=?') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlSubmitQueue.put('commit') + shared.sqlLock.release() + def sendMsg(self): # Check to see if there are any messages queued to be sent From 46c900f027944d4c19e3aedfb72130cf74b20299 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Wed, 31 Jul 2013 15:38:01 -0400 Subject: [PATCH 8/8] show Invalid Method error in same format as other API errors --- src/bitmessagemain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index d3ed53fa..8168fd52 100644 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -695,7 +695,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): elif method == 'clientStatus': return '{ "networkConnections" : "%s" }' % str(len(shared.connectedHostsList)) else: - return 'Invalid Method: %s' % method + return 'API Error 0020: Invalid method: %s' % method # This thread, of which there is only one, runs the API.