def __init__(self, parent=None): super(NetworkStatus, self).__init__(parent) widgets.load('networkstatus.ui', self) header = self.tableWidgetConnectionCount.horizontalHeader() header.setResizeMode(QtGui.QHeaderView.ResizeToContents) # Somehow this value was 5 when I tested if header.sortIndicatorSection() > 4: header.setSortIndicator(0, QtCore.Qt.AscendingOrder) self.startup = time.localtime() self.labelStartupTime.setText(_translate("networkstatus", "Since startup on %1").arg( l10n.formatTimestamp(self.startup))) self.UISignalThread = UISignaler.get() QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateNumberOfMessagesProcessed()"), self.updateNumberOfMessagesProcessed) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateNumberOfPubkeysProcessed()"), self.updateNumberOfPubkeysProcessed) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateNumberOfBroadcastsProcessed()"), self.updateNumberOfBroadcastsProcessed) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateNetworkStatusTab(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.updateNetworkStatusTab) self.timer = QtCore.QTimer() QtCore.QObject.connect( self.timer, QtCore.SIGNAL("timeout()"), self.runEveryTwoSeconds)
def __init__(self, parent=None): super(NetworkStatus, self).__init__(parent) widgets.load('networkstatus.ui', self) self.labelStartupTime.setText(_translate("networkstatus", "Since startup on %1").arg( l10n.formatTimestamp())) self.UISignalThread = UISignaler.get() QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateNumberOfMessagesProcessed()"), self.updateNumberOfMessagesProcessed) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateNumberOfPubkeysProcessed()"), self.updateNumberOfPubkeysProcessed) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateNumberOfBroadcastsProcessed()"), self.updateNumberOfBroadcastsProcessed) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateNetworkStatusTab()"), self.updateNetworkStatusTab) self.totalNumberOfBytesReceived = 0 self.totalNumberOfBytesSent = 0 self.timer = QtCore.QTimer() self.timer.start(2000) # milliseconds QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.runEveryTwoSeconds)
def checkackdata(self, data): # Let's check whether this is a message acknowledgement bound for us. if len(data) < 32: return if data[-32:] in shared.ackdataForWhichImWatching: logger.info('This object is an acknowledgement bound for me.') del shared.ackdataForWhichImWatching[data[-32:]] sqlExecute('UPDATE sent SET status=?, lastactiontime=? WHERE ackdata=?', 'ackreceived', int(time.time()), data[-32:]) queues.UISignalQueue.put(('updateSentItemStatusByAckdata', (data[-32:], tr._translate("MainWindow",'Acknowledgement of the message received %1').arg(l10n.formatTimestamp())))) else: logger.debug('This object is not an acknowledgement bound for me.')
def retranslateUi(self): super(NetworkStatus, self).retranslateUi() self.labelStartupTime.setText(_translate("networkstatus", "Since startup on %1").arg( l10n.formatTimestamp(self.startup)))
def processmsg(self, data): messageProcessingStartTime = time.time() shared.numberOfMessagesProcessed += 1 shared.UISignalQueue.put(( 'updateNumberOfMessagesProcessed', 'no data')) readPosition = 20 # bypass the nonce, time, and object type msgVersion, msgVersionLength = decodeVarint(data[readPosition:readPosition + 9]) if msgVersion != 1: logger.info('Cannot understand message versions other than one. Ignoring message.') return readPosition += msgVersionLength streamNumberAsClaimedByMsg, streamNumberAsClaimedByMsgLength = decodeVarint( data[readPosition:readPosition + 9]) readPosition += streamNumberAsClaimedByMsgLength inventoryHash = calculateInventoryHash(data) initialDecryptionSuccessful = False # Let's check whether this is a message acknowledgement bound for us. if data[-32:] in shared.ackdataForWhichImWatching: logger.info('This msg IS an acknowledgement bound for me.') del shared.ackdataForWhichImWatching[data[-32:]] sqlExecute('UPDATE sent SET status=?, lastactiontime=? WHERE ackdata=?', 'ackreceived', int(time.time()), data[-32:]) shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (data[-32:], tr.translateText("MainWindow",'Acknowledgement of the message received. %1').arg(l10n.formatTimestamp())))) return else: logger.info('This was NOT an acknowledgement bound for me.') # This is not an acknowledgement bound for me. See if it is a message # bound for me by trying to decrypt it with my private keys. for key, cryptorObject in shared.myECCryptorObjects.items(): try: decryptedData = cryptorObject.decrypt(data[readPosition:]) toRipe = key # This is the RIPE hash of my pubkeys. We need this below to compare to the destination_ripe included in the encrypted data. initialDecryptionSuccessful = True logger.info('EC decryption successful using key associated with ripe hash: %s.' % key.encode('hex')) break except Exception as err: pass if not initialDecryptionSuccessful: # This is not a message bound for me. logger.info('Length of time program spent failing to decrypt this message: %s seconds.' % (time.time() - messageProcessingStartTime,)) return # This is a message bound for me. toAddress = shared.myAddressesByHash[ toRipe] # Look up my address based on the RIPE hash. readPosition = 0 sendersAddressVersionNumber, sendersAddressVersionNumberLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += sendersAddressVersionNumberLength if sendersAddressVersionNumber == 0: logger.info('Cannot understand sendersAddressVersionNumber = 0. Ignoring message.') return if sendersAddressVersionNumber > 4: logger.info('Sender\'s address version number %s not yet supported. Ignoring message.' % sendersAddressVersionNumber) return if len(decryptedData) < 170: logger.info('Length of the unencrypted data is unreasonably short. Sanity check failed. Ignoring message.') return sendersStreamNumber, sendersStreamNumberLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) if sendersStreamNumber == 0: logger.info('sender\'s stream number is 0. Ignoring message.') return readPosition += sendersStreamNumberLength behaviorBitfield = decryptedData[readPosition:readPosition + 4] readPosition += 4 pubSigningKey = '\x04' + decryptedData[ readPosition:readPosition + 64] readPosition += 64 pubEncryptionKey = '\x04' + decryptedData[ readPosition:readPosition + 64] readPosition += 64 if sendersAddressVersionNumber >= 3: requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += varintLength logger.info('sender\'s requiredAverageProofOfWorkNonceTrialsPerByte is %s' % requiredAverageProofOfWorkNonceTrialsPerByte) requiredPayloadLengthExtraBytes, varintLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += varintLength logger.info('sender\'s requiredPayloadLengthExtraBytes is %s' % requiredPayloadLengthExtraBytes) endOfThePublicKeyPosition = readPosition # needed for when we store the pubkey in our database of pubkeys for later use. if toRipe != decryptedData[readPosition:readPosition + 20]: logger.info('The original sender of this message did not send it to you. Someone is attempting a Surreptitious Forwarding Attack.\n\ See: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html \n\ your toRipe: %s\n\ embedded destination toRipe: %s' % (toRipe.encode('hex'), decryptedData[readPosition:readPosition + 20].encode('hex')) ) return readPosition += 20 messageEncodingType, messageEncodingTypeLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += messageEncodingTypeLength messageLength, messageLengthLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += messageLengthLength message = decryptedData[readPosition:readPosition + messageLength] # print 'First 150 characters of message:', repr(message[:150]) readPosition += messageLength ackLength, ackLengthLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += ackLengthLength ackData = decryptedData[readPosition:readPosition + ackLength] readPosition += ackLength positionOfBottomOfAckData = readPosition # needed to mark the end of what is covered by the signature signatureLength, signatureLengthLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += signatureLengthLength signature = decryptedData[ readPosition:readPosition + signatureLength] signedData = data[8:20] + encodeVarint(1) + encodeVarint(streamNumberAsClaimedByMsg) + decryptedData[:positionOfBottomOfAckData] if not highlevelcrypto.verify(signedData, signature, pubSigningKey.encode('hex')): logger.debug('ECDSA verify failed') return logger.debug('ECDSA verify passed') logger.debug('As a matter of intellectual curiosity, here is the Bitcoin address associated with the keys owned by the other person: %s ..and here is the testnet address: %s. The other person must take their private signing key from Bitmessage and import it into Bitcoin (or a service like Blockchain.info) for it to be of any use. Do not use this unless you know what you are doing.' % (helper_bitcoin.calculateBitcoinAddressFromPubkey(pubSigningKey), helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey)) ) sigHash = hashlib.sha512(hashlib.sha512(signature).digest()).digest()[32:] # Used to detect and ignore duplicate messages in our inbox # calculate the fromRipe. sha = hashlib.new('sha512') sha.update(pubSigningKey + pubEncryptionKey) ripe = hashlib.new('ripemd160') ripe.update(sha.digest()) fromAddress = encodeAddress( sendersAddressVersionNumber, sendersStreamNumber, ripe.digest()) # Let's store the public key in case we want to reply to this # person. sqlExecute( '''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', fromAddress, sendersAddressVersionNumber, decryptedData[:endOfThePublicKeyPosition], int(time.time()), 'yes') # Check to see whether we happen to be awaiting this # pubkey in order to send a message. If we are, it will do the POW # and send it. self.possibleNewPubkey(fromAddress) # If this message is bound for one of my version 3 addresses (or # higher), then we must check to make sure it meets our demanded # proof of work requirement. If this is bound for one of my chan # addresses then we skip this check; the minimum network POW is # fine. if decodeAddress(toAddress)[1] >= 3 and not shared.safeConfigGetBoolean(toAddress, 'chan'): # If the toAddress version number is 3 or higher and not one of my chan addresses: if not shared.isAddressInMyAddressBookSubscriptionsListOrWhitelist(fromAddress): # If I'm not friendly with this person: requiredNonceTrialsPerByte = shared.config.getint( toAddress, 'noncetrialsperbyte') requiredPayloadLengthExtraBytes = shared.config.getint( toAddress, 'payloadlengthextrabytes') if not shared.isProofOfWorkSufficient(data, requiredNonceTrialsPerByte, requiredPayloadLengthExtraBytes): logger.info('Proof of work in msg is insufficient only because it does not meet our higher requirement.') return blockMessage = False # Gets set to True if the user shouldn't see the message according to black or white lists. if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black': # If we are using a blacklist queryreturn = sqlQuery( '''SELECT label FROM blacklist where address=? and enabled='1' ''', fromAddress) if queryreturn != []: logger.info('Message ignored because address is in blacklist.') blockMessage = True else: # We're using a whitelist queryreturn = sqlQuery( '''SELECT label FROM whitelist where address=? and enabled='1' ''', fromAddress) if queryreturn == []: logger.info('Message ignored because address not in whitelist.') blockMessage = True toLabel = shared.config.get(toAddress, 'label') if toLabel == '': toLabel = toAddress if messageEncodingType == 2: subject, body = self.decodeType2Message(message) logger.info('Message subject (first 100 characters): %s' % repr(subject)[:100]) elif messageEncodingType == 1: body = message subject = '' elif messageEncodingType == 0: logger.info('messageEncodingType == 0. Doing nothing with the message. They probably just sent it so that we would store their public key or send their ack data for them.') subject = '' body = '' else: body = 'Unknown encoding type.\n\n' + repr(message) subject = '' # Let us make sure that we haven't already received this message if helper_inbox.isMessageAlreadyInInbox(sigHash): logger.info('This msg is already in our inbox. Ignoring it.') blockMessage = True if not blockMessage: if messageEncodingType != 0: t = (inventoryHash, toAddress, fromAddress, subject, int( time.time()), body, 'inbox', messageEncodingType, 0, sigHash) helper_inbox.insert(t) shared.UISignalQueue.put(('displayNewInboxMessage', ( inventoryHash, toAddress, fromAddress, subject, body))) # 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"]) # Let us now check and see whether our receiving address is # behaving as a mailing list if shared.safeConfigGetBoolean(toAddress, 'mailinglist'): try: mailingListName = shared.config.get( toAddress, 'mailinglistname') except: mailingListName = '' # Let us send out this message as a broadcast subject = self.addMailingListNameToSubject( subject, mailingListName) # Let us now send this message out as a broadcast message = time.strftime("%a, %Y-%m-%d %H:%M:%S UTC", time.gmtime( )) + ' Message ostensibly from ' + fromAddress + ':\n\n' + body fromAddress = toAddress # The fromAddress for the broadcast that we are about to send is the toAddress (my address) for the msg message we are currently processing. ackdataForBroadcast = OpenSSL.rand( 32) # We don't actually need the ackdataForBroadcast for acknowledgement since this is a broadcast message but we can use it to update the user interface when the POW is done generating. toAddress = '[Broadcast subscribers]' ripe = '' # We really should have a discussion about how to # set the TTL for mailing list broadcasts. This is obviously # hard-coded. TTL = 2*7*24*60*60 # 2 weeks t = ('', toAddress, ripe, fromAddress, subject, message, ackdataForBroadcast, int(time.time()), # sentTime (this doesn't change) int(time.time()), # lastActionTime 0, 'broadcastqueued', 0, 'sent', 2, TTL) helper_sent.insert(t) shared.UISignalQueue.put(('displayNewSentMessage', ( toAddress, '[Broadcast subscribers]', fromAddress, subject, message, ackdataForBroadcast))) shared.workerQueue.put(('sendbroadcast', '')) if self.ackDataHasAVaildHeader(ackData): shared.checkAndShareObjectWithPeers(ackData[24:]) # Display timing data timeRequiredToAttemptToDecryptMessage = time.time( ) - messageProcessingStartTime shared.successfullyDecryptMessageTimings.append( timeRequiredToAttemptToDecryptMessage) sum = 0 for item in shared.successfullyDecryptMessageTimings: sum += item logger.debug('Time to decrypt this message successfully: %s\n\ Average time for all message decryption successes since startup: %s.' % (timeRequiredToAttemptToDecryptMessage, sum / len(shared.successfullyDecryptMessageTimings)) )
def checkackdata(self, data): # Let's check whether this is a message acknowledgement bound for us. if len(data) < 32: return # bypass nonce and time, retain object type/version/stream + body readPosition = 16 if data[readPosition:] in shared.ackdataForWhichImWatching: logger.info('This object is an acknowledgement bound for me.') del shared.ackdataForWhichImWatching[data[readPosition:]] sqlExecute('UPDATE sent SET status=?, lastactiontime=? WHERE ackdata=?', 'ackreceived', int(time.time()), data[readPosition:]) queues.UISignalQueue.put(('updateSentItemStatusByAckdata', (data[readPosition:], tr._translate("MainWindow",'Acknowledgement of the message received %1').arg(l10n.formatTimestamp())))) else: logger.debug('This object is not an acknowledgement bound for me.')
def processmsg(self, data): messageProcessingStartTime = time.time() shared.numberOfMessagesProcessed += 1 queues.UISignalQueue.put( ('updateNumberOfMessagesProcessed', 'no data')) readPosition = 20 # bypass the nonce, time, and object type msgVersion, msgVersionLength = decodeVarint( data[readPosition:readPosition + 9]) if msgVersion != 1: logger.info( 'Cannot understand message versions other than one. Ignoring message.' ) return readPosition += msgVersionLength streamNumberAsClaimedByMsg, streamNumberAsClaimedByMsgLength = decodeVarint( data[readPosition:readPosition + 9]) readPosition += streamNumberAsClaimedByMsgLength inventoryHash = calculateInventoryHash(data) initialDecryptionSuccessful = False # Let's check whether this is a message acknowledgement bound for us. if data[-32:] in shared.ackdataForWhichImWatching: logger.info('This msg IS an acknowledgement bound for me.') del shared.ackdataForWhichImWatching[data[-32:]] sqlExecute( 'UPDATE sent SET status=?, lastactiontime=? WHERE ackdata=?', 'ackreceived', int(time.time()), data[-32:]) queues.UISignalQueue.put( ('updateSentItemStatusByAckdata', (data[-32:], tr._translate( "MainWindow", 'Acknowledgement of the message received %1').arg( l10n.formatTimestamp())))) return else: logger.info('This was NOT an acknowledgement bound for me.') # This is not an acknowledgement bound for me. See if it is a message # bound for me by trying to decrypt it with my private keys. for key, cryptorObject in shared.myECCryptorObjects.items(): try: if initialDecryptionSuccessful: # continue decryption attempts to avoid timing attacks cryptorObject.decrypt(data[readPosition:]) else: decryptedData = cryptorObject.decrypt(data[readPosition:]) toRipe = key # This is the RIPE hash of my pubkeys. We need this below to compare to the destination_ripe included in the encrypted data. initialDecryptionSuccessful = True logger.info( 'EC decryption successful using key associated with ripe hash: %s.' % hexlify(key)) except Exception as err: pass if not initialDecryptionSuccessful: # This is not a message bound for me. logger.info( 'Length of time program spent failing to decrypt this message: %s seconds.' % (time.time() - messageProcessingStartTime, )) return # This is a message bound for me. toAddress = shared.myAddressesByHash[ toRipe] # Look up my address based on the RIPE hash. readPosition = 0 sendersAddressVersionNumber, sendersAddressVersionNumberLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += sendersAddressVersionNumberLength if sendersAddressVersionNumber == 0: logger.info( 'Cannot understand sendersAddressVersionNumber = 0. Ignoring message.' ) return if sendersAddressVersionNumber > 4: logger.info( 'Sender\'s address version number %s not yet supported. Ignoring message.' % sendersAddressVersionNumber) return if len(decryptedData) < 170: logger.info( 'Length of the unencrypted data is unreasonably short. Sanity check failed. Ignoring message.' ) return sendersStreamNumber, sendersStreamNumberLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) if sendersStreamNumber == 0: logger.info('sender\'s stream number is 0. Ignoring message.') return readPosition += sendersStreamNumberLength behaviorBitfield = decryptedData[readPosition:readPosition + 4] readPosition += 4 pubSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64] readPosition += 64 pubEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64] readPosition += 64 if sendersAddressVersionNumber >= 3: requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += varintLength logger.info( 'sender\'s requiredAverageProofOfWorkNonceTrialsPerByte is %s' % requiredAverageProofOfWorkNonceTrialsPerByte) requiredPayloadLengthExtraBytes, varintLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += varintLength logger.info('sender\'s requiredPayloadLengthExtraBytes is %s' % requiredPayloadLengthExtraBytes) endOfThePublicKeyPosition = readPosition # needed for when we store the pubkey in our database of pubkeys for later use. if toRipe != decryptedData[readPosition:readPosition + 20]: logger.info( 'The original sender of this message did not send it to you. Someone is attempting a Surreptitious Forwarding Attack.\n\ See: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html \n\ your toRipe: %s\n\ embedded destination toRipe: %s' % (hexlify(toRipe), hexlify(decryptedData[readPosition:readPosition + 20]))) return readPosition += 20 messageEncodingType, messageEncodingTypeLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += messageEncodingTypeLength messageLength, messageLengthLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += messageLengthLength message = decryptedData[readPosition:readPosition + messageLength] # print 'First 150 characters of message:', repr(message[:150]) readPosition += messageLength ackLength, ackLengthLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += ackLengthLength ackData = decryptedData[readPosition:readPosition + ackLength] readPosition += ackLength positionOfBottomOfAckData = readPosition # needed to mark the end of what is covered by the signature signatureLength, signatureLengthLength = decodeVarint( decryptedData[readPosition:readPosition + 10]) readPosition += signatureLengthLength signature = decryptedData[readPosition:readPosition + signatureLength] signedData = data[8:20] + encodeVarint( 1) + encodeVarint(streamNumberAsClaimedByMsg ) + decryptedData[:positionOfBottomOfAckData] if not highlevelcrypto.verify(signedData, signature, hexlify(pubSigningKey)): logger.debug('ECDSA verify failed') return logger.debug('ECDSA verify passed') logger.debug( 'As a matter of intellectual curiosity, here is the Bitcoin address associated with the keys owned by the other person: %s ..and here is the testnet address: %s. The other person must take their private signing key from Bitmessage and import it into Bitcoin (or a service like Blockchain.info) for it to be of any use. Do not use this unless you know what you are doing.' % (helper_bitcoin.calculateBitcoinAddressFromPubkey(pubSigningKey), helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey))) sigHash = hashlib.sha512(hashlib.sha512(signature).digest()).digest()[ 32:] # Used to detect and ignore duplicate messages in our inbox # calculate the fromRipe. sha = hashlib.new('sha512') sha.update(pubSigningKey + pubEncryptionKey) ripe = hashlib.new('ripemd160') ripe.update(sha.digest()) fromAddress = encodeAddress(sendersAddressVersionNumber, sendersStreamNumber, ripe.digest()) # Let's store the public key in case we want to reply to this # person. sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', fromAddress, sendersAddressVersionNumber, decryptedData[:endOfThePublicKeyPosition], int(time.time()), 'yes') # Check to see whether we happen to be awaiting this # pubkey in order to send a message. If we are, it will do the POW # and send it. self.possibleNewPubkey(fromAddress) # If this message is bound for one of my version 3 addresses (or # higher), then we must check to make sure it meets our demanded # proof of work requirement. If this is bound for one of my chan # addresses then we skip this check; the minimum network POW is # fine. if decodeAddress(toAddress)[1] >= 3 and not BMConfigParser( ).safeGetBoolean( toAddress, 'chan' ): # If the toAddress version number is 3 or higher and not one of my chan addresses: if not shared.isAddressInMyAddressBookSubscriptionsListOrWhitelist( fromAddress): # If I'm not friendly with this person: requiredNonceTrialsPerByte = BMConfigParser().getint( toAddress, 'noncetrialsperbyte') requiredPayloadLengthExtraBytes = BMConfigParser().getint( toAddress, 'payloadlengthextrabytes') if not protocol.isProofOfWorkSufficient( data, requiredNonceTrialsPerByte, requiredPayloadLengthExtraBytes): logger.info( 'Proof of work in msg is insufficient only because it does not meet our higher requirement.' ) return blockMessage = False # Gets set to True if the user shouldn't see the message according to black or white lists. if BMConfigParser().get( 'bitmessagesettings', 'blackwhitelist') == 'black': # If we are using a blacklist queryreturn = sqlQuery( '''SELECT label FROM blacklist where address=? and enabled='1' ''', fromAddress) if queryreturn != []: logger.info('Message ignored because address is in blacklist.') blockMessage = True else: # We're using a whitelist queryreturn = sqlQuery( '''SELECT label FROM whitelist where address=? and enabled='1' ''', fromAddress) if queryreturn == []: logger.info( 'Message ignored because address not in whitelist.') blockMessage = True toLabel = BMConfigParser().get(toAddress, 'label') if toLabel == '': toLabel = toAddress decodedMessage = helper_msgcoding.MsgDecode(messageEncodingType, message) subject = decodedMessage.subject body = decodedMessage.body # Let us make sure that we haven't already received this message if helper_inbox.isMessageAlreadyInInbox(sigHash): logger.info('This msg is already in our inbox. Ignoring it.') blockMessage = True if not blockMessage: if messageEncodingType != 0: t = (inventoryHash, toAddress, fromAddress, subject, int(time.time()), body, 'inbox', messageEncodingType, 0, sigHash) helper_inbox.insert(t) queues.UISignalQueue.put( ('displayNewInboxMessage', (inventoryHash, toAddress, fromAddress, subject, body))) # 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 BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'): try: apiNotifyPath = BMConfigParser().get( 'bitmessagesettings', 'apinotifypath') except: apiNotifyPath = '' if apiNotifyPath != '': call([apiNotifyPath, "newMessage"]) # Let us now check and see whether our receiving address is # behaving as a mailing list if BMConfigParser().safeGetBoolean( toAddress, 'mailinglist') and messageEncodingType != 0: try: mailingListName = BMConfigParser().get( toAddress, 'mailinglistname') except: mailingListName = '' # Let us send out this message as a broadcast subject = self.addMailingListNameToSubject( subject, mailingListName) # Let us now send this message out as a broadcast message = time.strftime( "%a, %Y-%m-%d %H:%M:%S UTC", time.gmtime() ) + ' Message ostensibly from ' + fromAddress + ':\n\n' + body fromAddress = toAddress # The fromAddress for the broadcast that we are about to send is the toAddress (my address) for the msg message we are currently processing. ackdataForBroadcast = OpenSSL.rand( 32 ) # We don't actually need the ackdataForBroadcast for acknowledgement since this is a broadcast message but we can use it to update the user interface when the POW is done generating. toAddress = '[Broadcast subscribers]' ripe = '' # We really should have a discussion about how to # set the TTL for mailing list broadcasts. This is obviously # hard-coded. TTL = 2 * 7 * 24 * 60 * 60 # 2 weeks t = ( '', toAddress, ripe, fromAddress, subject, message, ackdataForBroadcast, int(time.time()), # sentTime (this doesn't change) int(time.time()), # lastActionTime 0, 'broadcastqueued', 0, 'sent', messageEncodingType, TTL) helper_sent.insert(t) queues.UISignalQueue.put( ('displayNewSentMessage', (toAddress, '[Broadcast subscribers]', fromAddress, subject, message, ackdataForBroadcast))) queues.workerQueue.put(('sendbroadcast', '')) # Don't send ACK if invalid, blacklisted senders, invisible messages, disabled or chan if self.ackDataHasAValidHeader(ackData) and \ not blockMessage and \ messageEncodingType != 0 and \ not BMConfigParser().safeGetBoolean(toAddress, 'dontsendack') and \ not BMConfigParser().safeGetBoolean(toAddress, 'chan'): shared.checkAndShareObjectWithPeers(ackData[24:]) # Display timing data timeRequiredToAttemptToDecryptMessage = time.time( ) - messageProcessingStartTime shared.successfullyDecryptMessageTimings.append( timeRequiredToAttemptToDecryptMessage) sum = 0 for item in shared.successfullyDecryptMessageTimings: sum += item logger.debug('Time to decrypt this message successfully: %s\n\ Average time for all message decryption successes since startup: %s.' % (timeRequiredToAttemptToDecryptMessage, sum / len(shared.successfullyDecryptMessageTimings)))
def checkackdata(self, data): # Let's check whether this is a message acknowledgement bound for us. if len(data) < 32: return readPosition = 20 # bypass the nonce, time, and object type # chomp version number versionNumber, varIntLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += varIntLength # chomp stream number streamNumber, varIntLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += varIntLength if data[readPosition:] in shared.ackdataForWhichImWatching: logger.info('This object is an acknowledgement bound for me.') del shared.ackdataForWhichImWatching[data[readPosition:]] sqlExecute('UPDATE sent SET status=?, lastactiontime=? WHERE ackdata=?', 'ackreceived', int(time.time()), data[readPosition:]) queues.UISignalQueue.put(('updateSentItemStatusByAckdata', (data[readPosition:], tr._translate("MainWindow",'Acknowledgement of the message received %1').arg(l10n.formatTimestamp())))) else: logger.debug('This object is not an acknowledgement bound for me.')