Merge pull request #18 from Atheros1/master

Accept addresses which lack the prepended BM-; useful for copying and pasting
This commit is contained in:
Jonathan Warren 2012-12-19 11:53:59 -08:00
commit 80e0ae9d0a
2 changed files with 38 additions and 22 deletions

View File

@ -117,12 +117,18 @@ def encodeAddress(version,stream,ripe):
def decodeAddress(address): def decodeAddress(address):
#returns (status, address version number, stream number, data (almost certainly a ripe hash)) #returns (status, address version number, stream number, data (almost certainly a ripe hash))
#check for the BM- at the front of the address. If it isn't there, this address might be for a different version of Bitmessage """#check for the BM- at the front of the address. If it isn't there, this address might be for a different version of Bitmessage
if address[:3] != 'BM-': if address[:3] != 'BM-':
status = 'missingbm' status = 'missingbm'
return status,0,0,0 return status,0,0,0
#take off the BM- #take off the BM-
integer = decodeBase58(address[3:])"""
#changed Bitmessage to accept addresses that lack the "BM-" prefix.
if address[:3] == 'BM-':
integer = decodeBase58(address[3:]) integer = decodeBase58(address[3:])
else:
integer = decodeBase58(address)
if integer == 0: if integer == 0:
status = 'invalidcharacters' status = 'invalidcharacters'
return status,0,0,0 return status,0,0,0
@ -166,6 +172,11 @@ def decodeAddress(address):
status = 'success' status = 'success'
return status,addressVersionNumber,streamNumber,data[-24:-4] return status,addressVersionNumber,streamNumber,data[-24:-4]
def addBMIfNotPresent(address):
if address[:3] != 'BM-':
return 'BM-'+address
else:
return address
def addressStream(address): def addressStream(address):
#returns the stream number of an address or False if there is a problem with the address. #returns the stream number of an address or False if there is a problem with the address.

View File

@ -226,6 +226,7 @@ class receiveDataThread(QThread):
self.initiatedConnection = False self.initiatedConnection = False
else: else:
self.initiatedConnection = True self.initiatedConnection = True
self.ackDataThatWeHaveYetToSend = [] #When we receive a message bound for us, we store the acknowledgement that we need to send (the ackdata) here until we are done processing all other data received from this peer.
def run(self): def run(self):
@ -288,7 +289,7 @@ class receiveDataThread(QThread):
self.data = "" self.data = ""
if verbose >= 2: if verbose >= 2:
printLock.acquire() printLock.acquire()
sys.stderr.write('The magic bytes were not correct. This may indicate a problem with the program code, or a transmission error occurred.\n') sys.stderr.write('The magic bytes were not correct.\n')
printLock.release() printLock.release()
elif len(self.data) < 20: #if so little of the data has arrived that we can't even unpack the payload length elif len(self.data) < 20: #if so little of the data has arrived that we can't even unpack the payload length
pass pass
@ -340,19 +341,22 @@ class receiveDataThread(QThread):
random.seed() random.seed()
objectHash, = random.sample(self.objectsThatWeHaveYetToGet, 1) objectHash, = random.sample(self.objectsThatWeHaveYetToGet, 1)
if objectHash in inventory: if objectHash in inventory:
print 'Inventory (in memory) already has object the hash of which we received in an inv message.' print 'Inventory (in memory) already has object listed in inv message.'
del self.objectsThatWeHaveYetToGet[objectHash] del self.objectsThatWeHaveYetToGet[objectHash]
elif isInSqlInventory(objectHash): elif isInSqlInventory(objectHash):
print 'Inventory (SQL on disk) already has object the hash of which we received in an inv message.' print 'Inventory (SQL on disk) already has object listed in inv message.'
del self.objectsThatWeHaveYetToGet[objectHash] del self.objectsThatWeHaveYetToGet[objectHash]
else: else:
print 'processData function making request for object:', repr(objectHash) print 'processData function making request for object:', repr(objectHash)
self.sendgetdata(objectHash) self.sendgetdata(objectHash)
del self.objectsThatWeHaveYetToGet[objectHash] #It is possible that the remote node doesn't respond with the object. In that case, we'll very likely get it from someone else anyway. del self.objectsThatWeHaveYetToGet[objectHash] #It is possible that the remote node doesn't respond with the object. In that case, we'll very likely get it from someone else anyway.
break break
if len(self.objectsThatWeHaveYetToGet) > 0:
printLock.acquire() printLock.acquire()
print 'within processData, length of objectsThatWeHaveYetToGet is now', len(self.objectsThatWeHaveYetToGet) print 'within processData, number of objectsThatWeHaveYetToGet is now', len(self.objectsThatWeHaveYetToGet)
printLock.release() printLock.release()
if len(self.ackDataThatWeHaveYetToSend) > 0:
self.data = self.ackDataThatWeHaveYetToSend.pop()
self.processData() self.processData()
else: else:
print 'Checksum incorrect. Clearing this message.' print 'Checksum incorrect. Clearing this message.'
@ -541,7 +545,6 @@ class receiveDataThread(QThread):
if messageEncodingType == 2: if messageEncodingType == 2:
bodyPositionIndex = string.find(message,'\nBody:') bodyPositionIndex = string.find(message,'\nBody:')
print 'bodyPositionIndex', bodyPositionIndex
if bodyPositionIndex > 1: if bodyPositionIndex > 1:
subject = message[8:bodyPositionIndex] subject = message[8:bodyPositionIndex]
body = message[bodyPositionIndex+6:] body = message[bodyPositionIndex+6:]
@ -781,7 +784,7 @@ class receiveDataThread(QThread):
else: else:
body = 'Unknown encoding type.\n\n' + repr(message) body = 'Unknown encoding type.\n\n' + repr(message)
subject = '' subject = ''
print 'within recmsg, inventoryHash is', inventoryHash print 'within recmsg, inventoryHash is', repr(inventoryHash)
if messageEncodingType <> 0: if messageEncodingType <> 0:
sqlLock.acquire() sqlLock.acquire()
t = (inventoryHash,toAddress,fromAddress,subject,int(time.time()),body,'inbox') t = (inventoryHash,toAddress,fromAddress,subject,int(time.time()),body,'inbox')
@ -799,7 +802,7 @@ class receiveDataThread(QThread):
#We'll need to make sure that our client will properly process the ackData; if the packet is malformed, we could clear out self.data and an attacker could use that behavior to determine that we were capable of decoding this message. #We'll need to make sure that our client will properly process the ackData; if the packet is malformed, we could clear out self.data and an attacker could use that behavior to determine that we were capable of decoding this message.
ackDataValidThusFar = True ackDataValidThusFar = True
if len(ackData) < 24: if len(ackData) < 24:
print 'The length of Ackdata is unreasonably short. Not sending ackData.' print 'The length of ackData is unreasonably short. Not sending ackData.'
ackDataValidThusFar = False ackDataValidThusFar = False
if ackData[0:4] != '\xe9\xbe\xb4\xd9': if ackData[0:4] != '\xe9\xbe\xb4\xd9':
print 'Ackdata magic bytes were wrong. Not sending ackData.' print 'Ackdata magic bytes were wrong. Not sending ackData.'
@ -811,7 +814,8 @@ class receiveDataThread(QThread):
ackDataValidThusFar = False ackDataValidThusFar = False
if ackDataValidThusFar: if ackDataValidThusFar:
print 'ackData is valid. Will process it.' print 'ackData is valid. Will process it.'
self.data = self.data[:self.payloadLength+24] + ackData + self.data[self.payloadLength+24:] #self.data = self.data[:self.payloadLength+24] + ackData + self.data[self.payloadLength+24:]
self.ackDataThatWeHaveYetToSend.append(ackData) #When we have processed all data
#print 'self.data after:', repr(self.data) #print 'self.data after:', repr(self.data)
'''if ackData[4:16] == 'msg\x00\x00\x00\x00\x00\x00\x00\x00\x00': '''if ackData[4:16] == 'msg\x00\x00\x00\x00\x00\x00\x00\x00\x00':
inventoryHash = calculateInventoryHash(ackData[24:]) inventoryHash = calculateInventoryHash(ackData[24:])
@ -2750,7 +2754,7 @@ class MyForm(QtGui.QMainWindow):
message = str(self.ui.textEditMessage.document().toPlainText().toUtf8()) message = str(self.ui.textEditMessage.document().toPlainText().toUtf8())
if self.ui.radioButtonSpecific.isChecked(): #To send a message to specific people (rather than broadcast) if self.ui.radioButtonSpecific.isChecked(): #To send a message to specific people (rather than broadcast)
toAddressesList = [s.strip() for s in toAddresses.replace(',', ';').split(';')] toAddressesList = [s.strip() for s in toAddresses.replace(',', ';').split(';')]
toAddressesList = list(set(toAddressesList)) #remove duplicate addresses toAddressesList = list(set(toAddressesList)) #remove duplicate addresses. If the user has one address with a BM- and the same address without the BM-, this will not catch it. They'll send the message to the person twice.
for toAddress in toAddressesList: for toAddress in toAddressesList:
if toAddress <> '': if toAddress <> '':
status,addressVersionNumber,streamNumber,ripe = decodeAddress(toAddress) status,addressVersionNumber,streamNumber,ripe = decodeAddress(toAddress)
@ -2768,6 +2772,7 @@ class MyForm(QtGui.QMainWindow):
print 'Status bar!', 'Error: you must specify a From address.' print 'Status bar!', 'Error: you must specify a From address.'
self.statusBar().showMessage('Error: You must specify a From address. If you don''t have one, go to the ''Your Identities'' tab.') self.statusBar().showMessage('Error: You must specify a From address. If you don''t have one, go to the ''Your Identities'' tab.')
else: else:
toAddress = addBMIfNotPresent(toAddress)
self.statusBar().showMessage('') self.statusBar().showMessage('')
if connectionsCount[streamNumber] == 0: if connectionsCount[streamNumber] == 0:
self.statusBar().showMessage('Warning: You are currently not connected. Bitmessage will do the work necessary to send the message but it won\'t send until you connect.') self.statusBar().showMessage('Warning: You are currently not connected. Bitmessage will do the work necessary to send the message but it won\'t send until you connect.')
@ -3017,7 +3022,7 @@ class MyForm(QtGui.QMainWindow):
if self.NewSubscriptionDialogInstance.ui.labelSubscriptionAddressCheck.text() == 'Address is valid.': if self.NewSubscriptionDialogInstance.ui.labelSubscriptionAddressCheck.text() == 'Address is valid.':
#First we must check to see if the address is already in the address book. The user cannot add it again or else it will cause problems when updating and deleting the entry. #First we must check to see if the address is already in the address book. The user cannot add it again or else it will cause problems when updating and deleting the entry.
sqlLock.acquire() sqlLock.acquire()
t = (str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()),) t = (addBMIfNotPresent(str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),)
sqlSubmitQueue.put('''select * from addressbook where address=?''') sqlSubmitQueue.put('''select * from addressbook where address=?''')
sqlSubmitQueue.put(t) sqlSubmitQueue.put(t)
queryreturn = sqlReturnQueue.get() queryreturn = sqlReturnQueue.get()
@ -3026,10 +3031,10 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetAddressBook.insertRow(0) self.ui.tableWidgetAddressBook.insertRow(0)
newItem = QtGui.QTableWidgetItem(unicode(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8(),'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8(),'utf-8'))
self.ui.tableWidgetAddressBook.setItem(0,0,newItem) self.ui.tableWidgetAddressBook.setItem(0,0,newItem)
newItem = QtGui.QTableWidgetItem(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()) newItem = QtGui.QTableWidgetItem(addBMIfNotPresent(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
self.ui.tableWidgetAddressBook.setItem(0,1,newItem) self.ui.tableWidgetAddressBook.setItem(0,1,newItem)
t = (str(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()),str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())) t = (str(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()),addBMIfNotPresent(str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())))
sqlLock.acquire() sqlLock.acquire()
sqlSubmitQueue.put('''INSERT INTO addressbook VALUES (?,?)''') sqlSubmitQueue.put('''INSERT INTO addressbook VALUES (?,?)''')
sqlSubmitQueue.put(t) sqlSubmitQueue.put(t)
@ -3048,7 +3053,7 @@ class MyForm(QtGui.QMainWindow):
if self.NewSubscriptionDialogInstance.ui.labelSubscriptionAddressCheck.text() == 'Address is valid.': if self.NewSubscriptionDialogInstance.ui.labelSubscriptionAddressCheck.text() == 'Address is valid.':
#First we must check to see if the address is already in the address book. The user cannot add it again or else it will cause problems when updating and deleting the entry. #First we must check to see if the address is already in the address book. The user cannot add it again or else it will cause problems when updating and deleting the entry.
sqlLock.acquire() sqlLock.acquire()
t = (str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()),) t = (addBMIfNotPresent(str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),)
sqlSubmitQueue.put('''select * from subscriptions where address=?''') sqlSubmitQueue.put('''select * from subscriptions where address=?''')
sqlSubmitQueue.put(t) sqlSubmitQueue.put(t)
queryreturn = sqlReturnQueue.get() queryreturn = sqlReturnQueue.get()
@ -3057,10 +3062,10 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetSubscriptions.insertRow(0) self.ui.tableWidgetSubscriptions.insertRow(0)
newItem = QtGui.QTableWidgetItem(unicode(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8(),'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8(),'utf-8'))
self.ui.tableWidgetSubscriptions.setItem(0,0,newItem) self.ui.tableWidgetSubscriptions.setItem(0,0,newItem)
newItem = QtGui.QTableWidgetItem(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()) newItem = QtGui.QTableWidgetItem(addBMIfNotPresent(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
self.ui.tableWidgetSubscriptions.setItem(0,1,newItem) self.ui.tableWidgetSubscriptions.setItem(0,1,newItem)
t = (str(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()),str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()),True) t = (str(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()),addBMIfNotPresent(str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),True)
sqlLock.acquire() sqlLock.acquire()
sqlSubmitQueue.put('''INSERT INTO subscriptions VALUES (?,?,?)''') sqlSubmitQueue.put('''INSERT INTO subscriptions VALUES (?,?,?)''')
sqlSubmitQueue.put(t) sqlSubmitQueue.put(t)
@ -3175,7 +3180,7 @@ class MyForm(QtGui.QMainWindow):
if self.NewBlacklistDialogInstance.ui.labelSubscriptionAddressCheck.text() == 'Address is valid.': if self.NewBlacklistDialogInstance.ui.labelSubscriptionAddressCheck.text() == 'Address is valid.':
#First we must check to see if the address is already in the address book. The user cannot add it again or else it will cause problems when updating and deleting the entry. #First we must check to see if the address is already in the address book. The user cannot add it again or else it will cause problems when updating and deleting the entry.
sqlLock.acquire() sqlLock.acquire()
t = (str(self.NewBlacklistDialogInstance.ui.lineEditSubscriptionAddress.text()),) t = (addBMIfNotPresent(str(self.NewBlacklistDialogInstance.ui.lineEditSubscriptionAddress.text())),)
if config.get('bitmessagesettings', 'blackwhitelist') == 'black': if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
sqlSubmitQueue.put('''select * from blacklist where address=?''') sqlSubmitQueue.put('''select * from blacklist where address=?''')
else: else:
@ -3187,10 +3192,10 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetBlacklist.insertRow(0) self.ui.tableWidgetBlacklist.insertRow(0)
newItem = QtGui.QTableWidgetItem(unicode(self.NewBlacklistDialogInstance.ui.newsubscriptionlabel.text().toUtf8(),'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(self.NewBlacklistDialogInstance.ui.newsubscriptionlabel.text().toUtf8(),'utf-8'))
self.ui.tableWidgetBlacklist.setItem(0,0,newItem) self.ui.tableWidgetBlacklist.setItem(0,0,newItem)
newItem = QtGui.QTableWidgetItem(self.NewBlacklistDialogInstance.ui.lineEditSubscriptionAddress.text()) newItem = QtGui.QTableWidgetItem(addBMIfNotPresent(self.NewBlacklistDialogInstance.ui.lineEditSubscriptionAddress.text()))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
self.ui.tableWidgetBlacklist.setItem(0,1,newItem) self.ui.tableWidgetBlacklist.setItem(0,1,newItem)
t = (str(self.NewBlacklistDialogInstance.ui.newsubscriptionlabel.text().toUtf8()),str(self.NewBlacklistDialogInstance.ui.lineEditSubscriptionAddress.text()),True) t = (str(self.NewBlacklistDialogInstance.ui.newsubscriptionlabel.text().toUtf8()),addBMIfNotPresent(str(self.NewBlacklistDialogInstance.ui.lineEditSubscriptionAddress.text())),True)
sqlLock.acquire() sqlLock.acquire()
if config.get('bitmessagesettings', 'blackwhitelist') == 'black': if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
sqlSubmitQueue.put('''INSERT INTO blacklist VALUES (?,?,?)''') sqlSubmitQueue.put('''INSERT INTO blacklist VALUES (?,?,?)''')