From 8d7eceb18e3435d8d8b67943093e9f3685bb6eb0 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Thu, 13 Jun 2013 15:15:22 -0400 Subject: [PATCH 1/8] Add error handling around .encrypt --- src/bitmessagemain.py | 18 +++++++++++++++--- src/bitmessageqt/__init__.py | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index 6fd42dd1..8d9bc461 100755 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -2899,11 +2899,12 @@ class singleWorker(threading.Thread): 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. + 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')) @@ -3166,7 +3167,18 @@ class singleWorker(threading.Thread): payload += signature #We have assembled the data that will be encrypted. - encrypted = highlevelcrypto.encrypt(payload,"04"+pubEncryptionKeyBase256.encode('hex')) + try: + encrypted = highlevelcrypto.encrypt(payload,"04"+pubEncryptionKeyBase256.encode('hex')) + except: + shared.sqlLock.acquire() + t = (ackdata,) + shared.sqlSubmitQueue.put('''UPDATE sent SET status='badkey' WHERE ackdata=?''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlSubmitQueue.put('commit') + shared.sqlLock.release() + shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Problem: The recipient\'s encryption key is no good. Could not encrypt message. ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))) + continue encryptedPayload = embeddedTime + encodeVarint(toStreamNumber) + encrypted target = 2**64 / ((len(encryptedPayload)+requiredPayloadLengthExtraBytes+8) * requiredAverageProofOfWorkNonceTrialsPerByte) shared.printLock.acquire() @@ -3194,7 +3206,7 @@ class singleWorker(threading.Thread): #Update the status of the message in the 'sent' table to have a 'msgsent' status shared.sqlLock.acquire() t = (ackdata,) - shared.sqlSubmitQueue.put('''UPDATE sent SET status='msgsent' WHERE ackdata=? AND (status='doingmsgpow' or status='forcepow') ''') + shared.sqlSubmitQueue.put('''UPDATE sent SET status='msgsent' WHERE ackdata=?''') shared.sqlSubmitQueue.put(t) queryreturn = shared.sqlReturnQueue.get() shared.sqlSubmitQueue.put('commit') diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 195403ea..3fe0da62 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -383,6 +383,8 @@ class MyForm(QtGui.QMainWindow): statusText = QtGui.QApplication.translate("MainWindow", "Broadcast on %1").arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))))) elif status == 'toodifficult': statusText = QtGui.QApplication.translate("MainWindow", "Problem: The work demanded by the recipient is more difficult than you are willing to do. %1").arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))))) + elif status == 'badkey': + statusText = QtGui.QApplication.translate("MainWindow", "Problem: The recipient\'s encryption key is no good. Could not encrypt message. %1").arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))))) elif status == 'forcepow': statusText = QtGui.QApplication.translate("MainWindow", "Forced difficulty override. Send should start soon.") else: -- 2.45.1 From 98aacd16ffb9ecc29ca21ecede475aee4a41da28 Mon Sep 17 00:00:00 2001 From: nimda Date: Thu, 13 Jun 2013 21:55:38 -0400 Subject: [PATCH 2/8] Subscribe to an address in the addressbook --- src/bitmessageqt/__init__.py | 67 ++++++++++++++++++++++-------------- src/shared.py | 11 +++++- 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 195403ea..f37e3b34 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -139,6 +139,7 @@ class MyForm(QtGui.QMainWindow): # Actions self.actionAddressBookSend = self.ui.addressBookContextMenuToolbar.addAction(QtGui.QApplication.translate("MainWindow", "Send message to this address"), self.on_action_AddressBookSend) self.actionAddressBookClipboard = self.ui.addressBookContextMenuToolbar.addAction(QtGui.QApplication.translate("MainWindow", "Copy address to clipboard"), self.on_action_AddressBookClipboard) + self.actionAddressBookSubscribe = self.ui.addressBookContextMenuToolbar.addAction(QtGui.QApplication.translate("MainWindow", "Subscribe to this address"), self.on_action_AddressBookSubscribe) self.actionAddressBookNew = self.ui.addressBookContextMenuToolbar.addAction(QtGui.QApplication.translate("MainWindow", "Add New Address"), self.on_action_AddressBookNew) self.actionAddressBookDelete = self.ui.addressBookContextMenuToolbar.addAction(QtGui.QApplication.translate("MainWindow", "Delete"), self.on_action_AddressBookDelete) self.ui.tableWidgetAddressBook.setContextMenuPolicy( QtCore.Qt.CustomContextMenu ) @@ -146,6 +147,7 @@ class MyForm(QtGui.QMainWindow): self.popMenuAddressBook = QtGui.QMenu( self ) self.popMenuAddressBook.addAction( self.actionAddressBookSend ) self.popMenuAddressBook.addAction( self.actionAddressBookClipboard ) + self.popMenuAddressBook.addAction( self.actionAddressBookSubscribe ) self.popMenuAddressBook.addSeparator() self.popMenuAddressBook.addAction( self.actionAddressBookNew ) self.popMenuAddressBook.addAction( self.actionAddressBookDelete ) @@ -1380,37 +1382,41 @@ class MyForm(QtGui.QMainWindow): self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want.")) else: self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "The address you entered was invalid. Ignoring it.")) + def addSubscription(self, label, address): + address = addBMIfNotPresent(address) + #This should be handled outside of this function, for error displaying and such, but it must also be checked here. + if shared.isAddressInMySubscriptionsList(address): + return + #Add to UI list + self.ui.tableWidgetSubscriptions.setSortingEnabled(False) + self.ui.tableWidgetSubscriptions.insertRow(0) + newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) + self.ui.tableWidgetSubscriptions.setItem(0,0,newItem) + newItem = QtGui.QTableWidgetItem(address) + newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) + self.ui.tableWidgetSubscriptions.setItem(0,1,newItem) + self.ui.tableWidgetSubscriptions.setSortingEnabled(True) + #Add to database (perhaps this should be separated from the MyForm class) + t = (str(label),address,True) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put('''INSERT INTO subscriptions VALUES (?,?,?)''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlSubmitQueue.put('commit') + shared.sqlLock.release() + self.rerenderInboxFromLabels() + shared.reloadBroadcastSendersForWhichImWatching() def click_pushButtonAddSubscription(self): self.NewSubscriptionDialogInstance = NewSubscriptionDialog(self) if self.NewSubscriptionDialogInstance.exec_(): if self.NewSubscriptionDialogInstance.ui.labelSubscriptionAddressCheck.text() == 'Address is valid.': - #First we must check to see if the address is already in the subscriptions list. The user cannot add it again or else it will cause problems when updating and deleting the entry. - shared.sqlLock.acquire() - t = (addBMIfNotPresent(str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),) - shared.sqlSubmitQueue.put('''select * from subscriptions where address=?''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - if queryreturn == []: - self.ui.tableWidgetSubscriptions.setSortingEnabled(False) - self.ui.tableWidgetSubscriptions.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8(),'utf-8')) - self.ui.tableWidgetSubscriptions.setItem(0,0,newItem) - newItem = QtGui.QTableWidgetItem(addBMIfNotPresent(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())) - newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) - self.ui.tableWidgetSubscriptions.setItem(0,1,newItem) - self.ui.tableWidgetSubscriptions.setSortingEnabled(True) - t = (str(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()),addBMIfNotPresent(str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),True) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put('''INSERT INTO subscriptions VALUES (?,?,?)''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlSubmitQueue.put('commit') - shared.sqlLock.release() - self.rerenderInboxFromLabels() - shared.reloadBroadcastSendersForWhichImWatching() + address = str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()) + #We must check to see if the address is already in the subscriptions list. The user cannot add it again or else it will cause problems when updating and deleting the entry. + if not shared.isAddressInMySubscriptionsList(address): + label = self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8() + self.addSubscription(label, address) else: self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want.")) else: @@ -1880,6 +1886,17 @@ class MyForm(QtGui.QMainWindow): else: self.statusBar().showMessage('') self.ui.tabWidget.setCurrentIndex(1) + def on_action_AddressBookSubscribe(self): + listOfSelectedRows = {} + for i in range(len(self.ui.tableWidgetAddressBook.selectedIndexes())): + listOfSelectedRows[self.ui.tableWidgetAddressBook.selectedIndexes()[i].row()] = 0 + for currentRow in listOfSelectedRows: + addressAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,1).text() + # Then subscribe to it... provided it's not already in the address book + if shared.isAddressInMySubscriptionsList(addressAtCurrentRow): + continue # maybe set the status bar or something + labelAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,0).text() + self.addSubscription(labelAtCurrentRow, addressAtCurrentRow) def on_context_menuAddressBook(self, point): self.popMenuAddressBook.exec_( self.ui.tableWidgetAddressBook.mapToGlobal(point) ) diff --git a/src/shared.py b/src/shared.py index d91c99c1..111016a0 100644 --- a/src/shared.py +++ b/src/shared.py @@ -59,6 +59,15 @@ def isAddressInMyAddressBook(address): sqlLock.release() return queryreturn != [] +#At this point we should really just have a isAddressInMy(book, address)... +def isAddressInMySubscriptionsList(address): + t = (addBMIfNotPresent(address),) + sqlLock.acquire() + sqlSubmitQueue.put('''select * from subscriptions where address=?''') + sqlSubmitQueue.put(t) + queryreturn = sqlReturnQueue.get() + sqlLock.release() + return queryreturn != [] def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address): if isAddressInMyAddressBook(address): return True @@ -185,7 +194,7 @@ def doCleanShutdown(): printLock.release() os._exit(0) -#Wen you want to command a sendDataThread to do something, like shutdown or send some data, this function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are responsible for putting their queue into (and out of) the sendDataQueues list. +#When you want to command a sendDataThread to do something, like shutdown or send some data, this function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are responsible for putting their queue into (and out of) the sendDataQueues list. def broadcastToSendDataQueues(data): #print 'running broadcastToSendDataQueues' for q in sendDataQueues: -- 2.45.1 From 5b6a3d419ebb3891c02bf91f88a6ac1c6189546c Mon Sep 17 00:00:00 2001 From: nimda Date: Thu, 13 Jun 2013 22:03:03 -0400 Subject: [PATCH 3/8] cleanup --- src/shared.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shared.py b/src/shared.py index 111016a0..f945b168 100644 --- a/src/shared.py +++ b/src/shared.py @@ -51,7 +51,7 @@ def lookupAppdataFolder(): return dataFolder def isAddressInMyAddressBook(address): - t = (address,) + t = (addBMIfNotPresent(address,) sqlLock.acquire() sqlSubmitQueue.put('''select address from addressbook where address=?''') sqlSubmitQueue.put(t) @@ -68,6 +68,7 @@ def isAddressInMySubscriptionsList(address): queryreturn = sqlReturnQueue.get() sqlLock.release() return queryreturn != [] + def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address): if isAddressInMyAddressBook(address): return True @@ -219,4 +220,4 @@ def fixPotentiallyInvalidUTF8Data(text): return text except: output = 'Part of the message is corrupt. The message cannot be displayed the normal way.\n\n' + repr(text) - return output \ No newline at end of file + return output -- 2.45.1 From 3539160bd4c5050fcbcf66b2178f1c41dcf929f8 Mon Sep 17 00:00:00 2001 From: nimda Date: Thu, 13 Jun 2013 22:07:19 -0400 Subject: [PATCH 4/8] I can't believe I forgot that bracket. --- src/shared.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared.py b/src/shared.py index f945b168..a5867026 100644 --- a/src/shared.py +++ b/src/shared.py @@ -51,7 +51,7 @@ def lookupAppdataFolder(): return dataFolder def isAddressInMyAddressBook(address): - t = (addBMIfNotPresent(address,) + t = (addBMIfNotPresent(address,)) sqlLock.acquire() sqlSubmitQueue.put('''select address from addressbook where address=?''') sqlSubmitQueue.put(t) -- 2.45.1 From 06ca8625f500009c77768a3a12f4495bdaa5a29f Mon Sep 17 00:00:00 2001 From: nimda Date: Thu, 13 Jun 2013 22:16:37 -0400 Subject: [PATCH 5/8] try to fix SQL error --- src/shared.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared.py b/src/shared.py index a5867026..8c6a834c 100644 --- a/src/shared.py +++ b/src/shared.py @@ -51,7 +51,7 @@ def lookupAppdataFolder(): return dataFolder def isAddressInMyAddressBook(address): - t = (addBMIfNotPresent(address,)) + t = (address,) sqlLock.acquire() sqlSubmitQueue.put('''select address from addressbook where address=?''') sqlSubmitQueue.put(t) @@ -61,7 +61,7 @@ def isAddressInMyAddressBook(address): #At this point we should really just have a isAddressInMy(book, address)... def isAddressInMySubscriptionsList(address): - t = (addBMIfNotPresent(address),) + t = (address,) sqlLock.acquire() sqlSubmitQueue.put('''select * from subscriptions where address=?''') sqlSubmitQueue.put(t) -- 2.45.1 From f264c22ffb5d6bd15e9f05d4e2100841fd0a172e Mon Sep 17 00:00:00 2001 From: nimda Date: Thu, 13 Jun 2013 22:27:14 -0400 Subject: [PATCH 6/8] actually fix SQL error, add status bar message. --- src/shared.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared.py b/src/shared.py index 8c6a834c..256008c1 100644 --- a/src/shared.py +++ b/src/shared.py @@ -61,7 +61,7 @@ def isAddressInMyAddressBook(address): #At this point we should really just have a isAddressInMy(book, address)... def isAddressInMySubscriptionsList(address): - t = (address,) + t = (str(address),) # As opposed to Qt str sqlLock.acquire() sqlSubmitQueue.put('''select * from subscriptions where address=?''') sqlSubmitQueue.put(t) -- 2.45.1 From e7378cffccbb4fe998be249a16f4f26c02110c70 Mon Sep 17 00:00:00 2001 From: nimda Date: Thu, 13 Jun 2013 22:27:52 -0400 Subject: [PATCH 7/8] actually add status bar message. --- src/bitmessageqt/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index f37e3b34..d6916059 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1382,6 +1382,7 @@ class MyForm(QtGui.QMainWindow): self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want.")) else: self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "The address you entered was invalid. Ignoring it.")) + def addSubscription(self, label, address): address = addBMIfNotPresent(address) #This should be handled outside of this function, for error displaying and such, but it must also be checked here. @@ -1894,7 +1895,8 @@ class MyForm(QtGui.QMainWindow): addressAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,1).text() # Then subscribe to it... provided it's not already in the address book if shared.isAddressInMySubscriptionsList(addressAtCurrentRow): - continue # maybe set the status bar or something + self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want.")) + continue labelAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,0).text() self.addSubscription(labelAtCurrentRow, addressAtCurrentRow) def on_context_menuAddressBook(self, point): -- 2.45.1 From e6beeedea1f0c7e394f39b85624786cd4d6b5246 Mon Sep 17 00:00:00 2001 From: nimda Date: Thu, 13 Jun 2013 22:28:33 -0400 Subject: [PATCH 8/8] str() for luck --- src/bitmessageqt/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index d6916059..90a9aba0 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1892,12 +1892,12 @@ class MyForm(QtGui.QMainWindow): for i in range(len(self.ui.tableWidgetAddressBook.selectedIndexes())): listOfSelectedRows[self.ui.tableWidgetAddressBook.selectedIndexes()[i].row()] = 0 for currentRow in listOfSelectedRows: - addressAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,1).text() + addressAtCurrentRow = str(self.ui.tableWidgetAddressBook.item(currentRow,1).text()) # Then subscribe to it... provided it's not already in the address book if shared.isAddressInMySubscriptionsList(addressAtCurrentRow): self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want.")) continue - labelAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,0).text() + labelAtCurrentRow = str(self.ui.tableWidgetAddressBook.item(currentRow,0).text()) self.addSubscription(labelAtCurrentRow, addressAtCurrentRow) def on_context_menuAddressBook(self, point): self.popMenuAddressBook.exec_( self.ui.tableWidgetAddressBook.mapToGlobal(point) ) -- 2.45.1