KeePass support
This commit is contained in:
parent
1f28ee3622
commit
ff2cddbf65
@ -88,3 +88,11 @@ This configures [`keyringer`](https://0xacab.org/rhatto/keyringer) (based on GPG
|
||||
|
||||
`keyringer` need a "keyring" to search in, and you can (optionally) specify a folder to be
|
||||
prefixed to the password names created from the realm.
|
||||
|
||||
#### keepass
|
||||
|
||||
```yaml
|
||||
keepass: /home/me/mypasswords.kdbx
|
||||
```
|
||||
|
||||
This configures KeePass as password manager; it will prompt for your master password every time.
|
||||
|
@ -22,6 +22,11 @@ dependencies = [
|
||||
"PyYAML",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
keepass = [
|
||||
"pykeepass",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
ldaptool = "ldaptool._main:main"
|
||||
|
||||
@ -46,5 +51,6 @@ module = [
|
||||
"ldap",
|
||||
"ldap.dn",
|
||||
"ldap.controls.libldap",
|
||||
"pykeepass",
|
||||
]
|
||||
ignore_missing_imports = true
|
||||
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import abc
|
||||
import dataclasses
|
||||
import getpass
|
||||
import os
|
||||
import os.path
|
||||
import shlex
|
||||
@ -122,6 +123,34 @@ class Keyringer(PasswordManager):
|
||||
return result.stdout.strip()
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Keepass(PasswordManager):
|
||||
database: str
|
||||
|
||||
@staticmethod
|
||||
def load(data: typing.Any) -> Keepass:
|
||||
try:
|
||||
import pykeepass # make sure dependency is present during config loading
|
||||
|
||||
assert pykeepass # so it isn't unused...
|
||||
except ImportError:
|
||||
raise Exception(
|
||||
"Missing (optional) dependency for keepass support - please install (python package for) pykeepass"
|
||||
)
|
||||
assert isinstance(
|
||||
data, str
|
||||
), "keepass integration expects a single string as configuration with the database location"
|
||||
return Keepass(database=data)
|
||||
|
||||
def get_password(self, password_name: str) -> str:
|
||||
import pykeepass # already made sure it is avaiable above
|
||||
|
||||
password = getpass.getpass(f"KeePass password for database {self.database}: ")
|
||||
kp = pykeepass.PyKeePass(self.database, password=password)
|
||||
entry = kp.find_entries(username=password_name, first=True)
|
||||
return entry.password # type: ignore
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class PasswordScript(PasswordManager):
|
||||
command: list[str]
|
||||
@ -173,6 +202,10 @@ class Config:
|
||||
if password_manager:
|
||||
raise ValueError("Can only set a single password manager")
|
||||
password_manager = Keyringer.load(data.pop("keyringer"))
|
||||
if "keepass" in data:
|
||||
if password_manager:
|
||||
raise ValueError("Can only set a single password manager")
|
||||
password_manager = Keepass.load(data.pop("keepass"))
|
||||
if "password-script" in data:
|
||||
if password_manager:
|
||||
raise ValueError("Can only set a single password manager")
|
||||
@ -189,6 +222,5 @@ class Config:
|
||||
raise RuntimeError("Can't get password without acccount - should use kerberos instead")
|
||||
if self.password_manager:
|
||||
return self.password_manager.get_password(realm.password_name)
|
||||
import getpass
|
||||
|
||||
return getpass.getpass(f"Enter password for {realm.password_name}: ")
|
||||
|
Loading…
Reference in New Issue
Block a user