def dealWithMessage(message):
		'''Examine the received message and decide what to do with it'''
		print("Hmm, the MessageShuffler has been given some kind of message")
		# We must be online if we've received a message
		Contacts.comeOnline(MessageShuffler.getOwnTorId())

		if message.senderMustBeTrusted:
			sender = DbClient.getProfile(message.senderId, False)
			if not sender or sender['status'] != "trusted":
				return # throw message away

		if not message.isComplete():
			print("A message of type", message.encryptionType, "was received but it's not complete - throwing away")
			return # throw message away

		# if it's not encrypted, it's for us -> save in inbox
		if message.encryptionType == Message.ENCTYPE_NONE:
			MessageShuffler.dealWithUnencryptedMessage(message)

		elif message.encryptionType == Message.ENCTYPE_SYMM:
			# if it's symmetric, forget it for now
			pass

		elif message.encryptionType == Message.ENCTYPE_ASYM:
			MessageShuffler.dealWithAsymmetricMessage(message)

		else:
			print("Hä?  What kind of encryption type is that? ", message.encryptionType)

		# Log receipt of message (do we want to know about relays at all?)
		if message.encryptionType in [Message.ENCTYPE_NONE, Message.ENCTYPE_ASYM]:
			logMessage = "Message of type: %s received from %s" % (message.getMessageTypeKey(), message.senderId)
			MessageShuffler.getTannoy().shout(logMessage)
Example #2
0
 def testComingOnline(self):
     '''Check that a contact coming online is handled properly'''
     contacts = Contacts()
     contacts.comeOnline("abcdef")
     self.assertTrue(contacts.isOnline("abcdef"))
     self.assertIsNotNone(contacts.lastSeen("abcdef"),
                          "last seen time should be filled now")
     # Other contacts should still be offline
     self.assertFalse(contacts.isOnline("abcdef2"))
     self.assertFalse(contacts.isOnline("ABCDEF"))
     self.assertFalse(contacts.isOnline("ghijklmn"))
     self.assertIsNone(contacts.lastSeen("ghijklmn"),
                       "last seen time should be None")
     self.assertIsNone(contacts.lastSeen(None),
                       "last seen time should be None")
     self.assertIsNone(contacts.lastSeen(""),
                       "last seen time should be None")
Example #3
0
 def testGoingOffline(self):
     '''Check that a contact going offline is handled properly'''
     contacts = Contacts()
     contacts.comeOnline("abcdef")
     self.assertTrue(contacts.isOnline("abcdef"))
     self.assertIsNotNone(contacts.lastSeen("abcdef"),
                          "last seen time should be filled now")
     goOnlineTime = contacts.lastSeen("abcdef")
     # Now go offline again
     contacts.goneOffline("abcdef")
     self.assertFalse(contacts.isOnline("abcdef"))
     self.assertIsNotNone(contacts.lastSeen("abcdef"),
                          "last seen time should be filled now")
     goOfflineTime = contacts.lastSeen("abcdef")
     self.assertNotEqual(goOnlineTime, goOfflineTime)
     # Reappear
     contacts.comeOnline("abcdef")
     self.assertTrue(contacts.isOnline("abcdef"))
     self.assertIsNotNone(contacts.lastSeen("abcdef"),
                          "last seen time should be filled now")
     reappearTime = contacts.lastSeen("abcdef")
     self.assertNotEqual(goOnlineTime, reappearTime)
     self.assertNotEqual(goOfflineTime, reappearTime)
Example #4
0
	def sendMessage(self, message, whoto):
		# Check status of recipient in profile
		profile = DbClient.getProfile(whoto, False)
		status = profile['status'] if profile else "deleted"
		if status in ['deleted', 'blocked']:
			return self.RC_MESSAGE_IGNORED
		print("Trying to send message to '%s'" % whoto)
		if whoto is not None and len(whoto) == 16:
			try:
				s = socks.socksocket()
				s.setproxy(socks.PROXY_TYPE_SOCKS4, "localhost", 11109)
				s.connect((whoto + ".onion", 11009))
				numsent = s.send(message)
				s.close()
				if numsent != len(message):
					print("Oops - num bytes sent:", numsent, "but message has length:", len(message))
					# For really long messages, maybe need to chunk into 4k blocks or something?
				else:
					Contacts.comeOnline(whoto)
					return self.RC_MESSAGE_SENT
			except Exception as e:
				print("Woah, that threw something:", e)
		print("Bailed from the send attempt, returning failure")
		return self.RC_MESSAGE_FAILED   # it didn't work
	def dealWithAsymmetricMessage(message):
		'''Decide what to do with the given asymmetric message'''
		if message.senderId == MessageShuffler.getOwnTorId():
			print("*** Shouldn't receive a message from myself!")
			return
		# Sort message according to type
		if message.messageType == Message.TYPE_CONTACT_RESPONSE:
			print("Received a contact accept from", message.senderId, "name", message.senderName)
			if MessageShuffler._isProfileStatusOk(message.senderId, ['pending', 'requested', 'untrusted']):
				print(message.senderName, "'s public key is", message.senderKey)
				ContactMaker.handleReceiveAccept(message.senderId, message.senderName, message.senderKey)
				# Call DbClient to store new message in inbox
				rowToStore = {"messageType":"contactresponse", "fromId":message.senderId,
					"fromName":message.senderName, "messageBody":message.introMessage, "accepted":True,
					"messageRead":False, "messageReplied":False, "timestamp":message.timestamp,
					"recipients":MessageShuffler.getOwnTorId()}
				DbClient.addMessageToInbox(rowToStore)
			elif MessageShuffler._isProfileStatusOk(message.senderId, [None, 'blocked']):
				print("Received a contact response but I didn't send them a request!")
				print("Encrypted contents are:", message.encryptedContents)
				rowToStore = {"messageType":"contactresponse", "fromId":message.senderId,
					"fromName":message.senderName, "messageBody":message.introMessage, "accepted":True,
					"timestamp":message.timestamp, "encryptedMsg":message.encryptedContents}
				DbClient.addMessageToPendingContacts(rowToStore)
		elif message.messageType == Message.TYPE_STATUS_NOTIFY:
			if message.online:
				print("One of our contacts has just come online- ", message.senderId,
					"and hash is", message.profileHash)
				prof = DbClient.getProfile(userid=message.senderId, extend=False)
				if prof:
					storedHash = prof.get("profileHash", "empty")
					if message.profileHash != storedHash:
						reply = InfoRequestMessage(infoType=InfoRequestMessage.INFO_PROFILE)
						reply.recipients = [message.senderId]
						DbClient.addMessageToOutbox(reply)
					if message.ping:
						print("Now sending back a pong, too")
						reply = StatusNotifyMessage(online=True, ping=False, profileHash=None)
						reply.recipients = [message.senderId]
						DbClient.addMessageToOutbox(reply)
					else:
						print("It's already a pong so I won't reply")
				Contacts.comeOnline(message.senderId)
			else:
				print("One of our contacts is going offline -", message.senderId)
				Contacts.goneOffline(message.senderId)
		elif message.messageType == Message.TYPE_INFO_REQUEST:
			print("I've received an info request message for type", message.infoType)
			if MessageShuffler._isProfileStatusOk(message.senderId, ['trusted']):
				reply = InfoResponseMessage(message.messageType)
				reply.recipients = [message.senderId]
				DbClient.addMessageToOutbox(reply)
		elif message.messageType == Message.TYPE_INFO_RESPONSE:
			if message.profile and MessageShuffler._isProfileStatusOk(message.senderId, ['trusted', 'untrusted']):
				if message.profileHash:
					message.profile['profileHash'] = message.profileHash
				DbClient.updateContact(message.senderId, message.profile)
		elif message.messageType == Message.TYPE_ASYM_MESSAGE:
			print("It's a general kind of message, this should go in the Inbox, right?")
			if MessageShuffler._isProfileStatusOk(message.senderId, ['trusted', 'untrusted']):
				Contacts.comeOnline(message.senderId)
		else:
			# It's another asymmetric message type
			print("Hä?  What kind of asymmetric message type is that? ", message.messageType)