From b41afde2c99be230c665c790e94ba18a45ab3ee9 Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Thu, 4 Jan 2024 16:33:38 +0100 Subject: [PATCH 1/3] Allow starting with an empty config if --configfile is either empty or points to /dev/null --- osc/conf.py | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/osc/conf.py b/osc/conf.py index 97503aea..0a1c44b8 100644 --- a/osc/conf.py +++ b/osc/conf.py @@ -1824,29 +1824,33 @@ def get_config(override_conffile=None, else: conffile = identify_conf() - conffile = os.path.expanduser(conffile) - if not os.path.exists(conffile): - raise oscerr.NoConfigfile(conffile, account_not_configured_text % conffile) + if conffile in ["", "/dev/null"]: + cp = OscConfigParser.OscConfigParser() + cp.add_section("general") + else: + conffile = os.path.expanduser(conffile) + if not os.path.exists(conffile): + raise oscerr.NoConfigfile(conffile, account_not_configured_text % conffile) - # make sure oscrc is not world readable, it may contain a password - conffile_stat = os.stat(conffile) - if conffile_stat.st_mode != 0o600: - try: - os.chmod(conffile, 0o600) - except OSError as e: - if e.errno in (errno.EROFS, errno.EPERM): - print(f"Warning: Configuration file '{conffile}' may have insecure file permissions.") - else: - raise e + # make sure oscrc is not world readable, it may contain a password + conffile_stat = os.stat(conffile) + if conffile_stat.st_mode != 0o600: + try: + os.chmod(conffile, 0o600) + except OSError as e: + if e.errno in (errno.EROFS, errno.EPERM): + print(f"Warning: Configuration file '{conffile}' may have insecure file permissions.") + else: + raise e - cp = get_configParser(conffile) + cp = get_configParser(conffile) - if not cp.has_section('general'): - # FIXME: it might be sufficient to just assume defaults? - msg = config_incomplete_text % conffile - defaults = Options().dict() - msg += new_conf_template % defaults - raise oscerr.ConfigError(msg, conffile) + if not cp.has_section("general"): + # FIXME: it might be sufficient to just assume defaults? + msg = config_incomplete_text % conffile + defaults = Options().dict() + msg += new_conf_template % defaults + raise oscerr.ConfigError(msg, conffile) global config From 7d27b6d1402cba648a1821024e1740de188563cf Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Thu, 4 Jan 2024 16:39:27 +0100 Subject: [PATCH 2/3] Fix credentials managers to consistently return Password --- osc/credentials.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osc/credentials.py b/osc/credentials.py index 0674a8d9..70598827 100644 --- a/osc/credentials.py +++ b/osc/credentials.py @@ -74,7 +74,10 @@ class AbstractCredentialsManager: class PlaintextConfigFileCredentialsManager(AbstractCredentialsManager): def get_password(self, url, user, defer=True, apiurl=None): - return self._cp.get(url, 'pass', raw=True) + password = self._cp.get(url, "pass", fallback=None, raw=True) + if password is None: + return None + return conf.Password(password) def set_password(self, url, user, password): self._cp.set(url, 'pass', password) @@ -108,7 +111,8 @@ class ObfuscatedConfigFileCredentialsManager(PlaintextConfigFileCredentialsManag passwd = self._cp.get(url, 'passx', raw=True) else: passwd = super().get_password(url, user, apiurl=apiurl) - return self.decode_password(passwd) + password = self.decode_password(passwd) + return conf.Password(password) def set_password(self, url, user, password): compressed_pw = bz2.compress(password.encode('ascii')) From 82216c72b423bfb4ad7ef79c439f8240ba46686d Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Thu, 4 Jan 2024 16:41:24 +0100 Subject: [PATCH 3/3] Implement reading credentials from environmental variables Options for apiurls can be set via OSC_HOST__