From c9c1403685fd1b7af8bbd94a88090f2ce35185e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= Date: Thu, 20 Sep 2018 13:32:34 +0200 Subject: [PATCH] read a passphrase from a file descriptor Read a passpharase from a file descriptor specified in the BORG_PASSPHRASE_FD environment variable. --- borg/key.py | 15 ++++++++++++++- docs/usage.rst | 7 +++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/borg/key.py b/borg/key.py index d699f6f29..650b0fcc5 100644 --- a/borg/key.py +++ b/borg/key.py @@ -26,7 +26,7 @@ PREFIX = b'\0' * 8 class PassphraseWrong(Error): - """passphrase supplied in BORG_PASSPHRASE or by BORG_PASSCOMMAND is incorrect.""" + """passphrase supplied in BORG_PASSPHRASE, by BORG_PASSCOMMAND or via BORG_PASSPHRASE_FD is incorrect.""" class PasscommandFailure(Error): @@ -323,6 +323,9 @@ class Passphrase(str): passphrase = cls.env_passcommand() if passphrase is not None: return passphrase + passphrase = cls.fd_passphrase() + if passphrase is not None: + return passphrase @classmethod def env_passcommand(cls, default=None): @@ -336,6 +339,16 @@ class Passphrase(str): raise PasscommandFailure(e) return cls(passphrase.rstrip('\n')) + @classmethod + def fd_passphrase(cls): + try: + fd = int(os.environ.get('BORG_PASSPHRASE_FD')) + except (ValueError, TypeError): + return None + with os.fdopen(fd, mode='r') as f: + passphrase = f.read() + return cls(passphrase.rstrip('\n')) + @classmethod def getpass(cls, prompt): return cls(getpass.getpass(prompt)) diff --git a/docs/usage.rst b/docs/usage.rst index 64fc3f961..86ec281e4 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -172,6 +172,13 @@ General: It is used when a passphrase is needed to access an encrypted repo as well as when a new passphrase should be initially set when initializing an encrypted repo. If BORG_PASSPHRASE is also set, it takes precedence. + BORG_PASSPHRASE_FD + When set, specifies a file descriptor to read a passphrase + from. Programs starting borg may choose to open an anonymous pipe + and use it to pass a passphrase. This is safer than passing via + BORG_PASSPHRASE, because on some systems (e.g. Linux) environment + can be examined by other processes. + If BORG_PASSPHRASE or BORG_PASSCOMMAND are also set, they take precedence. BORG_DISPLAY_PASSPHRASE When set, use the value to answer the "display the passphrase for verification" question when defining a new passphrase for encrypted repositories. BORG_LOGGING_CONF