Coverage for /home/ken/src/shared/avendesora/avendesora/preferences.py : 0%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# Avendesora Password Generator Preferences # # Copyright (C) 2016 Kenneth S. Kundert
# License {{{1 # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/.
# Imports {{{1 from textwrap import dedent import re from appdirs import user_config_dir
# Non-Config Settings {{{1 # These value can be accessed with get_settings, # but should not be found in the config file NONCONFIG_SETTINGS = { 'config_file': 'config', 'settings_dir': user_config_dir('avendesora'), 'default_accounts_file': 'accounts.gpg', 'default_stealth_accounts_file': 'stealth_accounts', 'charsets_hash': 'e4ae3714d9dbdffc0cf3b51a0462b5ec', 'dict_hash': '11fe5bc734f4a956c37d7cb3da16ab3f', 'secrets_hash': '45fabadad98e2ce50c076a371fd90588', 'discard_logfile': False, }
# Config Settings {{{1 # These are the default values for settings that may be found in the config file CONFIG_DEFAULTS = { 'default_command': 'value', 'accounts_files': [ NONCONFIG_SETTINGS['default_accounts_file'], NONCONFIG_SETTINGS['default_stealth_accounts_file'], ], 'account_list_file': '.accounts_files', 'archive_file': 'archive.gpg', 'previous_archive_file': 'archive.prev.gpg', 'label_color': 'blue', 'color_scheme': 'dark', 'browsers': { 'f': 'firefox -new-tab {url}', 'c': 'google-chrome {url}', 't': 'torbrowser {url}', 'x': 'xdg-open {url}', # system default browser }, 'default_browser': 'x', 'default_field': 'passcode', 'default_vector_field': 'questions', 'display_time': 60, 'dictionary_file': 'words', 'encoding': 'utf8', 'edit_account': ( 'vim', '+silent /^class {account}(Account):/', '+silent normal zozt', # open the fold, position near top of screen '{filepath}' ), 'edit_template': ( 'vim', '+silent /_[A-Z0-9_]\+_/', # matches user modifiable template fields # fields take the form '_AAA_' '+silent normal zozt', # open the fold, position near top of screen '{filepath}' ), 'hashes_file': '.hashes', 'indent': ' ', 'log_file': 'log.gpg', 'required_protocols': ['https'], 'user_key_file': '.key.gpg', 'verbose': False, 'default_account_template': 'bank', 'account_templates': { 'website': """ class _NAME_(Account): # %s1 aliases = '_ALIAS1_ _ALIAS2_' username = '_USERNAME_' email = '_EMAIL_' passcode = PasswordRecipe('12 2u 2d 2s') default = 'username: {email}, password: {passcode}' discovery = RecognizeURL( 'https://_URL_', script='{email}{tab}{passcode}{return}' ) """ % (3*'{'), 'shell': """ class _NAME_(Account): # %s1 aliases = '_ALIAS1_ _ALIAS2_' passcode = Passphrase() discovery = RecognizeTitle( '_TITLE1_', '_TITLE2_', script='{passcode}{return}' ) """ % (3*'{'), 'bank': """ class _NAME_(Account): # %s1 aliases = '_ALIAS1_ _ALIAS2_' username = '_NAME_' email = '_EMAIL_' accounts = { 'checking': <<_ACCOUNT_NUMBER_>>, 'savings': <<_ACCOUNT_NUMBER_>>, 'creditcard': <<_ACCOUNT_NUMBER_>>, } customer_service = '_PHONE_NUMBER_' passcode = PasswordRecipe('12 2u 2d 2s') verbal = Passphrase(length=2) pin = PIN() default = 'username: {username}, password: {passcode}' questions = [ Question("_QUESTION1_?"), Question("_QUESTION2_?"), Question("_QUESTION3_?"), ] discovery = RecognizeURL( 'https://_URL_', script='{email}{tab}{passcode}{return}' ) """ % (3*'{'), },
# use absolute paths for executables so they cannot be maliciously replaced # by changing the path. 'gpg_executable': '/usr/bin/gpg2', 'gpg_home': '~/.gnupg', 'gpg_armor': 'extension', 'gpg_ids': None, 'xdotool_executable': '/usr/bin/xdotool', 'xsel_executable': '/usr/bin/xsel -p', 'use_pager': True, }
# the following could be config settings, but they do not seem worth promoting INITIAL_AUTOTYPE_DELAY = 0.0
# Initial config file {{{1 CONFIG_FILE_INITIAL_CONTENTS = dedent('''\ # Avendesora Configuration # vim: filetype=python sw=4 sts=4 et ai ff=unix nofen fileencoding={encoding} : # # The desired location of the log file (relative to config directory). # Adding a suffix of .gpg or .asc causes the file to be encrypted # (otherwise it can leak account names). Use None to disable logging. log_file = {log_file}
# The desired location of the archive file (relative to config director). # End the path in .gpg. Use None to disable archiving. archive_file = {archive_file} previous_archive_file = {previous_archive_file}
# Various settings default_command = {default_command} default_field = {default_field} default_vector_field = {default_vector_field} display_time = {display_time} encoding = {encoding} edit_account = {edit_account} edit_template = {edit_template} browsers = {browsers} default_browser = {default_browser} required_protocols = {required_protocols} label_color = {label_color} # choose from black, red, green, yellow, blue, magenta, cyan, white color_scheme = {color_scheme} # choose from dark, light verbose = {verbose} # normally set to false, if set true it sets --verbose option, which can # help when debugging account discovery use_pager = {use_pager}
# Prototype accounts default_account_template = {default_account_template} account_templates = {account_templates}
# Information used by GPG when encrypting and decrypting files. gpg_ids = {gpg_ids} gpg_armor = {gpg_armor} # choose between 'always', 'never' and 'by-ext' (.asc: armor, .gpg: no) gpg_home = {gpg_home}
# Utilities # use of full absolute paths for executables is recommended gpg_executable = {gpg_executable} xdotool_executable = {xdotool_executable} xsel_executable = {xsel_executable} ''')
# Initial hash file {{{1 HASH_FILE_INITIAL_CONTENTS = dedent('''\ # Avendesora Hashes # vim: filetype=python sw=4 sts=4 et ai ff=unix fileencoding={encoding} : # # Changing the contents of the dictionary, secrets, or charsets will change # the secrets you generate, thus you do not want to change these files once # you have started using the program. These are hashes for the contents of # these files at the time that this file was created. The program will # complain if the current contents of these files generate a different # hash. Only update these hashes if you know what you are doing. # # Here is the procedure you should use. # 1. Using the original version of Advendesora, run 'avendesora archive' # This version should not emit a hash warning. # 2. Update Avendesora # This version may emit hash warnings. # 3. Run 'avendesora changed'. If no changes are noted, it is okay to update # the appropriate hashes. # 4. If there are changes, either do not upgrade or manually override the # changed secrets to return them to their original values.
charsets_hash = {charsets_hash} # DO NOT CHANGE THIS LINE dict_hash = {dict_hash} # DO NOT CHANGE THIS LINE secrets_hash = {secrets_hash} # DO NOT CHANGE THIS LINE ''')
# Initial accounts file {{{1 ACCOUNTS_FILE_INITIAL_CONTENTS = dedent('''\ # Avendesora Accounts # vim: filetype=python sw=4 sts=4 et ai ff=unix fileencoding={encoding} : # # Add information about each of your accounts to the accounts dictionary. # # You can use the dedent function to strip leading whitespace from # multi-line remarks. You can use the character sets and exclude function # to create alphabets for you character-base passwords. # # Example: # To create an alphabet with all characters except tabs use either: # 'alphabet': exclude(PRINTABLE, '\\t') # or: # 'alphabet': ALPHANUMERIC + PUNCTUATION + ' ' #
from avendesora import ( # Basics Account, StealthAccount, Hidden, GPG, Scrypt,
# Character sets exclude, LOWERCASE, UPPERCASE, LETTERS, DIGITS, ALPHANUMERIC, HEXDIGITS, PUNCTUATION, SYMBOLS, WHITESPACE, PRINTABLE, DISTINGUISHABLE,
# Secrets Password, Passphrase, PIN, Question, MixedPassword, PasswordRecipe, BirthDate,
# Account Discovery RecognizeAll, RecognizeAny, RecognizeTitle, RecognizeURL, RecognizeCWD, RecognizeHost, RecognizeUser, RecognizeEnvVar, ) try: # You need to install scrypt using 'pip install scrypt' to use Scrypt import Scrypt except ImportError: pass
master_password = Hidden({master_password}, secure=True) gpg_ids = {gpg_ids}
# Accounts
''')
# Initial stealth_accounts file {{{1 STEALTH_ACCOUNTS_FILE_INITIAL_CONTENTS = dedent('''\ # Avendesora Stealth Accounts # vim: filetype=python sw=4 sts=4 et ai ff=unix fileencoding={encoding} : # # Stealth accounts are accounts where the class name is not taken to be the # account name, instead the user is interactively asked for the account # name. In this way there is no record that the account actually exists.
# Imports {section} from avendesora import ( # Account StealthAccount,
# Character sets exclude, LOWERCASE, UPPERCASE, LETTERS, DIGITS, ALPHANUMERIC, HEXDIGITS, PUNCTUATION, WHITESPACE, PRINTABLE, DISTINGUISHABLE,
# Secrets Password, PasswordRecipe, Passphrase, PIN, Hidden )
# Accounts # Alphanumeric passwords {section} class Anum4(StealthAccount): passcode = Password(length=4, alphabet=DISTINGUISHABLE)
class Anum6(StealthAccount): passcode = Password(length=6, alphabet=DISTINGUISHABLE)
class Anum8(StealthAccount): passcode = Password(length=8, alphabet=DISTINGUISHABLE)
class Anum10(StealthAccount): passcode = Password(length=10, alphabet=DISTINGUISHABLE)
class Anum12(StealthAccount): aliases = 'anum' passcode = Password(length=12, alphabet=DISTINGUISHABLE)
class Anum14(StealthAccount): passcode = Password(length=14, alphabet=DISTINGUISHABLE)
class Anum16(StealthAccount): passcode = Password(length=16, alphabet=DISTINGUISHABLE)
class Anum18(StealthAccount): passcode = Password(length=18, alphabet=DISTINGUISHABLE)
class Anum20(StealthAccount): passcode = Password(length=20, alphabet=DISTINGUISHABLE)
# High entropy passwords {section} class Char4(StealthAccount): passcode = Password(length=4, alphabet=ALPHANUMERIC+PUNCTUATION)
class Char6(StealthAccount): passcode = Password(length=6, alphabet=ALPHANUMERIC+PUNCTUATION)
class Char8(StealthAccount): passcode = Password(length=8, alphabet=ALPHANUMERIC+PUNCTUATION)
class Char10(StealthAccount): passcode = Password(length=10, alphabet=ALPHANUMERIC+PUNCTUATION)
class Char12(StealthAccount): aliases = 'char' passcode = Password(length=12, alphabet=ALPHANUMERIC+PUNCTUATION)
class Char14(StealthAccount): passcode = Password(length=14, alphabet=ALPHANUMERIC+PUNCTUATION)
class Char16(StealthAccount): passcode = Password(length=16, alphabet=ALPHANUMERIC+PUNCTUATION)
class Char18(StealthAccount): passcode = Password(length=18, alphabet=ALPHANUMERIC+PUNCTUATION)
class Char20(StealthAccount): passcode = Password(length=20, alphabet=ALPHANUMERIC+PUNCTUATION)
# Extreme passwords {section} class Extreme(StealthAccount): passcode = Passphrase(length=64, alphabet=PRINTABLE)
# Hex passwords {section} class Hex4(StealthAccount): passcode = Password(length=4, alphabet=HEXDIGITS, prefix='0x')
class Hex8(StealthAccount): passcode = Password(length=8, alphabet=HEXDIGITS, prefix='0x')
class Hex16(StealthAccount): passcode = Password(length=16, alphabet=HEXDIGITS, prefix='0x')
class Hex32(StealthAccount): passcode = Password(length=32, alphabet=HEXDIGITS, prefix='0x')
class Hex64(StealthAccount): aliases = 'hex' passcode = Password(length=64, alphabet=HEXDIGITS, prefix='0x')
# PINs {section} class Pin4(StealthAccount): aliases = 'pin' passcode = PIN(length=4)
class Pin6(StealthAccount): passcode = PIN(length=6)
class Pin8(StealthAccount): aliases = 'num' passcode = PIN(length=8)
class Pin10(StealthAccount): passcode = PIN(length=10)
class Pin12(StealthAccount): passcode = PIN(length=12)
# Pass phrases {section} class Word(StealthAccount): passcode = Passphrase(length=1)
class Word2(StealthAccount): aliases = 'pair' passcode = Passphrase(length=2)
class Word3(StealthAccount): passcode = Passphrase(length=3)
class Word4(StealthAccount): aliases = 'word xkcd' passcode = Passphrase(length=4)
class Word5(StealthAccount): passcode = Passphrase(length=5)
class Word6(StealthAccount): passcode = Passphrase(length=6)
class Word7(StealthAccount): passcode = Passphrase(length=7)
class Word8(StealthAccount): passcode = Passphrase(length=8)
# Web passwords {section} class Web6(StealthAccount): passcode = PasswordRecipe('6 u d s')
class Web8(StealthAccount): passcode = PasswordRecipe('8 u d s')
class Web10(StealthAccount): passcode = PasswordRecipe('10 2u 2d 2s')
class Web12(StealthAccount): aliases = 'web' passcode = PasswordRecipe('12 2u 2d 2s')
class Web14(StealthAccount): passcode = PasswordRecipe('14 2u 2d 2s')
class Web16(StealthAccount): passcode = PasswordRecipe('16 3u 3d 3s')
class Web18(StealthAccount): passcode = PasswordRecipe('18 3u 3d 3s')
class Web20(StealthAccount): passcode = PasswordRecipe('20 3u 3d 3s') ''')
# Initial user key file {{{1 USER_KEY_FILE_INITIAL_CONTENTS = dedent('''\ # Avendesora Personal Key # vim: filetype=python sw=4 sts=4 et ai ff=unix fileencoding={encoding} : # # This is your personal encryption key. # DO NOT CHANGE THIS KEY. DO NOT SHARE THIS KEY. user_key = ({user_key}) ''')
# Archive file header {{{1 ARCHIVE_FILE_CONTENTS = dedent('''\ # Avendesora Archive File # vim: filetype=python sw=4 sts=4 et ai ff=unix fileencoding={encoding} : # # This file allows you to recover your secrets if Avendesora is not # available. Except for the master passwords it contains all of the # information for all of the accounts. The secrets have been generated and # hidden using base64 encoding. To decode a hidden argument of the form: # Hidden('<hidden_arg>'), you can use: # # > avendesora reveal # hidden text: <hidden_text> # # or # # > base64 -d - < <filename> # # where <filename> contains <hidden_arg>. #
from avendesora import ( Hidden, Question, RecognizeAll, RecognizeTitle, RecognizeURL, RecognizeCWD, RecognizeHost, RecognizeUser, RecognizeEnvVar )
CREATED = '{date}' ACCOUNTS = {{ {accounts} }} ''')
# Account list file {{{1 ACCOUNT_LIST_FILE_CONTENTS = dedent('''\ # The list of files that contain accounts. The order of the files is # immaterial, except that first file given is the default file, meaning that # the add account will add a new account to the first files specified unless # a different files is specified explicitly. accounts_files = {accounts_files} ''')
# Fields {{{1 # Fields reserved for use by Avendesora TOOL_FIELDS = [ 'NAME', 'aliases', 'default', 'master', 'discovery', 'browser', 'default_url' ] |