Compare commits
5 Commits
21069e892e
...
34fcd259ef
Author | SHA1 | Date | |
---|---|---|---|
34fcd259ef | |||
f036713d71 | |||
f1d57487be | |||
04fd42c63b | |||
1a9829b93b |
@ -105,7 +105,7 @@ class _Context:
|
|||||||
try:
|
try:
|
||||||
self.config = search.Config.load()
|
self.config = search.Config.load()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise SystemExit(f"config error: {e}")
|
raise SystemExit(f"config error: {e!r}")
|
||||||
try:
|
try:
|
||||||
self.arguments = arguments_p.from_args(args)
|
self.arguments = arguments_p.from_args(args)
|
||||||
except decode.InvalidStep as e:
|
except decode.InvalidStep as e:
|
||||||
|
@ -7,6 +7,7 @@ import os
|
|||||||
import os.path
|
import os.path
|
||||||
import shlex
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
@ -28,13 +29,13 @@ class Realm:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load(name: str, data: typing.Any) -> Realm:
|
def load(name: str, data: typing.Any) -> Realm:
|
||||||
assert isinstance(data, dict)
|
assert isinstance(data, dict), f"Realm section isn't a dictionary: {data!r}"
|
||||||
domain = data.pop("domain")
|
domain = data["domain"]
|
||||||
servers = data.pop("servers").split()
|
servers = data["servers"].split()
|
||||||
forest_root_domain = data.pop("forest_root_domain", domain)
|
forest_root_domain = data.get("forest_root_domain", domain)
|
||||||
account = data.pop("account", None)
|
account = data.get("account", None)
|
||||||
password_file = data.pop("password_file", None)
|
password_file = data.get("password_file", None)
|
||||||
password_folder = data.pop("password_folder", None)
|
password_folder = data.get("password_folder", None)
|
||||||
return Realm(
|
return Realm(
|
||||||
name=name,
|
name=name,
|
||||||
domain=domain,
|
domain=domain,
|
||||||
@ -101,8 +102,8 @@ class Keyringer(PasswordManager):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def load(data: typing.Any) -> Keyringer:
|
def load(data: typing.Any) -> Keyringer:
|
||||||
assert isinstance(data, dict)
|
assert isinstance(data, dict)
|
||||||
keyring = data.pop("keyring")
|
keyring = data["keyring"]
|
||||||
folder = data.pop("folder")
|
folder = data.get("folder", "")
|
||||||
return Keyringer(keyring=keyring, folder=folder)
|
return Keyringer(keyring=keyring, folder=folder)
|
||||||
|
|
||||||
def get_password(self, password_name: str) -> str:
|
def get_password(self, password_name: str) -> str:
|
||||||
@ -145,9 +146,17 @@ class Keepass(PasswordManager):
|
|||||||
def get_password(self, password_name: str) -> str:
|
def get_password(self, password_name: str) -> str:
|
||||||
import pykeepass # already made sure it is avaiable above
|
import pykeepass # already made sure it is avaiable above
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
password = getpass.getpass(f"KeePass password for database {self.database}: ")
|
password = getpass.getpass(f"KeePass password for database {self.database}: ")
|
||||||
kp = pykeepass.PyKeePass(self.database, password=password)
|
kp = pykeepass.PyKeePass(self.database, password=password)
|
||||||
|
break
|
||||||
|
except pykeepass.exceptions.CredentialsError:
|
||||||
|
print("Invalid password", file=sys.stderr)
|
||||||
|
|
||||||
entry = kp.find_entries(username=password_name, first=True)
|
entry = kp.find_entries(username=password_name, first=True)
|
||||||
|
if not entry:
|
||||||
|
raise SystemExit(f"no KeePass entry for {password_name!r} found")
|
||||||
return entry.password # type: ignore
|
return entry.password # type: ignore
|
||||||
|
|
||||||
|
|
||||||
@ -190,8 +199,8 @@ class Config:
|
|||||||
with open(conf_path) as f:
|
with open(conf_path) as f:
|
||||||
data = yaml.safe_load(f)
|
data = yaml.safe_load(f)
|
||||||
assert isinstance(data, dict)
|
assert isinstance(data, dict)
|
||||||
assert "realms" in data
|
assert "realms" in data, "Missing realms section in config"
|
||||||
realms_data = data.pop("realms")
|
realms_data = data["realms"]
|
||||||
assert isinstance(realms_data, dict)
|
assert isinstance(realms_data, dict)
|
||||||
realms = {}
|
realms = {}
|
||||||
for name, realm_data in realms_data.items():
|
for name, realm_data in realms_data.items():
|
||||||
@ -201,15 +210,15 @@ class Config:
|
|||||||
if "keyringer" in data:
|
if "keyringer" in data:
|
||||||
if password_manager:
|
if password_manager:
|
||||||
raise ValueError("Can only set a single password manager")
|
raise ValueError("Can only set a single password manager")
|
||||||
password_manager = Keyringer.load(data.pop("keyringer"))
|
password_manager = Keyringer.load(data["keyringer"])
|
||||||
if "keepass" in data:
|
if "keepass" in data:
|
||||||
if password_manager:
|
if password_manager:
|
||||||
raise ValueError("Can only set a single password manager")
|
raise ValueError("Can only set a single password manager")
|
||||||
password_manager = Keepass.load(data.pop("keepass"))
|
password_manager = Keepass.load(data["keepass"])
|
||||||
if "password-script" in data:
|
if "password-script" in data:
|
||||||
if password_manager:
|
if password_manager:
|
||||||
raise ValueError("Can only set a single password manager")
|
raise ValueError("Can only set a single password manager")
|
||||||
password_manager = PasswordScript.load(data.pop("password-script"))
|
password_manager = PasswordScript.load(data["password-script"])
|
||||||
|
|
||||||
return Config(realms=realms, password_manager=password_manager)
|
return Config(realms=realms, password_manager=password_manager)
|
||||||
|
|
||||||
@ -220,7 +229,11 @@ class Config:
|
|||||||
"""
|
"""
|
||||||
if realm.account is None:
|
if realm.account is None:
|
||||||
raise RuntimeError("Can't get password without acccount - should use kerberos instead")
|
raise RuntimeError("Can't get password without acccount - should use kerberos instead")
|
||||||
|
|
||||||
|
try:
|
||||||
if self.password_manager:
|
if self.password_manager:
|
||||||
return self.password_manager.get_password(realm.password_name)
|
return self.password_manager.get_password(realm.password_name)
|
||||||
|
|
||||||
return getpass.getpass(f"Enter password for {realm.password_name}: ")
|
return getpass.getpass(f"Enter password for {realm.password_name}: ")
|
||||||
|
except (KeyboardInterrupt, EOFError):
|
||||||
|
raise SystemExit("Password prompt / retrieval aborted")
|
||||||
|
Loading…
Reference in New Issue
Block a user