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
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
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)
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
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