Exemplo n.º 1
0
 def servePage(self, view, url, params):
     if url == "/edit":
         selectedLang = params.get('lang', None)
         if selectedLang and len(selectedLang) == 2:
             Config.setProperty(Config.KEY_LANGUAGE, selectedLang)
             # I18nManager will be triggered here because it listens to the Config
         fsf = params.get('friendsseefriends', None)
         friendsseefriends = fsf is not None and len(fsf) > 0
         Config.setProperty(Config.KEY_ALLOW_FRIENDS_TO_SEE_FRIENDS,
                            friendsseefriends)
         slw = params.get('showlogwindow', None)
         showlogwindow = slw is not None and len(slw) > 0
         Config.setProperty(Config.KEY_SHOW_LOG_WINDOW, showlogwindow)
         # If Config has changed, may need to update profile to include/hide friends info
         DbI.updateContactList(friendsseefriends)
         # When friends are notified next time, the profile's hash will be calculated and sent
         afw = params.get('allowfriendrequests', None)
         allowfriendrequests = afw is not None and len(afw) > 0
         Config.setProperty(Config.KEY_ALLOW_FRIEND_REQUESTS,
                            allowfriendrequests)
         # Save config to file in case it's changed
         Config.save()
         contents = self.buildPage({
             'pageTitle':
             I18nManager.getText("settings.title"),
             'pageBody':
             "<p>Settings changed... should I go back to settings or back to home now?</p>",
             'pageFooter':
             "<p>Footer</p>"
         })
         view.setHtml(contents)
     else:
         pageProps = {
             "friendsseefriends":
             "checked" if Config.getProperty(
                 Config.KEY_ALLOW_FRIENDS_TO_SEE_FRIENDS) else "",
             "allowfriendrequests":
             "checked" if Config.getProperty(
                 Config.KEY_ALLOW_FRIEND_REQUESTS) else "",
             "showlogwindow":
             "checked"
             if Config.getProperty(Config.KEY_SHOW_LOG_WINDOW) else "",
             "language_en":
             "",
             "language_de":
             ""
         }
         pageProps["language_" +
                   Config.getProperty(Config.KEY_LANGUAGE)] = "selected"
         #print("body:", self.formtemplate.getHtml(pageProps))
         contents = self.buildPage({
             'pageTitle':
             I18nManager.getText("settings.title"),
             'pageBody':
             self.formtemplate.getHtml(pageProps),
             'pageFooter':
             "<p>Footer</p>"
         })
         view.setHtml(contents)
Exemplo n.º 2
0
 def closeEvent(self, event):
     '''Clean up before closing by stopping all services'''
     print("Closing Murmeli")
     # Tell postmen to stop working
     for p in self.postmen:
         p.stop()
     DbI.releaseDb()
     TorClient.stopTor()
     self.clearWebCache()
     event.accept()
Exemplo n.º 3
0
 def processPendingContacts(torId):
     print("Process pending contact accept responses from:", torId)
     foundReq = False
     for resp in DbI.getPendingContactMessages(torId):
         name = resp.get("fromName", None)
         if not name:
             profile = DbI.getProfile(torId)
             name = profile["displayName"]
         print("Found pending contact accept request from: ", name)
         # Check signature using keyring
         _, signatureKey = CryptoClient.decryptAndCheckSignature(
             resp.get("encryptedMsg", None))
         if signatureKey:
             foundReq = True
             # Insert new message into inbox with message contents
             rowToStore = {
                 "messageType": "contactresponse",
                 "fromId": resp.get("fromId", None),
                 "fromName": name,
                 "accepted": True,
                 "messageBody": resp.get("messageBody", ""),
                 "timestamp": resp.get("timestamp", None),
                 "messageRead": True,
                 "messageReplied": True,
                 "recipients": DbI.getOwnTorid()
             }
             DbI.addToInbox(rowToStore)
     if foundReq:
         DbI.updateProfile(torId, {"status": "untrusted"})
         # Delete all pending contact responses from this torId
         DbI.deletePendingContactMessages(torId)
Exemplo n.º 4
0
 def sendReferRequestMessage(sendToId, requestedId, intro):
     '''Send a message to sendToId, to ask that they recommend you to requestedId'''
     sendToProfile = DbI.getProfile(sendToId)
     if sendToProfile and sendToProfile.get("status", "nostatus") == "trusted" \
       and requestedId != DbI.getOwnTorid():
         print("Send message to", sendToId, "requesting referral of",
               requestedId)
         notify = ContactReferRequestMessage(friendId=requestedId,
                                             introMessage=intro)
         notify.recipients = [sendToId]
         DbI.addToOutbox(notify)
Exemplo n.º 5
0
 def broadcastOnlineStatus(self):
     '''Queue a status notification message for each of our trusted contacts'''
     print("Outgoing postman is broadcasting the status...")
     self._broadcasting = True
     profileList = DbI.getTrustedProfiles()
     if profileList:
         msg = StatusNotifyMessage(online=True, ping=True, profileHash=None)
         msg.recipients = [c['torid'] for c in profileList]
         DbI.addToOutbox(msg)
     self._broadcasting = False
     self.flushSignal.emit()
Exemplo n.º 6
0
    def handleReceiveAccept(torId, name, keyStr):
        '''We have requested contact with another id, and this has now been accepted.
		So we can import their public key into our keyring and update their status
		from "requested" to "untrusted"'''
        # Use keyStr to update keyring and get the keyId
        keyId = CryptoClient.importPublicKey(keyStr)
        # Store the keyId and name in their existing row, and update status to "untrusted"
        DbI.updateProfile(torId, {
            "name": name,
            "status": "untrusted",
            "keyid": keyId
        })
Exemplo n.º 7
0
    def handleInitiate(torId, displayName):
        '''We have requested contact with another id, so we can set up
		this new contact's name with a status of "requested"'''
        # TODO: If row already exists then get status (and name/displayname) and error with it
        # Add new row in db with id, name and "requested"
        if torId and torId != DbI.getOwnTorid():
            DbI.updateProfile(
                torId, {
                    'displayName': displayName,
                    'name': displayName,
                    'status': 'requested'
                })
Exemplo n.º 8
0
    def __init__(self, *args):
        self.logPanel = LogWindow()
        GuiWindow.__init__(self, lowerItem=self.logPanel)
        self.clearWebCache()
        self.postmen = None
        self.toolbar = self.makeToolbar([
            ("images/toolbar-home.png", self.onHomeClicked,
             "mainwindow.toolbar.home"),
            ("images/toolbar-people.png", self.onContactsClicked,
             "mainwindow.toolbar.contacts"),
            ("images/toolbar-messages.png", self.onMessagesClicked,
             "mainwindow.toolbar.messages"),
            ("images/toolbar-messages-highlight.png", self.onMessagesClicked,
             "mainwindow.toolbar.messages"),
            ("images/toolbar-calendar.png", self.onCalendarClicked,
             "mainwindow.toolbar.calendar"),
            ("images/toolbar-settings.png", self.onSettingsClicked,
             "mainwindow.toolbar.settings")
        ])
        self.addToolBar(self.toolbar)
        self.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
        # status bar
        self.statusbar = QtWidgets.QStatusBar(self)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)

        self.setWindowTitle(I18nManager.getText("mainwindow.title"))

        self.setStatusTip("Murmeli")
        self.setPageServer(PageServer())
        self.navigateTo("/")
        # we want to be notified of Config changes
        Config.registerSubscriber(self)
        self.postmen = [
            postmen.IncomingPostman(self),
            postmen.OutgoingPostman(self)
        ]
        self.postmen[1].messageSentSignal.connect(self.logPanel.notifyLogEvent)
        MessageShuffler.getTannoy().updateSignal.connect(
            self.logPanel.notifyLogEvent)
        # Make sure Tor client is started
        if not TorClient.isStarted():
            TorClient.startTor()
        # Create database instance if not already set
        if not DbI.hasDbSet():
            DbI.setDb(MurmeliDb(Config.getSsDatabaseFile()))
        # Make sure the status of the contacts matches our keyring
        missingKeyNames = ContactMaker.checkAllContactsKeys()
        if missingKeyNames:
            warningTexts = [I18nManager.getText("warning.keysnotfoundfor")
                            ] + missingKeyNames
            QtWidgets.QMessageBox.warning(self, "Murmeli",
                                          "\n   ".join(warningTexts))
Exemplo n.º 9
0
 def keyFingerprintChecked(torId):
     '''The fingerprint of this contact's public key has been checked (over a separate channel)'''
     # Check that userid exists and that status is currently "untrusted" (trusted also doesn't hurt)
     profile = DbI.getProfile(torId)
     if profile and profile["status"] in ["untrusted", "trusted"]:
         # Update the user's status to trusted
         DbI.updateProfile(torId, {"status": "trusted"})
         # Trigger a StatusNotify to tell them we're online
         notify = StatusNotifyMessage(online=True,
                                      ping=True,
                                      profileHash=None)
         notify.recipients = [torId]
         DbI.addToOutbox(notify)
Exemplo n.º 10
0
 def setUp(self):
     Config.load()
     CryptoClient.useTestKeyring()
     self.FRIEND_TORID = "zo7quhgn1nq1uppt"
     FRIEND_KEYID = "3B898548F994C536"
     TestUtils.setupOwnProfile("46944E14D24D711B")  # id of key1
     DbI.updateProfile(
         self.FRIEND_TORID, {
             "status": "trusted",
             "keyid": FRIEND_KEYID,
             "name": "Norbert Jones",
             "displayName": "Uncle Norbert"
         })
     TestUtils.setupKeyring(["key1_private", "key2_public"])
Exemplo n.º 11
0
 def _createUnencryptedPayload(self):
     if self.senderId is None:
         self.senderId = DbI.getOwnTorid()
     return self.packBytesTogether([
         self.encodeNumberToBytes(self.messageType, 1), self.senderId,
         self._createSubpayload()
     ])
Exemplo n.º 12
0
 def sendMessage(self, message, whoto):
     # Check status of recipient in profile
     profile = DbI.getProfile(whoto)
     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.instance().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
Exemplo n.º 13
0
 def _createSubpayload(self):
     '''Use the stored fields to pack the payload contents together'''
     if self.senderKey is None: self.senderKey = self.getOwnPublicKey()
     # Get own torid and name
     if not self.senderId: self.senderId = DbI.getOwnTorid()
     if not self.senderName:
         self.senderName = DbI.getProfile().get('name', self.senderId)
     if not self.introMessage: self.introMessage = ""
     nameAsBytes = self.senderName.encode('utf-8')
     messageAsBytes = self.introMessage.encode('utf-8')
     print("Packing contact request with senderId", self.senderId)
     return self.packBytesTogether([
         self.senderId,
         self.encodeNumberToBytes(len(nameAsBytes), 4), nameAsBytes,
         self.encodeNumberToBytes(len(messageAsBytes), 4), messageAsBytes,
         self.senderKey
     ])
Exemplo n.º 14
0
    def getSharedAndPossibleContacts(torid):
        '''Check which contacts we share with the given torid and which ones we could recommend to each other'''
        nameMap = {}
        ourContactIds = set()
        trustedContactIds = set()
        theirContactIds = set()
        # Get our id so we can exclude it from the sets
        myTorId = DbI.getOwnTorid()
        if torid == myTorId:
            return (None, None, None, None)
        # Find the contacts of the specified person
        selectedProfile = DbI.getProfile(torid)
        selectedContacts = selectedProfile.get(
            'contactlist', None) if selectedProfile else None
        if selectedContacts:
            for s in selectedContacts.split(","):
                if s and len(s) >= 16:
                    foundid = s[0:16]
                    if foundid != myTorId:
                        foundName = s[16:]
                        theirContactIds.add(foundid)
                        nameMap[foundid] = foundName
        foundTheirContacts = len(theirContactIds) > 0
        # Now get information about our contacts
        for c in DbI.getMessageableProfiles():
            foundid = c['torid']
            ourContactIds.add(foundid)
            if c['status'] == 'trusted' and foundid != torid:
                trustedContactIds.add(foundid)
            nameMap[foundid] = c['displayName']
            # Should we check the contact information too?
            if not foundTheirContacts:
                foundContacts = c.get('contactlist', None)
                if foundContacts:
                    for s in foundContacts.split(","):
                        if s[0:16] == torid:
                            theirContactIds.add(foundid)
        # Now we have three sets of torids: our contacts, our trusted contacts, and their contacts.
        sharedContactIds = ourContactIds.intersection(
            theirContactIds)  # might be empty
        suggestionsForThem = trustedContactIds.difference(theirContactIds)
        possibleForMe = theirContactIds.difference(ourContactIds)
        # TODO: Maybe subtract requested contacts from the "possibleForMe" set?

        # Some or all of these sets may be empty, but we still return the map so we can look up names
        return (sharedContactIds, suggestionsForThem, possibleForMe, nameMap)
Exemplo n.º 15
0
 def _createSubpayload(self):
     '''Use the stored fields to pack the payload contents together'''
     if self.profileHash is None or self.profileHash == "":
         self.profileHash = dbutils.calculateHash(DbI.getProfile())
     return self.packBytesTogether([
         self.encodeNumberToBytes(1 if self.online else 0, 1),
         self.encodeNumberToBytes(1 if self.ping else 0, 1),
         self.profileHash
     ])
Exemplo n.º 16
0
    def construct(payload, isEncrypted=True):
        '''Factory constructor using a given payload and extracting the fields'''
        if not payload:
            return None
        signatureKey = None
        if isEncrypted:
            # Decrypt the payload with our key
            decrypted, signatureKey = CryptoClient.decryptAndCheckSignature(
                payload)
        else:
            decrypted = payload
        if decrypted:
            print("Asymmetric message, length of decrypted is", len(decrypted))
        else:
            print("Asymmetric message has no decrypted")
        # Separate fields of message into common ones and the type-specific payload
        msgType, subpayload, tstmp = AsymmetricMessage._stripFields(decrypted)
        print("Recovered timestamp='", tstmp, "' (", len(tstmp), ")")

        # Find a suitable subclass to call using the messageType
        msg = None
        if msgType == Message.TYPE_CONTACT_RESPONSE:
            msg = ContactResponseMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_STATUS_NOTIFY:
            msg = StatusNotifyMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_ASYM_MESSAGE:
            msg = RegularMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_INFO_REQUEST:
            msg = InfoRequestMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_INFO_RESPONSE:
            msg = InfoResponseMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_FRIEND_REFERRAL:
            msg = ContactReferralMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_FRIENDREFER_REQUEST:
            msg = ContactReferRequestMessage.constructFrom(subpayload)
        # Ask the message if it's ok to have no signature
        if isEncrypted and msg:
            if msg.acceptUnrecognisedSignature():
                # Save the encrypted contents so we can verify it later
                msg.encryptedContents = payload
            elif not signatureKey:
                msg = None
        if msg:
            try:
                msgTimestamp = tstmp.decode('utf-8')
            except:
                msgTimestamp = msg.makeCurrentTimestamp()
            msg.timestamp = Message.convertTimestampFromString(msgTimestamp)
            msg.signatureKeyId = signatureKey
            if signatureKey:
                print(
                    "Asymm setting senderId because I've got a signatureKey: '%s'"
                    % signatureKey)
                signatureId = DbI.findUserIdFromKeyId(signatureKey)
                if signatureId:
                    msg.senderId = signatureId
        return msg
Exemplo n.º 17
0
 def checkAllContactsKeys():
     '''Return a list of names for which the key can't be found'''
     nameList = []
     for c in DbI.getMessageableProfiles():
         torId = c['torid'] if c else None
         if torId:
             keyId = c['keyid']
             if not keyId:
                 print("No keyid found for torid", torId)
                 nameList.append(c['displayName'])
             elif not CryptoClient.getPublicKey(keyId):
                 print("CryptoClient hasn't got a public key for torid",
                       torId)
                 nameList.append(c['displayName'])
             if not keyId or not CryptoClient.getPublicKey(keyId):
                 # We haven't got their key in our keyring!
                 DbI.updateProfile(torId, {"status": "requested"})
     return nameList
Exemplo n.º 18
0
 def setupOwnProfile(keyId):
     tempDb = MurmeliDb()
     DbI.setDb(tempDb)
     DbI.updateProfile(
         TestUtils._ownTorId, {
             "status":
             "self",
             "ownprofile":
             True,
             "keyid":
             keyId,
             "name":
             "Geoffrey Lancaster",
             "displayName":
             "Me",
             "description":
             "Ä fictitious person with a couple of Umläute in his description."
         })
Exemplo n.º 19
0
    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.instance().comeOnline(DbI.getOwnTorid())

        if message.senderMustBeTrusted:
            sender = DbI.getProfile(message.senderId)
            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)

        elif message.encryptionType == Message.ENCTYPE_RELAY:
            # Get received bytes of message, and add to Outbox, send to everybody EXCEPT the sender
            bytesToSend = message.createOutput(None)
            if bytesToSend:
                # add to outbox, but don't send it back to message.senderId
                DbI.addRelayMessageToOutbox(bytesToSend, message.senderId)
        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)
Exemplo n.º 20
0
 def testProfileResponse(self):
     m = message.InfoResponseMessage(
         message.InfoRequestMessage.INFO_PROFILE)
     output = m.createUnencryptedOutput()
     bac = message.Message.MessageFromReceivedData(output, False)
     self.assertIsNotNone(bac, "couldn't decode the data")
     self.assertEqual(message.InfoRequestMessage.INFO_PROFILE, bac.infoType)
     mydescription = DbI.getProfile()['description']
     bacProfile = bac.profile
     self.assertEqual(mydescription, bacProfile['description'])
Exemplo n.º 21
0
 def generateAddPage(self):
     '''Build the form page for adding a new user, using the template'''
     bodytext = self.addtemplate.getHtml({"owntorid": DbI.getOwnTorid()})
     return self.buildPage({
         'pageTitle':
         I18nManager.getText("contacts.title"),
         'pageBody':
         bodytext,
         'pageFooter':
         "<p>Footer</p>"
     })
Exemplo n.º 22
0
 def finish(self):
     '''Finished the key gen'''
     # Store key, name in the database for our own profile
     selectedKey = self.privateKeys[self.keypairListWidget.currentRow()]
     ownid = TorClient.getOwnId()
     # See if a name was entered before, if so use that
     myname = self.keygenParamBoxes['name'].text()
     if not myname:
         # Extract the name from the string which comes back from the key as "'Some Name (no comment) <*****@*****.**>'"
         myname = self.extractName(selectedKey['uids'])
     profile = {
         "name": myname,
         "keyid": selectedKey['keyid'],
         "torid": ownid,
         "status": "self",
         "ownprofile": True
     }
     # Store this in the database
     DbI.updateProfile(ownid, profile)
     return True
Exemplo n.º 23
0
    def handleAccept(torId):
        '''We want to accept a contact request, so we need to find the request(s),
		and use it/them to update our keyring and our database entry'''

        # Get this person's current status from the db, if available
        profile = DbI.getProfile(torId)
        status = profile.get("status", None) if profile else None

        # Look for the contact request(s) in the inbox, and extract the name and publicKey
        senderName, senderKeystr, directRequest = ContactMaker.getContactRequestDetails(
            torId)
        keyValid = senderKeystr and len(senderKeystr) > 20

        if keyValid:
            if status in [None, "requested"]:
                # add key to keyring
                keyId = CryptoClient.importPublicKey(senderKeystr)
                # work out what name and status to stores
                storedSenderName = profile["name"] if profile else None
                nameToStore = storedSenderName if storedSenderName else senderName
                statusToStore = "untrusted" if directRequest else "pending"
                # add or update the profile
                DbI.updateProfile(
                    torId, {
                        "status": statusToStore,
                        "keyid": keyId,
                        "name": nameToStore,
                        "displayName": nameToStore
                    })
                ContactMaker.processPendingContacts(torId)
            elif status == "pending":
                print("Request already pending, nothing to do")
            elif status in ["untrusted", "trusted"]:
                # set status to untrusted?  Send response?
                print("Trying to handle an accept but status is already",
                      status)
            # Move all corresponding requests to be regular messages instead
            DbI.changeRequestMessagesToRegular(torId)
        else:
            print("Trying to handle an accept but key isn't valid")
Exemplo n.º 24
0
 def run(self):
     # Check each of the services in turn
     self.successFlags = {}
     # Database
     time.sleep(0.5)
     DbI.setDb(MurmeliDb(Config.getSsDatabaseFile()))
     self.successFlags['database'] = True
     self.updatedSignal.emit()
     time.sleep(0.5)
     # Gnupg
     self.successFlags['gpg'] = CryptoClient.checkGpg()
     self.updatedSignal.emit()
     time.sleep(1)
     # Tor
     if TorClient.startTor():
         torid = TorClient.getOwnId()
         if torid:
             print("Started tor, our own id is: ", torid)
             self.successFlags['tor'] = True
         else:
             print("Failed to start tor")
     else:
         print("startTor returned false :(")
Exemplo n.º 25
0
 def _createSubpayload(self):
     '''Pack the specific fields into the subpayload'''
     # Get own name
     if self.senderName is None:
         self.senderName = DbI.getProfile().get('name', self.senderId)
     myPublicKey = self.getOwnPublicKey()
     messageAsBytes = self.message.encode('utf-8')
     nameAsBytes = self.senderName.encode('utf-8')
     subpayload = Message.packBytesTogether([
         self.encodeNumberToBytes(len(nameAsBytes), 4), nameAsBytes,
         self.encodeNumberToBytes(len(messageAsBytes), 4), messageAsBytes,
         myPublicKey
     ])
     return subpayload
Exemplo n.º 26
0
 def _createSubpayload(self):
     '''Use the stored fields to pack the payload contents together'''
     ownProfile = DbI.getProfile()
     if self.infoType is None:
         self.infoType = InfoRequestMessage.INFO_PROFILE
     if self.profileString is None:
         self.profileString = dbutils.getProfileAsString(ownProfile)
     self.profileHash = dbutils.calculateHash(ownProfile)
     return self.packBytesTogether([
         self.encodeNumberToBytes(self.infoType),
         self.encodeNumberToBytes(len(self.profileString),
                                  4), self.profileString,
         self.encodeNumberToBytes(len(self.profileHash), 4),
         self.profileHash
     ])
Exemplo n.º 27
0
 def construct(payload, isEncrypted):
     '''Construct a message from its payload'''
     originalPayload, signKey = CryptoClient.verifySignedData(
         payload) if isEncrypted else (payload, None)
     if originalPayload:
         # The payload could be verified and extracted, but we still don't know
         # if the contents are for me or for somebody else (probably for somebody else!)
         messageForMe = Message.MessageFromReceivedData(
             originalPayload, isEncrypted)
         if messageForMe:
             return messageForMe
         else:
             msg = RelayingMessage(rcvdBytes=originalPayload)
             msg.senderId = DbI.findUserIdFromKeyId(signKey)
             return msg
Exemplo n.º 28
0
	def testAvatars(self):
		'''Test the loading, storing and exporting of binary avatar images'''
		db = supersimpledb.MurmeliDb()
		DbI.setDb(db)
		inputPath = "testdata/example-avatar.jpg"
		outPath = "cache/avatar-deadbeef.jpg"
		if os.path.exists(outPath):
			os.remove(outPath)
		os.makedirs('cache', exist_ok=True)
		self.assertFalse(os.path.exists(outPath))
		DbI.updateProfile("deadbeef", {"profilepicpath":inputPath})
		# Output file still shouldn't exist, we didn't give a path to write picture to
		self.assertFalse(os.path.exists(outPath))
		DbI.updateProfile("deadbeef", {"profilepicpath":inputPath}, "cache")
		# Output file should exist now
		self.assertTrue(os.path.exists(outPath))
		# TODO: Any way to compare input with output?  They're not the same.
		DbI.releaseDb()
Exemplo n.º 29
0
 def _createSubpayload(self):
     '''Pack the specific fields into the subpayload'''
     # Get own name
     if not self.friendName:
         self.friendName = DbI.getProfile(self.friendId).get(
             'name', self.friendId)
     publicKey = self.getPublicKey(torid=self.friendId)
     # TODO: Complain if publicKey is empty
     messageAsBytes = self.message.encode('utf-8')
     nameAsBytes = self.friendName.encode('utf-8')
     subpayload = Message.packBytesTogether([
         self.friendId,
         self.encodeNumberToBytes(len(nameAsBytes), 4), nameAsBytes,
         self.encodeNumberToBytes(len(messageAsBytes), 4), messageAsBytes,
         publicKey
     ])
     return subpayload
Exemplo n.º 30
0
    def generateFingerprintsPage(self, userid):
        '''Build the page for checking the fingerprints of the selected user'''
        # First, get the name of the user
        person = DbI.getProfile(userid)
        dispName = person['displayName']
        fullName = person['name']
        if dispName != fullName:
            fullName = dispName + " (" + fullName + ")"
        fc = self._makeFingerprintChecker(userid)
        # check it's ok to generate
        status = person.get('status', '')
        if not fc.valid \
          or status not in ['untrusted', 'trusted']:
            print("Not generating fingerprints page because status is", status)
            return None

        # Get one set of words for us and three sets for them
        printsAlreadyChecked = (person.get('status', '') == "trusted")
        bodytext = self.fingerprintstemplate.getHtml({
            "mywords":
            fc.getCodeWords(True, 0, "en"),
            "theirwords0":
            fc.getCodeWords(False, 0, "en"),
            "theirwords1":
            fc.getCodeWords(False, 1, "en"),
            "theirwords2":
            fc.getCodeWords(False, 2, "en"),
            "fullname":
            fullName,
            "shortname":
            dispName,
            "userid":
            userid,
            "alreadychecked":
            printsAlreadyChecked
        })
        return self.buildPage({
            'pageTitle':
            I18nManager.getText("contacts.title"),
            'pageBody':
            bodytext,
            'pageFooter':
            "<p>Footer</p>"
        })