diff options
author | Ryan Lue <hello@ryanlue.com> | 2022-06-30 23:04:35 -0700 |
---|---|---|
committer | Lukas Fleischer <lfleischer@calcurse.org> | 2023-04-11 15:22:03 -0400 |
commit | e772c4b6d52627c463e70b4284e3794aa0bd0634 (patch) | |
tree | ea1962c737cac208ab8c8b034bde22b8cc3e32d1 | |
parent | 4cd300f2c408907b4a576b55fc15479afbd5d81f (diff) | |
download | calcurse-e772c4b6d52627c463e70b4284e3794aa0bd0634.tar.gz calcurse-e772c4b6d52627c463e70b4284e3794aa0bd0634.zip |
calcurse-caldav: Support PasswordCommand option
This commit adds a new `Auth/PasswordCommand` option
to support security best practices re: handling secrets
in CLI program configuration.
Prior to this commit, the two available options
for specifying a password were:
1. via the `Auth/Password` config parameter, or
2. via a `$CALCURSE_CALDAV_PASSWORD` environment variable.
The former is unsafe for obvious reasons;
the latter is unsafe because as long as the script is running,
its environment can be accessed via
$ cat /proc/<pid>/environ
and is thus visible to anyone with access to the system.
This commit preserves preexisting behavior (for backward compatibility)
but removes all mention of option 2 from the README.
Since the README example for option 2 used a password command anyway,
there is little reason to continue its use,
and this commit recommends it be deprecated.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
-rw-r--r-- | contrib/caldav/README.md | 13 | ||||
-rwxr-xr-x | contrib/caldav/calcurse-caldav.py | 17 | ||||
-rw-r--r-- | contrib/caldav/config.sample | 8 |
3 files changed, 24 insertions, 14 deletions
diff --git a/contrib/caldav/README.md b/contrib/caldav/README.md index a842081..b464dc9 100644 --- a/contrib/caldav/README.md +++ b/contrib/caldav/README.md @@ -34,13 +34,12 @@ argument. You can choose between the following initialization modes: For subsequent calcurse-caldav invocations, you don't need to specify any additional parameters. -You can specify a username and password for basic authentication in the -config file. Alternatively, the password can be passed securely from another -program (such as *pass*) via the `CALCURSE_CALDAV_PASSWORD` environment variable like -so: -``` -CALCURSE_CALDAV_PASSWORD=$(pass show calcurse) calcurse-caldav -``` +Specify your HTTP Basic authentication credentials under the config file's +`Auth` section. The most secure approach is to save your password in a CLI +encrypted password store (_e.g.,_ [pass](https://www.passwordstore.org/)), and +then set `PasswordCommand` to the shell command used to retrieve it. +If security is not a priority, you may store your password in plain text +instead. Hooks ----- diff --git a/contrib/caldav/calcurse-caldav.py b/contrib/caldav/calcurse-caldav.py index 99e2e6a..f9488e6 100755 --- a/contrib/caldav/calcurse-caldav.py +++ b/contrib/caldav/calcurse-caldav.py @@ -6,6 +6,7 @@ import configparser import os import pathlib import re +import shlex import subprocess import sys import textwrap @@ -30,6 +31,7 @@ class Config: self._map = { 'Auth': { 'Password': None, + 'PasswordCommand': None, 'Username': None, }, 'CustomHeaders': {}, @@ -657,9 +659,6 @@ verbose = args.verbose debug = args.debug debug_raw = args.debug_raw -# Read environment variables -password = os.getenv('CALCURSE_CALDAV_PASSWORD') - # Read configuration. config = Config(configfn) @@ -674,7 +673,17 @@ path = config.get('General', 'Path') sync_filter = config.get('General', 'SyncFilter') verbose = verbose or config.get('General', 'Verbose') -password = password or config.get('Auth', 'Password') +if os.getenv('CALCURSE_CALDAV_PASSWORD'): + # This approach is deprecated, but preserved for backwards compatibility + password = os.getenv('CALCURSE_CALDAV_PASSWORD') +elif config.get('Auth', 'Password'): + password = config.get('Auth', 'Password') +elif config.get('Auth', 'PasswordCommand'): + tokenized_cmd = shlex.split(config.get('Auth', 'PasswordCommand')) + password = subprocess.run(tokenized_cmd, capture_output=True).stdout.decode('UTF-8') +else: + password = None + username = config.get('Auth', 'Username') client_id = config.get('OAuth2', 'ClientID') diff --git a/contrib/caldav/config.sample b/contrib/caldav/config.sample index e2c6c2d..0ba8fa8 100644 --- a/contrib/caldav/config.sample +++ b/contrib/caldav/config.sample @@ -48,11 +48,13 @@ DryRun = Yes # Enable this if you want detailed logs written to stdout. Verbose = Yes -# Credentials for HTTP Basic Authentication. Leave this commented out if you do -# not want to use authentication. +# Credentials for HTTP Basic Authentication (if required). +# Set `Password` to your password in plaintext (unsafe), +# or `PasswordCommand` to a shell command that retrieves it (recommended). #[Auth] #Username = user -#Password = pass +#Password = password +#PasswordCommand = pass baikal # Optionally specify additional HTTP headers here. #[CustomHeaders] |