Merge pull request #4083 from steelman/borg-passphrase-fd-1.1

read a passphrase from a file descriptor
This commit is contained in:
TW 2018-09-22 19:09:52 +02:00 committed by GitHub
commit 3162abb356
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 1 deletions

View File

@ -174,6 +174,13 @@ General:
passphrase should be initially set when initializing an encrypted repo. passphrase should be initially set when initializing an encrypted repo.
If BORG_PASSPHRASE is also set, it takes precedence. If BORG_PASSPHRASE is also set, it takes precedence.
See also BORG_NEW_PASSPHRASE. See also BORG_NEW_PASSPHRASE.
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_NEW_PASSPHRASE BORG_NEW_PASSPHRASE
When set, use the value to answer the passphrase question when a **new** passphrase is asked for. When set, use the value to answer the passphrase question when a **new** passphrase is asked for.
This variable is checked first. If it is not set, BORG_PASSPHRASE and BORG_PASSCOMMAND will also This variable is checked first. If it is not set, BORG_PASSPHRASE and BORG_PASSCOMMAND will also

View File

@ -37,7 +37,7 @@ class NoPassphraseFailure(Error):
class PassphraseWrong(Error): 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): class PasscommandFailure(Error):
@ -436,6 +436,9 @@ class Passphrase(str):
passphrase = cls.env_passcommand() passphrase = cls.env_passcommand()
if passphrase is not None: if passphrase is not None:
return passphrase return passphrase
passphrase = cls.fd_passphrase()
if passphrase is not None:
return passphrase
@classmethod @classmethod
def env_passcommand(cls, default=None): def env_passcommand(cls, default=None):
@ -449,6 +452,16 @@ class Passphrase(str):
raise PasscommandFailure(e) raise PasscommandFailure(e)
return cls(passphrase.rstrip('\n')) 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 @classmethod
def env_new_passphrase(cls, default=None): def env_new_passphrase(cls, default=None):
return cls._env_passphrase('BORG_NEW_PASSPHRASE', default) return cls._env_passphrase('BORG_NEW_PASSPHRASE', default)