Пример #1
0
    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
Пример #2
0
    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)
Пример #3
0
 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
Пример #4
0
    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)
Пример #5
0
    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)
Пример #6
0
    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)
Пример #7
0
    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)
Пример #8
0
 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)
Пример #9
0
    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)
Пример #10
0
    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'))
Пример #11
0
    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)
Пример #12
0
    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")
Пример #13
0
 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)