pwclip
""""""

Description
-----------

pwclip is a password management tool. It's main target is having fast and
comfortable access to passwords by storing them for a variable time in the
systems clipboard (copy/paste buffer). It uses either GnuPG2 or OpenSSL
(converted to GPGSM) keys for cryptographic operations. It also works with
yubikey's challenge-response to generate uniq HMAC-SHA1 hashes as well.

The main feature is the pwcli/pwclip mode which provides easy access to the
~/.passcrypt file. That file is used by default as password storage. The
program is executed in gui mode when pwclip is called and in cli mode when
pwcli is called respectivly. It creates the ~/.passcrypt file which is gpg
encrypted text using either the value of GPGKEY or GPGKEYS from the users
environment as gpg encryption recipients. On startup it lookes for a
~/.pwd.yaml file which is merged with the already known passwords from the
~/.passcrypt file if there already is one. All entrys in the ~/.passcrypt file
will be overridden by entrys from the ~/.pwd.yaml file. Adding, removing or
changing password entrys is also possible using pwcli mode.

The second operating mode is for operating on yubikeys to generate uniq
responses which might be used as passwords while they can be generated by that
exact yubikey only. The first yubikey found on the system and the first slot,
configured with (HMAC-SHA1) challenge-response, will be used. For that function
Windows is supported (see "Install" section).

To catch user input python's Tk (tkinter) library is used to create a simple
password input window. The appropriate response is saved for only 3 seconds
by default to not have it exposed as soon as it's used. The utility also
supports the input of any integer which is then used as timer. Otherwise the
environment is searched for PWCLIPTIME and uses the value of that environment
variable as timer. The timer is used as time in which the received password
stays in the paste buffer bevore its replaced by the previously copied value.
As you may see there is an optional commet which is used as text notification
displayed on the screen if set. Therefor python3's gi notify2 is used which is
another reason for discontinuing python2 support.

I would encourage you to bind pwclip to a shortcut within your X-Environment
to have access to your passwords at any time. On Windows-Systems you need to
create a link for it somewhere. When editing that link you may set a keyboard
shortcut (could not find a nicer solution by now). The target for that link
then whould be "%PYTHONINSTALLDIR%\\scripts\\pwclip.exe".

I've been trying my best to keep the passwords from unwanted access BUT i do
!NOT GUARANTEE! that the passwords handled during runtime are safe from other
users access (especially "root" on linux systems - help on that is very
welcome) - please be aware of that!

Since version 1.2 openssl keys are supported. For the use with pwclip they will
be converted to gpg-keys automaticly and gpgsm is used instead of gpg - openssl
is not used for en/decryption to be precisely.

The ~/.pwd.yaml as well as the ~/.passcrypt file is assembled as a list of one
or more users which should be named like the username used for current system
login. You may have more than one users passwords in the passcrypt but any user
who can store passwords also is able to read password stored for other users in
that file. It is just of use for visual kategories if you have stored passwords
for different systems users sharing the same passcrypt file.
As an example: A person called "Andrew" has a username called "bob". On some
other machine he has a username called "cat" and he uses SSH for both of them.
The shared passcrypt file would be assembled like the attached YAML-Format
section. If so providing -u or -A when beeing logged in as "bob" or "cat"
respectivly may be omitted. In the following example both, "bob" and "cat" have
an entry called ssh. If -A is used in that case the entry corresponding to the
logged-in user is prefered. If in doubt you're able to read the crypt file
using "gpg -d ~/.passcrypt" as well (assuming the correct gpg-key is present).

YAML-Format
-----------

\-\-\-

bob:
    \- ssh:

        \- $om3(rypt!cPass

        \- DoNotForgetSomethingReminder

    \- othertool:

        \- 0th3r(rypt!cPass

cat:
    \- ssh:

        \- $om30ther(rypticPass


Installation
------------

On Windows you need to install Python3 from http://python.org/ first. On most
Linux distributions python will be part of the system. With Python installed,
you can install the pwclip package from the Python-Package-Index (pyPI) by
running:

``pip3 install pwclip``

and installing the dependencies (not managed by pip) manually.

Installing from source
----------------------

To install this package from a source distribution archive, do the following:

1. Extract all the files in the distribution archive to some directory on your
   system.

2. In that directory, run:

``python setup.py install``

Installing via apt
------------------

curl deb.janeiskla.de/ubuntu/project/d0ndeb-pub.key | apt-key add -
apt-get update
apt-get install python3-pwclip

Usage
-----

    Although is was planed as GUI-Program it's also possible to be executed from
    terminals. For Windows, Linux and OSX there is an appropriate executable
    packed which might be executed like the following examples will show:

    **-GPG-Mode-**

    If there is an environment variable called GPGKEYS it will use those keys to
    encrypt on changes to the password file. To list the password file you may use
    the list switch followed by optional search pattern like:

    ``pwcli -l``

    or

    ``pwcli -l $PATTERN``

    as you can see the yaml format tends to be used for multiple user names to
    better manage large lists. By default the current users entrys will be listed
    only. To have them all listed (or searched for by the above pattern example)
    use:

    ``pwcli -A -l $PATTERN``

    To one-shot convert a key/cert pair in openssl x509 format, read passwords from
    passwords.yaml and list them:

    ``pwcli -Y passwords.yaml --cert ssl.crt --key ssl.key --ca-cert ca.crt -l``

    **-Yubikey-Mode-**

    The YKSERIAL environment variable is used if found to select the yubikey to use
    if more than one key is connected. Otherwise the first one found is chosen.
    Likewise it also accepts an option:

    ``pwcli -y $YKSERIAL``

    To have it wait for a specific time like 60 seconds (bevore resetting the paste
    buffer to the previously copied value) the PWCLIPTIME environment variable is
    used or also the command accepts it as input:

    ``pwcli -t 60 -l somename``

    Most of the options may be combined. For more information on possible options in
    cli mode please see:

    ``pwcli --help``

    **-GUI-Modes-**

    For the GUI-Mode just use one of the following commands, also accepting most of
    the commandline arguments:

    ``pwclip``

    ``ykclip``


Troubleshoot
------------

When using the yubikey challenge-response mode there is a bug in the usb_hid
interface. This is because of python2 => 3 transition, most likely and can be
fixed by executing the following command:

``sudo vi +':107s/\(.* =\).*/\1 response[0]/' +':wq' /usr/local/lib/python3.5/dist-packages/yubico/yubikey_4_usb_hid.py``

Explained:

In line 107 of the file

``/usr/local/lib/python3.5/dist-packages/yubico/yubikey_4_usb_hid.py``

the ord() coversion of the response:

``r_len = ord(response[0])``

needs to be replaced by:

``r_len = response[0]``


Credits
-------

I hope that this might be somewhat of help or at least be inspiring for own
ideas. You're alway welcome to leave me a message for reviews or feature
requests as well as bug reports: <mail@leonpelzer.de>

 * Python3 developers for IMHO one of the best programming languages
 * stackoverflow.com for hosting endless threads of troubleshooting
 * Pyperclip for the excellent Windows & OSX clipboard code
 * Conrad Parker for xsel as linux copy/paste backend
 * Yubico (cheap & solid HW-Security-Modules) & python-yubico developers
 * GNU Privacy Guard (basic kryptography) & python-gnupg developers
 * SonicLux for testing and telling me that a final version must not be 0.3.3 :D


=========
Changelog
=========

1.7.16
------

Released: 2021-01-14

  * fix wrong error message telling decryption went wrong although workin
  
  * fix continuation even though user input demands exit
  

1.7.15
------

Released: 2020-12-19

  * fix again for gpg self-check method

  * fix printing wrong passwords in gui-mode if the password contains
    combinations of the special caracters: `"$` and `'$`


1.7.14
------

Released: 2020-12-07

  * fix that no cli for yubi mode (ykcli) being created

  * fix gpg options to also accept untrusted keys

  * fix gpg interactive stuff hanging in backgroundwhen in gui-mode

  * fix gpg self-check method


1.7.13
------

Released: 2020-12-03

  * fix -e expression takes argument as it should

  * fix some user input parsing as well as corresponding reactions

  * fix aborting if password was entered wrong for the 3rd time

  * removed error output if not all keys listed in the recipients are found


1.7.12
------

Released: 2020-12-01

  * fix wrong names for notification and switched the API to py-notifyer since
    that one has windows suopport via `win10toast`


1.7.11
------

Released: 2020-03-20

  * [W] fix language settings for gnupg under windows since some characters
    of some languages are broken on commandline output

  * again fixing around automatic docs generating (pypi project description)
