def __enter__(self): """Enter the context manager.""" if not self.exist(): raise PMError("%s is not a password repository." % self.prefix) if not self.isvalid(): raise PMError( "invalid credentials, password encryption/decryption aborted.") self.open() return self
def __init__(self, prefix=None, settings=None): self._binary = shutil.which(self.command) if self._binary is None: raise PMError(f"{self.command} is required.") # pragma: no cover self.env = dict(**os.environ) super().__init__(prefix, settings)
def _command(self, arg, data=None, nline=True): """Call to the password manager cli command.""" command = [self._binary] command.extend(arg) res, stdout, stderr = self._call(command, data, nline) if res: raise PMError(f"{stderr} {stdout}") return stdout
def open(self): """Open the keepass repository.""" if not PYKEEPASS: raise ImportError(name='pykeepass') try: self.keepass = PyKeePass(self.prefix, password=getpassword(self.prefix), keyfile=self.keyfile) except CredentialsIntegrityError as error: raise PMError(error)
def open(self): """Sign in to your Lastpass account.""" if self.prefix == '': raise PMError("Your Lastpass username is empty") status = [self._binary, 'status', '--quiet'] res, _, _ = self._call(status) if res: login = ['login', '--trust', '--color=never', self.prefix] password = getpassword('Lastpass') res = self._command(login, password)
def insert(self, entry): """Insert a password entry into the password repository. :param dict entry: The password entry to insert. :raises PMError: If the entry already exists or in case of a password manager error. The entry is converted into the following format: .. code-block:: console <password> <key>: <value> If ``PasswordManager.all`` is true, all the entry values are printed. Otherwise, only the key present in ``PasswordManager.keyslist`` are printed following the order from this list. The title, path, and group keys are ignored. If ``PasswordManager.force`` is true, it will overwrite previous entry. If the 'data' key is present, the entry is considered as a binary attachment and return the binary data. """ path = os.path.join(self.root, entry.get('path')) if not self.force: if os.path.isfile(os.path.join(self.prefix, path + '.gpg')): raise PMError("An entry already exists for %s." % path) if 'data' in entry: data = entry['data'] else: seen = {'password', 'path', 'title', 'group'} data = entry.get('password', '') + '\n' for key in self.keyslist: if key in seen: continue if key in entry: if 'otpauth' in key: data += "%s\n" % entry.get(key) else: data += "%s: %s\n" % (key, entry.get(key)) seen.add(key) if self.all: for key, value in entry.items(): if key in seen: continue data += "%s: %s\n" % (key, value) arg = ['insert', '--multiline', '--force', '--', path] return self._command(arg, data)
def open(self): """Open the keepass repository.""" if not PYKEEPASS: raise ImportError(name='pykeepass') try: self.keepass = PyKeePass(self.prefix, password=getpassword(self.prefix), keyfile=self.keyfile) except (CredentialsError, PayloadChecksumError, HeaderChecksumError) as error: # pragma: no cover raise PMError(error)
def open(self): """Create/Re-create CSV exported file.""" if self.action is Cap.IMPORT: super(GenericCSV, self).open() else: if os.path.isfile(self.prefix): if self.force: self.file = open(self.prefix, 'w', encoding=self.encoding) else: raise PMError("%s is already a file." % self.prefix) else: self.file = open(self.prefix, 'w', encoding=self.encoding)
def insert(self, entry): """Insert a password entry into KDBX encrypted vault file.""" ignore = {'password', 'path', 'title', 'group', 'data'} path = os.path.join(self.root, entry.get('path')) title = os.path.basename(path) group = os.path.dirname(path) root_group = self.keepass.root_group kpgroup = self.keepass.find_groups(path=group) if not kpgroup: for grp in group.split('/'): kpgroup = self.keepass.find_groups(path=grp) if not kpgroup: kpgroup = self.keepass.add_group(root_group, grp) root_group = kpgroup if not self.force: pkentry = self.keepass.find_entries(title=title, group=kpgroup, recursive=False, first=True) if pkentry is not None: raise PMError("An entry already exists for %s." % path) kpentry = self.keepass.add_entry(destination_group=kpgroup, title=title, username=entry.pop('login', ''), password=entry.pop('password', ''), url=entry.pop('url', None), notes=entry.pop('comments', None), tags=entry.pop('tags', None), expiry_time=entry.pop( 'expiry_time', None), icon=entry.pop('icon', None), force_creation=True) for key, value in entry.items(): if key in ignore: continue kpentry.set_custom_property(key, str(value)) if 'data' in entry: attid = self.keepass.add_binary(entry['data']) kpentry.add_attachment(attid, title)
def open(self): """Ini file import or dir of ini file or default dir. If ``self.prefix`` is a path, open it. If it is a path to a directory, open the files it contains If it is empty, import data from the default directory. """ if os.path.isfile(self.prefix): self.files = [open(self.prefix, 'r', encoding='utf-8')] else: if self.prefix == '': self.prefix = self.path elif not os.path.isdir(self.prefix): raise PMError("%s is neither a file nor a " "directory" % self.prefix) self.files = [] for path in glob.glob(self.prefix + '/*'): self.files.append(open(path, 'r'))
def insert(self, entry): """Insert a password entry into lastpass using lpass.""" path = os.path.join(self.root, entry['path']) entry['group'] = os.path.dirname(path) entry['title'] = os.path.basename(path) path = entry['group'].replace(os.sep, self.sep) + '/' + entry['title'] # Remove entries with the same name. uids = self.list(path) if uids: if not self.force: raise PMError(f"An entry already exists for {path}.") for uid in uids: self.remove(uid) # Insert the entry into lastpass seen = {'path', 'title', 'group'} exportkeys = { 'title': 'Name', 'password': '******', 'login': '******', 'url': 'URL', 'comments': 'Notes', } data = '' for key in self.keyslist: if key in seen: continue if key in entry: data += f"{exportkeys.get(key, key)}: {entry[key]}\n" seen.add(key) if self.all: for key, value in entry.items(): if key in seen: continue data += f"{key}: {value}\n" arg = ['add', '--sync=now', '--non-interactive', '--color=never', path] self._command(arg, data)
def __init__(self, prefix=None, settings=None): self._gpgbinary = shutil.which('gpg2') or shutil.which('gpg') super(PasswordStore, self).__init__(prefix, settings) self._setenv('PASSWORD_STORE_DIR') self._setenv('PASSWORD_STORE_KEY') self._setenv('PASSWORD_STORE_GIT', 'GIT_DIR') self._setenv('PASSWORD_STORE_GPG_OPTS') self._setenv('PASSWORD_STORE_X_SELECTION', 'X_SELECTION') self._setenv('PASSWORD_STORE_CLIP_TIME', 'CLIP_TIME') self._setenv('PASSWORD_STORE_UMASK') self._setenv('PASSWORD_STORE_GENERATED_LENGTH', 'GENERATED_LENGTH') self._setenv('PASSWORD_STORE_CHARACTER_SET', 'CHARACTER_SET') self._setenv('PASSWORD_STORE_CHARACTER_SET_NO_SYMBOLS', 'CHARACTER_SET_NO_SYMBOLS') self._setenv('PASSWORD_STORE_ENABLE_EXTENSIONS') self._setenv('PASSWORD_STORE_EXTENSIONS_DIR', 'EXTENSIONS') self._setenv('PASSWORD_STORE_SIGNING_KEY') self._setenv('GNUPGHOME') if prefix: self.prefix = prefix if 'PASSWORD_STORE_DIR' not in self.env or self.prefix is None: raise PMError("pass prefix unknown")
def open(self): """Ensure prefix is a path to a password repository.""" if not os.path.isdir(self.prefix): raise PMError("%s is not a password repository." % self.prefix)