Example #1
0
 def CreateUnusedLK(self):
     """Create a LockedKey with a random password."""
     lk = LockedKey()
     password = lk.generate(random=True)
     unusedkey = {
         'encryptedprivkey': lk.encryptedprivkey,
         'pubkey': lk.pubkey,
         'password': password
     }
     return unusedkey
Example #2
0
    def get_pmkey(self, talkingto=None):
        """Generate a Private Message to person X.

        This is create a new Secret Key for the message, and add it to
        our pool. This helps avoid analysis, and helps ensure that if
        our master key is compromised, our older communications don't
        leak.

        """

        if self.passkey is None:
            raise Exception("Must have a valid passkey to run this method")

        # Step 1, Create a new Key for this person.
        newkey = LockedKey()
        newkey.generate(passkey=self.passkey, autoexpire=True)
        self.Keys['secret'].append(newkey)
        self.savemongo()
        return newkey
Example #3
0
    def restore_keys(self):
        """
        After being loaded in, re-create out key objects.
        """
        # Restore our master key
        if self.UserSettings['keys'].get('master') is not None:
            if 'encryptedprivkey' in self.UserSettings['keys']['master']:
                self.Keys['master'] = LockedKey(
                    pub=self.UserSettings['keys']['master']['pubkey'],
                    encryptedprivkey=self.UserSettings['keys']['master']
                    ['encryptedprivkey'])
                self.Keys['master'].generated = self.UserSettings['keys'][
                    'master']['generated']
                self.Keys['master'].expires = self.UserSettings['keys'][
                    'master']['expires']
                self.server.logger.info("Reconstructed with encryptedprivkey")
            else:
                # If we just have a pubkey string, do the best we can.
                if self.UserSettings['keys']['master'].get('pubkey'):
                    self.Keys['master'] = Key(
                        pub=self.UserSettings['keys']['master']['pubkey'])
                    self.Keys['master'].generated = self.UserSettings['keys'][
                        'master'].get('generated')
                    self.Keys['master'].expires = self.UserSettings['keys'][
                        'master'].get('expires')
                    self.server.logger.info(
                        "reconstructed user without privkey")
        else:
            print("Requested user had no master key.")
        # Restore any Posted communication keys.
        for key in self.UserSettings['keys'].get('posted', []):
            lk = LockedKey(pub=key['pubkey'],
                           encryptedprivkey=key['encryptedprivkey'])
            lk.generated = key['generated']
            lk.expires = key['expires']
            self.Keys['posted'].append(lk)

        # Restore any oneoff communication keys
        for key in self.UserSettings['keys'].get('secret', []):
            lk = LockedKey(pub=key['pubkey'],
                           encryptedprivkey=key['encryptedprivkey'])
            lk.generated = key['generated']
            lk.expires = key['expires']
            self.Keys['secret'].append(lk)
Example #4
0
 def CreateUnusedLK(self):
     """Create a LockedKey with a random password."""
     lk = LockedKey()
     password = lk.generate(random=True)
     unusedkey = {'encryptedprivkey': lk.encryptedprivkey, 'pubkey': lk.pubkey, 'password': password}
     return unusedkey
Example #5
0
    def generate(self,
                 AllowGuestKey=True,
                 password=None,
                 email=None,
                 username=None):
        """Create a Tavern user, filling in any missing information for
        existing users.

        Only creates keys if asked to.

        """

        # Ensure that these values are filled in.
        # Either by Saved values, Passed-in values, or by Null objects.

        # Create a string/immutable version of UserSettings that we can compare
        # against later to see if anything changed.

        tmpsettings = str(self.UserSettings) + str(self.Keys)

        if self.UserSettings.get('username') is None:
            if username is not None:
                self.UserSettings['username'] = username
            else:
                self.UserSettings['username'] = "******"

        if self.UserSettings.get('email') is None:
            if email is not None:
                self.UserSettings['email'] = email
            else:
                self.UserSettings['email'] = "*****@*****.**"

        if self.UserSettings['status'].get('guest') is None:
            self.UserSettings['status']['guest'] = True

        if not 'setpassword' in self.UserSettings['status']:
            self.UserSettings['status']['setpassword'] = None

        # If we've been told not to use a GuestKey, make sure we don't have
        # one.
        if AllowGuestKey is False and self.server.guestacct is not None:
            if self.server.guestacct.Keys.get(
                    'master') is not None and self.Keys.get(
                        'master') is not None:
                if self.Keys['master'].pubkey == self.server.guestacct.Keys[
                        'master'].pubkey:
                    print("Getting rid of a GuestKey.")
                    self.UserSettings['keys'] = {}
                    self.UserSettings['keys']['master'] = {}
                    self.passkey = None
                    self.Keys = {}
                    self.Keys['posted'] = []
                    self.Keys['secret'] = []
                    self.Keys['master'] = None

        # Ensure we don't somehow end up as an empty, but keyed user..
        if isinstance(self.Keys['master'], LockedKey):
            if self.Keys['master'].pubkey is None:
                self.Keys['master'] = None

        # Ensure we have a valid keys, one way or another.
        # If GuestKey is true, then use the server default accts.
        # Otherwise, make the keys.
        if self.Keys.get('master') is None:
            # Save if we're using the GuestKey or not.
            if AllowGuestKey:
                self.Keys = self.server.guestacct.Keys
                self.UserSettings['status']['guest'] = True
            else:
                print("Generating a LockedKey")
                pulledkey = self.server.unusedkeycache.get(block=True)
                self.Keys['master'] = LockedKey(
                    encryptedprivkey=pulledkey['encryptedprivkey'],
                    pub=pulledkey['pubkey'],
                    password=pulledkey['password'])

                self.UserSettings['status']['guest'] = False
                self.passkey = self.Keys['master'].get_passkey(
                    password=pulledkey['password'])

        # Ensure we have a valid/current public posted key.
        if self.UserSettings['status']['guest'] is not True:
            # Set key to false, disprove assertion later.
            validcommkey = False
            # Make sure our Posted keys are in good shape.
            if len(self.Keys['posted']) > 0:
                # Sort the keys that we've already posted, highest expires
                # first.
                self.Keys['posted'].sort(key=lambda e: (e.expires),
                                         reverse=True)

                # Are we still in the same month we generated the key in?
                gen_month = datetime.datetime.fromtimestamp(
                    self.Keys['posted'][-1].generated).month
                gen_year = datetime.datetime.fromtimestamp(
                    self.Keys['posted'][-1].generated).year
                if gen_year == datetime.datetime.now().year:
                    if gen_month == datetime.datetime.now().month:
                        validcommkey = True

            # Either we have no key, or an old one.
            if validcommkey is False:
                print("Generating new posted key")
                newkey = LockedKey()
                newkey.generate(passkey=self.passkey)

                # We want the key to expire on the last second of NEXT month.
                # So if it's currently Oct 15, we want the answer Nov31-23:59:59
                # This makes it harder to pin down keys by when they were
                # generated, since it's not based on current time

                number_of_days_this_month = calendar.monthrange(
                    datetime.datetime.now().year,
                    datetime.datetime.now().month)[1]
                number_of_days_next_month = calendar.monthrange(
                    datetime.datetime.now().year,
                    datetime.datetime.now().month + 1)[1]
                two_months = datetime.datetime.now() + datetime.timedelta(
                    days=number_of_days_this_month + number_of_days_next_month)
                expiresdate = datetime.date(two_months.year, two_months.month,
                                            1) - datetime.timedelta(days=1)
                expiresdatetime = datetime.datetime.combine(
                    expiresdate, datetime.time.max)
                expirestamp = calendar.timegm(expiresdatetime.utctimetuple())

                newkey.expires = expirestamp
                self.Keys['posted'].append(newkey)

        if password is not None and self.passkey is None:
            self.passkey = self.Keys['master'].get_passkey(password=password)

        if self.UserSettings.get('time_created') is None:
            self.UserSettings['time_created'] = int(time.time())

        if self.UserSettings.get('display_useragent') is None:
            self.UserSettings['display_useragent'] = False

        if self.UserSettings.get('theme') is None:
            self.UserSettings['theme'] = 'default'

        if self.UserSettings.get('followedTopics') is None:
            self.UserSettings['followedTopics'] = []

        if self.UserSettings.get('allowembed') is None:
            self.UserSettings['allowembed'] = 0

        if self.UserSettings['followedTopics'] == []:
            self.followTopic("StarTrek")
            self.followTopic("Python")
            self.followTopic("Egypt")
            self.followTopic("Funny")

        if self.UserSettings.get('maxposts') is None:
            self.UserSettings['maxposts'] = 100

        if self.UserSettings.get('maxreplies') is None:
            self.UserSettings['maxreplies'] = 100

        # Set Friendlyname to most recent post, or Anonymous for lurkers
        if self.UserSettings.get('friendlyname') is None:
            if self.UserSettings['status']['guest'] is False:
                # They're registered, they may have posted.
                posts = self.server.getUsersPosts(self.Keys['master'].pubkey)
                if len(posts) > 0:
                    self.UserSettings['friendlyname'] = posts[0].dict[
                        'envelope']['local']['author']['friendlyname']
            if self.UserSettings.get('friendlyname') is None:
                self.UserSettings['friendlyname'] = 'Anonymous'

        if self.UserSettings.get('include_location') is None:
            self.UserSettings['include_location'] = False

        if self.UserSettings.get('ignoreedits') is None:
            self.UserSettings['ignoreedits'] = False

        if self.UserSettings.get('author_wordhash') is None:
            self.UserSettings[
                'author_wordhash'] = self.server.wordlist.wordhash(
                    self.Keys['master'].pubkey)

        if self.UserSettings.get('author_sha512') is None:
            if self.UserSettings['status']['guest'] is False:
                self.UserSettings['author_sha512'] = hashlib.sha512(
                    self.Keys['master'].pubkey.encode('utf-8')).hexdigest()
            else:
                self.UserSettings['author_sha512'] = None

        # Determine if we changed anything without an explicit dirty flag.
        if tmpsettings == str(self.UserSettings) + str(self.Keys):
            return False
        else:
            return True