========= abraxas ========= ------------------------------ collaborative password utility ------------------------------ :Author: Kale and Ken Kundert :Date: 2016-08-14 :Version: 1.8 :Manual section: 5 .. :Copyright: Kale and Ken Kundert .. :Manual group: Utilities DESCRIPTION =========== Abraxas requires two files to operate. The master password file and the accounts file. You may optionally add a third file that gives the dictionary used when creating pass phrases. Master Password File ++++++++++++++++++++ The master password file is named '~/.config/abraxas/master.gpg'. It is encrypted with the GPG ID that you specified when you ran 'abraxas --init'. It is a Python file that contains a collection of variables. To be able to edit it conveniently it is recommended that you add the gnupg plugin to vim (download it from ``http://www.vim.org/scripts/script.php?script_id=3645`` and copy it into ~/.vim/plugin). dict_hash ~~~~~~~~~ This is a hash of the file that contains the words used when generating pass phrases. You should not change this value. It is used to warn you if somehow your words file is changed or corrupted, which would corrupt your pass phrases. secrets_hash ~~~~~~~~~~~~ This is a hash of the file that contains the code used when generating the hash and converting it to a password or pass phrase. It is used to warn you that the secrets code has changed, presumably when the program itself was updated. If this occurs you should verify that the passwords it generates are the same. If not, you should not use the updated version of the program. If they are the same, you should update the *secrets_hash*. Do this by moving the existing *master.gpg* file out of the way, generating a new one with *abraxas --init*, copying the new *secrets_hash* to the original file, and then moving it back to its original location of *~/.config/abraxas/master.gpg*. charsets_hash ~~~~~~~~~~~~~ This is a hash of the file that contains the alphabets and the exclude function that you can use when creating alphabets for your character-based passwords. It is used to warn you that the character sets code has changed, presumably when the program itself was updated. If this occurs you should verify that the passwords it generates are the same. If not, you should not use the updated version of the program. If they are the same, you should update the *charsets_hash*. Do this by moving the existing *master.gpg* file out of the way, generating a new one with *abraxas --init*, copying the new *charsets_hash* to the original file, and then moving it back to its original location of *~/.config/abraxas/master.gpg*. accounts ~~~~~~~~ This is the name of the accounts file. The name may be given with or without an encryption suffix (``.gpg`` or ``.asc``). If given with an encryption suffix, the file must be encrypted. If given without a suffix, the file may still be encrypted (in which case the file itself should have a encryption suffix) but need not be. passwords ~~~~~~~~~ This is a dictionary that gives your master passwords. Each entry is a pair of the password ID and then password itself. For example:: passwords = { 'default': """l8i6-v?>GCTQK"oz3yzZg5Ne=&,.!*Q$2ddEaZbESwnl<4*BRi1D887XQ!W4/&}e""", 'derrick and peter': "hush puppie", 'derrick and debbie': "lounge lizard", } As shown, your account comes preloaded with a very long and very random default password. Generally you will never have to type these passwords again, so there is little reason not to make them long and very random. There are no limits on the length of the passwords or the characters they may contain, so you can go wild. For example, using your default master password you could use Abraxas to generate new master passwords:: $ abraxas -T =extreme 'derrick and peter' PASSWORD: [Y$*{QCf"?yvDc'{4v?4r.iA0b3brHY z40;lZIs~bjjGCTQK"oz3yzZg5Ne=&,.!*Q$2ddEaZbESwnl<4*BRi1D887XQ!W4/&}e""", 'derrick and peter': """[Y$*{QCf"?yvDc'{4v?4r.iA0b3brHY z40;lZIs~bjjGCTQK"oz3yzZg5Ne=&,.!*Q$2ddEaZbESwnl<4*BRi1D887XQ!W4/&}e""", 'derrick and peter': """[Y$*{QCf"?yvDc'{4v?4r.iA0b3brHY z40;lZIs~bjj)' to the end of the master password name, where is replaced with the date that the password was deprecated. When doing so, be sure to also change the name used in the *accounts* file so that the existing passwords do not change. That way you do not have to update all of your passwords at once. Rather, you update the high value ones immediately and migrate the others as you get time. Using this approach your master password file might look like this:: passwords = { 'default': """l8i6-v?>GCTQK"oz3yzZg5Ne=&,.!*Q$2ddEaZbESwnl<4*BRi1D887XQ!W4/&}e""", 'derrick and peter (deprecated 120301)': """[Y$*{QCf"?yvDc'{4v?4r.iA0b3brHY z40;lZIs~bjj?@[\]^_`{|}~""" WHITESPACE = " \t" PRINTABLE = ALPHANUMERIC + PUNCTUATION + WHITESPACE DISTINGUISHABLE = exclude(ALPHANUMERIC, 'Il1O0\\t') Finally, the *exclude* function is used to remove characters from a character set. The following attributes are read and used by the password program if they exist in an accounts file. log_file ~~~~~~~~ Specifies the location of the log file. If not given, it defaults to '~/.config/abraxas/log'. An absolute path should be used to specify the file. If a '.gpg' or '.asc' suffix is given on this file, it will be encrypted using your public key. Without encryption, this file leaks account names. archive_file ~~~~~~~~~~~~ Specifies the location of the archive file. If not given, it defaults to '~/.config/abraxas/archive.gpg'. An absolute path should be used to specify the file. The file should end with a .gpg extension. gpg_id ~~~~~~ The GPG ID of the user (it is used to encrypt the archive file). It would either by the email address associated with the ID, or the eight digit hexadecimal GPG key ID if you have multiple keys associated with the same email address. accounts ~~~~~~~~ A dictionary where each entry represents either an account or a template. By convention, templates have an ID that starts with '='. Templates are used to limit the information you need to give in an account. You just create or use a template that has the desired base information. Then when creating an account, you can refer to the template and only specify the fields that need to be unique for that account. The template for an account can be another account or a template. In this way templates are just accounts that are not associated with any particular account in the real world. For example:: accounts = { "=words": { # typically used for Linux pass phrases 'type': 'words', 'num-words': 4, 'autotype': "{password}{return}", }, "gmail": { 'template': "=words", 'username': "derrickAsh", 'url': "https://accounts.google.com", 'master': 'derrick', 'window': [ 'Google Accounts*', 'Gmail*', ], 'autotype': "{username}{tab}{password}{return}", }, ... } In this example '=words' is specified as the template for 'gmail' (it is a purely optional convention to add a leading = to account names that are intended to be used only as templates). Thus any field specified in '=words' that is not specified in 'gmail' is inherited by 'gmail'. Any field specified in 'gmail' overrides the field with the same name from '=words' when using 'gmail'. This process of inheritance can chain through any number of templates or accounts. For example, you can create another account, say 'gmail-work' that uses 'gmail' as a template but overrides the 'username'. The ID associated with an account is used in the process of generating the secrets for the account. For this reason you should choose IDs that are unambiguous and unlikely to change. The resulting IDs may be long and hard to type. You can use the *aliases* entry to specify shorter names that can be used as an alternative to the primary account ID. For example, when creating your gmail account, it is a good idea to add your username to the account ID, because in the future you might create additional gmail accounts. So, *gmail-username* would be a good account name. Then you should add a short name like *gmail* as an alias to the one you use the most. If at some point you migrate to a new gmail account for your day-to-day use, you can move the *gmail* alias to this new account without changing the generated password. additional_accounts ~~~~~~~~~~~~~~~~~~~ A list of additional account files. This is helpful in cases where you want to have a separate file for accounts shared with someone else. In this way you can share the details of the shared accounts file without exposing your personal accounts. The additional account files may also be encrypted. If they are truly shared, then you will want to encrypt them using multiple recipients. An additional accounts file is also a Python file, and the only thing that is used by Abraxas in this file is a dictionary named *accounts*. It is generally a good idea to start from a copy of the original accounts file and simply delete unnecessary definitions (*log_file*, *archive_file* and *gpg_id*) and the non-shared accounts. In this way, you still can use the character sets that are defined at the top of the file. You can specify a single account file using a string, and multiple account files as a list of strings. Here is how to specify a single additional account file:: additional_accounts = "business/accounts" Here is how you specify multiple additional account files:: additional_accounts = ["business/accounts", "charity/accounts"] Accounts Fields +++++++++++++++ Each dictionary in *accounts* may contain a number of fields that are described next. When first created the accounts dictionary comes with some useful templates and an example account entry that is commented out. Feel free to modify the templates and delete the example account. template ~~~~~~~~ A string containing the ID of the template for this account (explained above). master ~~~~~~ A string containing the ID of the master password for this account. It is recommended that each account explicitly declare its master password (perhaps through a template). That way existing passwords do not change if you were to change your default master password. version ~~~~~~~ The version is a string and its contents are arbitrary, however when its contents change so to does the generated password. So it can be as simple as a number or it could be a date or whatever you like. But it is good if you pick a convention and stick with it so that if you somehow lose your accounts file you still have some hope of recovering your passwords. Some websites put odd restrictions on the generated passwords, such as it must contain a digit and a symbol or it imposes a limit on the maximum number of repeated characters. Some of these restrictions can be satisfied by adding a prefix or a suffix, but for others, like the repeated character limit, there is no built in support in Abraxas to always satisfy them. In this case you can simply bump the version until you get a password that meets their requirements. password-type ~~~~~~~~~~~~~ The type of password to generate. Should be either 'words' (default) to generate pass phrases or 'chars' to generate passwords. num-words ~~~~~~~~~ The number of words to use in the pass phrase when 'type' is 'words' (default is 4). separator ~~~~~~~~~ A string that is used as the inter-word separator when 'type' is 'words'. If not given, a space is used. num-chars ~~~~~~~~~ The number of characters to use in the passwords when 'type' is 'chars' (default is 12). alphabet ~~~~~~~~ A string containing the characters to use when creating a password when 'type' is 'chars'. The default alphabet consists of the standard upper and lower case letters along with the digits. prefix ~~~~~~ A string whose contents are added to the beginning of a password or passphrase. suffix ~~~~~~ A string whose contents are added to the end of a password or passphrase. aliases ~~~~~~~ List of names that can be used as aliases for this account. This feature is often used to specify a shorter and easier to type name for the account. The secrets are generated based on the primary account name (the key for dictionary that describes the account). As such, that name should be chosen so that it is unambiguous and you will never be tempted to change it. That often results in a name that is too long to type easily. This entry allows you to specify one or more names that can be used as aliases for the primary account name. For example, you might want to choose a name like "gmail-derrickAsh" as the primary name of your gmail account and "gmail" as an alias. This would allow you to later create another gmail account and make it your primary gmail account simply by moving the "gmail" alias the new account. When sharing your accounts you may not wish to share your aliases. For example, if both you and your partner have accounts at Chase you may want to both use the alias Chase to refer to two different accounts. You can arrange this by using some Python code as follows:: from getpass import getuser accounts = { 'chase-amy': { 'aliases': ['chase'] if getuser() == 'amy' else [] ... }, 'chase-laura': { 'aliases': ['chase'] if getuser() == 'laura' else [] ... }, } username ~~~~~~~~ A string containing the username for the account. account ~~~~~~~ Either an account identifier for the account or a list containing multiple account identifier. Account identifiers must be given as strings. email ~~~~~ A string containing the email address associated with the account. url ~~~ A string containing the web address of the account or a list of strings each containing a web address. If a list of URLs are provided, the first will be used with the ``--browser`` and ``--default-browser`` command line arguments. In this case, the browser will be started and directed to display the first address. All the addresses are used in account discovery. If a URL component is discovered in a title bar, it will be compared against all of the URLs given in the list looking for a match. The URLs may be glob strings to generalize the matching. Given that the first URL can be sent to the browser it is best not to use globbing in the first URL. When a URL is used in account discovery, the presence of the communication protocol is significant. If the URL starts with 'https://', then Abraxas insists on the use of an encrypted link. If the link is not encrypted, the account will not be selected as a match and a warning will be issued (this is a relatively common way of tricking you into disclosing your password). Even if the URL does not start with 'https://', Abraxas will also require a encrypted link if PREFER_HTTPS is set to True in ``password/prefs.py`` unless the URL starts with 'http://'. remarks ~~~~~~~ A string containing any relevant remarks about the account. You can create a multiline remark as follows:: 'remarks': dedent(""" Wireless network settings: SSID: ourhouse Network security: WPA2 Personal """) security questions ~~~~~~~~~~~~~~~~~~ A list of strings containing the security questions they force you to answer. The string does not need to contain the question verbatim, a shortened version that is sufficient for you to identify which of the questions you need to provide the answer to is enough. For example, a typical list of security questions might be:: 'security questions': [ "first teacher's name", "name of elementary school", ], When initially giving the answers to these questions, you will have to select the questions you will answer, enter them into the accounts file, then get the answers by running Abraxas, and then copying the answers into the web page for your account. In this way, your answers will be quite unpredictable, even to those that know you well. The answers to the security questions will change if you change your security questions. Even the smallest change will result in a completely different answer. Once you have given the answers to your account provider you must not change the question at all unless you are willing to go through the trouble of updating the answers. window ~~~~~~ This may be either a glob string or a list of glob strings that match the title of the web page used to enter the username/password for the account. This is used to determine which account should be used if no account name is given on the command line. This enables you to set up a hot key, such as Alt-P, to run 'abraxas --autotype', which will identify which account to use from the active window title and then use the *autotype* field to log you in. When using commands from a shell the title of the window is generally unaffected by the command that is running. However, you can write a simple script that first sets the window title and then runs the command. Here is an example of such a script for mutt:: #!/bin/sh xdotool getactivewindow set_window --name "Mutt" mutt Alternatively, you can switch to Lilyterm, which is a Linux terminal emulator that I can recommend and that plays particularly nicely with Abraxas. It copies the command being run to the window title so it can be used to determine which account to use. Generally the window feature works well with web browsers, though some sites neglect to put identifying information in the title bar of their login page. This can be addressed in Firefox and Thunderbird by installing the 'Hostname in Titlebar' add on. In Chrome, use 'Url in Title'. They add the URL to the title bar, making it available to be matched with a window glob string. This add on also adds the protocol to the title as well. That allows you to key the password in such a way that it will not autotype unless the connection is encrypted (the protocol is https). In its default configuration, Abraxas recognizes the components in a 'Hostname in Titlebar' title. Those components, which include the title, the hostname, and the communication protocol (http or https), and compare those to the corresponding entries in each account. The title is compared to the *window* entries and the hostname and protocol are compared against the *url*. If no match is made with these components, then the raw title is compared against the *window* entries. When sharing your accounts with a partner you may not wish to share your window settings. For example, if both you and your partner have accounts at Chase and you both want to have the window title on the Chase web page to trigger your own account. You can arrange this by using some Python code as follows:: from getpass import getuser accounts = { 'chase-amy': { 'window': ['CHASE Bank*'] if getuser() == 'amy' else [] }, 'chase-laura': { 'window': ['CHASE Bank*'] if getuser() == 'laura' else [] }, } You might also find that you need different passwords on different machines. For example, you may have root access on several machines, each of which has a different root password. You can handle this as follows:: from socket import gethostname accounts = { 'root-mars': { 'template': '=words', 'window': ['su'] if gethostname() == 'mars' else [] }, 'root-venus': { 'template': '=words', 'window': ['su'] if gethostname() == 'venus' else [] }, } autotype ~~~~~~~~ A string containing a script that controls autotyping (when the -t or --autotype command line option is specified). The script consists of characters that will be emitted verbatim and codes that specify actions to take. Primarily the action is to replace the code with a character, a field from the account, or a secret. But the sleep action can be used to cause a pause in the typing. The following actions are supported: | {username} Replaced with the username for the account. | {account} Replaced with the account number for the account. | {url} Replaced with the URL for the account. | {email} Replaced with the email address for the account. | {remarks} Replaced with the remarks for the account. | {password} Replaced with the password for the account. | {question *N*} Replaced with security question *N* (*N* is an integer). | {answer *N*} Replaced with the answer to security question *N* (*N* is an integer). | {sleep *S*} Typing is paused for *S* seconds (*S* a real number) | {tab} Replaced with a tab. | {return} Replaced with newline. The default autotype script is "{username}{tab}{password}{return}" Other Fields ~~~~~~~~~~~~ The value of all other fields will be printed when the user requests all information about the account. Words File ++++++++++ The words file is '~/.config/abraxas/words'. The use of this file is optional. Abraxas has its own words that it uses if you do not provide a file yourself. It should contain a large number of words (thousands), one word per line. The more words your file contains, the more secure your pass phrases are, however anymore than 65,536 are not used. Do not change this file once you have started creating passwords, and be sure to back it up. Any change to this file will cause the generated pass phrases to change, which means you will not be able to use Abraxas to login to existing accounts that use pass phrases. EXAMPLE ======= Master Password File ++++++++++++++++++++ Here is a representative master password file (~/.config/abraxas/master.gpg):: dict_hash = "d9aa1c08e08d6cacdf82819eeb5832429eadb95a" secrets_hash = "db7ce3fc4a9392187d0a8df7c80b0cdfd7b1bc22" passwords = { 'derrick and peter': "e9a7a4246a6a95f179cd4579e6f9cb69", 'derrick and debbie': "60b56e021118ca2a261f405e15ac0165", 'default': """[Y$*{QCf"?yvDc'{4v?4r.iA0b3brHY z40;lZIs~bjj