safe

Hi there!

This is just an empty landing page for now. Safe is not at all ready for public consumption. But you can star it on GitHub if you want to keep up with development.

Thanks for dropping by!

Development

Internals

safe.app

IGNORE_FILE_ARGUMENT

Argument name for the internal value that indicates whether the file argument is required.

Type:str

safe.clip

safe.db

safe.ec

Exit codes for the application.

author:Joe Joyce <joe@decafjoe.com>
copyright:Copyright (c) Joe Joyce and contributors, 2016-2019.
license:BSD
safe.ec.CANCELED = 10

User canceled the operation.

safe.ec.DECRYPTION_FAILED = 31

Decryption of GPG file failed.

safe.ec.ENCRYPTION_FAILED = 32

Encryption of plaintext file failed.

safe.ec.FILE_ARGUMENT_REQUIRED = 42

Command requires file argument, which was not supplied.

safe.ec.FILE_EXISTS = 41

File to be created already exists.

safe.ec.MISSING_FILE = 40

File is required, but missing.

safe.ec.MISSING_GPG = 30

GPG executable not found on system.

safe.ec.NO_SUCH_ACCOUNT = 21

No account with given name.

safe.ec.NO_SUCH_POLICY = 22

No policy with given name.

safe.ec.NO_SUCH_QUESTION = 23

No policy with given identifier.

safe.ec.PASSWORD_NOT_SET = 101

No password has been set for the account.

safe.ec.SRM_FAILED = 100

Failed to securely delete a plaintext file with sensitive data. (File deleted, but not in a secure manner.)

safe.ec.VALIDATION_ERROR = 20

Generic validation error.

safe.form

safe.form.account
safe.form.policy

safe.gpg

Facilities for interacting with GPG encrypted files.

author:Joe Joyce <joe@decafjoe.com>
copyright:Copyright (c) Joe Joyce and contributors, 2016-2019.
license:BSD
safe.gpg.PREFERRED_CIPHER = 'aes256'

Name of the cipher to use if unspecified in GPGFile.save().

Type:str
exception safe.gpg.GPGError(message, stdout, stderr)[source]

Bases: exceptions.Exception

Raised for errors from this module.

__init__(message, stdout, stderr)[source]

Instantiate the error.

Parameters:
  • message (str) – Short message describing the error
  • stdout (str or None) – Standard output related to the error
  • stderr (str or None) – Standard error related to the error
stderr = None

Standard error associated with the error.

Type:str or None
stdout = None

Standard out associated with the error.

Type:str or None
class safe.gpg.GPGFile(path)[source]

Bases: object

Manage decryption and encryption of a GPG file.

_homedir = None

Home directory to use for GnuPG calls (i.e. the --homedir argument). Defaults to ~/.gnupg. This attribute exists to allow tests to tweak the GnuPG environment while running, and is not otherwise used.

Type:str
_keyid = None

Keyid to which the file was encrypted. Populated when decrypt_to() is called.

Type:str or None (if file is symmetrically encrypted)
_password = None

Password with which file was encryted. Populated when decrypt_to() is called.

Type:str or None (if file is asymmetrically encrypted)
_path = None

Path to the encrypted file.

Type:str
_symmetric = None

Boolean indicating whether the file is symmetrically encrypted. If false, the file is asymmetrically encrypted.

Type:bool
KEYID_RE = <_sre.SRE_Pattern object>

Regex matching the keyid output string from gpg --list-packets.

Type:re.compile()
__init__(path)[source]

Instantiate the file wrapper.

Parameters:path (str) – Path to the GPG encrypted file
Raise:GPGError if file cannot be read
decrypt_to(path, password=None)[source]

Decrypt file to path using password.

If decryption is successful, this will cache the password/keyid for use in subsequent calls to save().

Parameters:
  • path (str) – Path to which to decrypt file
  • password (str if file is symmetrically encrypted else None) – Password for file, if encrypted symmetrically
Raise:

GPGError if decryption fails

Return type:

None

save(source, cipher='aes256')[source]

Save plaintext file source back to the original path, encrypted.

decrypt_to() must be called before calling this method. Certain values needed by this method are cached when a file is decrypted. (Namely, password for symmetrically encrypted files and keyid for asymmetrically encrypted files.)

Parameters:
  • source (str) – Path to file to save
  • cipher (str) – Cipher to use for encryption (defaults to PREFERRED_CIPHER)
Raise:

GPGError if encryption fails (original encrypted file is left untouched)

Return type:

None

symmetric

If true, file is encrypted symmetrically (i.e. with a password).

safe.gpg.get_gpg_executable()[source]

Return GPG executable, raising a GPGError if not found.

This will first look for an executable named gpg2, returning it immediately if found. If gpg2 does not exist but gpg does, this function runs gpg --version to check the version. If version 2, the absolute path to the executable is returned.

Failure to find a GPG2 executable results in a GPGError being raised.

Raise:GPGError if GPG executable is not found
Returns:Absolute path to the GPG executable
Return type:str
class safe.gpg.GPGSubprocess(command)[source]

Bases: safe.util.Subprocess

Convenience class for running GPG commands.

__init__(command)[source]

Instantiate the subprocess.

Parameters:command (tuple() of arguments, not including gpg itself at the beginning) – Arguments to pass to GPG

safe.model

orm

ORM wrapper instance.

Type:safe.db.ORM

safe.sgen

generate = AttributeDict()

“Registry” for secret generators. Keys are the “friendly” name for the generator and the values are the generator functions.

Type:dict mapping str -> fn(int, str)

safe.srm

Secure file deletion utility.

author:Joe Joyce <joe@decafjoe.com>
copyright:Copyright (c) Joe Joyce and contributors, 2016-2019.
license:BSD
safe.srm.SHRED_ITERATIONS = 35

Value to pass to --iterations argument of shred.

Type:int:
exception safe.srm.SecureDeleteError(message, stdout, stderr)[source]

Bases: exceptions.Exception

Raised when there is a problem securely deleting a file.

__init__(message, stdout, stderr)[source]

Instantiate the error.

Parameters:
  • message (str) – Short message describing the error
  • stdout (str or None) – Standard output related to the error
  • stderr (str or None) – Standard error related to the error
stderr = None

Standard error associated with the error.

Type:str or None
stdout = None

Standard out associated with the error.

Type:str or None
safe.srm.secure_delete(path)[source]

Securely delete file at path.

Parameters:path (str) – Path of file to delete
Raise:SecureDeleteError if there are no secure deletion utilities found on the machine, or if the secure deletion utility returns a non-zero exit code
Return type:None

safe.util

No project is complete without a utility module.

author:Joe Joyce <joe@decafjoe.com>
copyright:Copyright (c) Joe Joyce and contributors, 2016-2019.
license:BSD
safe.util.expand_path(path)[source]

Return absolute path, with variables and ~ expanded.

Parameters:path (str) – Path, possibly with variables and ~
Returns:Absolute path with special sequences expanded
Return type:str
safe.util.get_executable(name)[source]

Return the full path to executable named name, if it exists.

Parameters:name (str) – Name of the executable to find
Returns:Full path to the executable or None
Return type:str or None
safe.util.prompt_bool(prompt, default=False)[source]

Prompt user for a yes or no answer and return the result as a boolean.

Parameters:
  • prompt (str) – Prompt. ' [y/n] ' will be appended to this value
  • default (bool) – Default value if user enters nothing
Returns:

Boolean indicating user’s choice

Return type:

bool

safe.util.temporary_directory(*args, **kwds)[source]

Context manager that creates a temporary directory for use in the body.

Example:

with temporary_directory() as tmp:
    # do stuff with tmp

The temporary directory permissions are set to 0700 before handing control over to the body.

class safe.util.Subprocess(<subprocess.Popen arguments>)[source]

Bases: subprocess.Popen

Subclass whose communicate() method turns bytes into strings.

communicate(stdin=None)[source]

Override parent to make sure bytes are decoded into strings.

Parameters:stdin (str or None) – Data to send to stdin
Returns:2-tuple, (stdout, stderr)
Return type:2-tuple()

Tests

test.test_clip

test.test_db

test.test_form

test_new_account_form
test_update_account_form
test_policy_forms

test.test_gpg

test_get_gpg_executable
test_wrapper

test.test_model

test.test_sanity

test.test_sgen

test.test_srm

test.test_util

test_expand_path
test_get_executable
test_prompt_bool
test_subprocess
test_temporary_directory

Changelog

0.7.3 – unreleased

0.7.2 – 2019-05-23

  • Adds print command, which is useful for supplying input to other programs
  • Updates dependencies to their latest versions
    • clik (0.92.3 -> 0.92.4)
    • SQLAlchemy (1.2.15 -> 1.3.3)

0.7.1 – 2019-01-02

  • Updates dependencies to their latest versions
    • clik (0.92.2 -> 0.92.3)
    • SQLAlchemy (1.2.8 -> 1.2.15)

0.7.0 – 2018-06-27

  • Drops support for Python 3.3
  • Updates dependencies to their latest versions
    • SQLAlchemy (1.2.7 -> 1.2.8)
    • wtforms (2.1 -> 2.2.1)

0.6.3 – 2018-04-26

  • Updates dependencies to their latest versions
    • SQLAlchemy (1.2.1 to 1.2.7)

0.6.2 – 2018-01-20

  • Updates dependencies to their latest versions
    • clik (0.91.1 to 0.92.2)
    • SQLAlchemy (1.1.14 to 1.2.1)

0.6.1 – 2018-01-02

  • Bug fix for xclip on Linux.

0.6.0 – 2017-12-06

Note: 0.5.0 files cannot be read by 0.6.x, and vice-versa.

  • Complete rewrite.
  • Actual tests, focused on the critical bits.
  • Linter is happy.
  • Internal documentation.
  • UI is arguably better.

0.5.0 – 2017-11-02

  • Initial release.