Introduction
turtle-cpm is a command line tool to manage passwords, a replacement of the now gone cpm project.
The latest version is v24.8, released on 2024-08-01. See the release notes.
Notable features:
- Simple database format: encrypted SQLite (via
gpg
), tracking machines, services, users and passwords - Supports plain passwords and also Time-based one-time password (TOTP) shared secrets, calculating the actual TOTP code
- Can import the original cpm's XML database
- A little bit better than trivial search: you can search for e.g.
ldap
ormybank
without telling if you are searching for a service type or machine name
Naturally it lacks telemetry, unlike e.g. 1Password.
Website
Check out the project's website for a list of features and installation and usage information.
Platforms
cpm has been used on Linux, but nothing was done intentionally to prevent it from working on e.g. macOS or Windows.
The important bits of the code
-
The entry point is the
Main()
function incommands/root.go
. -
The test code lives under
commands/*_test.go
. -
The documentation is undeer
guide/
.
The turtle
The turtle-cpm codebase is independent from the original cpm. It's turtle because this project is not in C, so might be a little bit slower (though not significantly in practice).
License
Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Installation
Dependencies
You need to install GPG if you don't have it already and need to generate at least a key using:
gpg --gen-key
This will allow cpm to encrypt and decrypt your password database. Don't fear from specifying a passphrase for your key: you'll only have to enter it once after login (thanks to gpg-agent), and this way an attacker can't get access to your passwords, even if they steal both your private key & your cpm database.
Build from source
You can install cpm using:
go install vmiklos.hu/go/cpm@latest
If $(go env GOPATH)/bin
is not in your PATH
yet, you may want to add it, so typing cpm
will
invoke the installed executable.
Optional shell completion
Optionally, you can install shell completion for cpm, example for bash:
cpm completion bash > ~/.local/share/bash-completion/completions/cpm
You can test if it works in a new shell using:
cpm <tab><tab>
Usage
cpm supports creating, reading, updating and deleting passwords. You'll just create and read them most of the time, though.
Creating
You can ask cpm to generate a password for you and remember it using:
cpm create
You'll have to provide the machine and the user:
Machine: example.com
User: myuser
Generated password: 7U1FvIzubR95Itg
Specifying parameters can be useful if:
- you want to avoid an interactive question for the machine
- you want to specify a non-HTTP service
- you want to avoid an interactive question for the user
- you want to specify a password type
- you have preferred password
Example for such usage:
cpm create -m example.com -s http -u myuser -t plain -p 7U1FvIzubR95Itg
When the machine is not yours, it can be e.g. the domain of a website.
If you try to insert a password twice (same machine, service, user and password type), you will get an error. You can update or delete a password, though (see below).
Reading
You can search in your passwords by entering a search term. You can do this interactively:
cpm
You'll have to provide a search term:
Search term: example.com
id: 1, machine: example.com, service: http, user: myuser, password type: plain, password: 7U1FvIzubR95Itg
The search term can also be specified as an argument if non-interactive mode is wanted.
Or you can specify parameters to create additional filters for the search:
cpm search -m example.com -s http -u myuser -t plain
The search term is already specified in this case:
id: 1, machine: example.com, service: http, user: myuser, password type: plain, password: 7U1FvIzubR95Itg
Archived passwords are not shown, unless -v
or --verbose
is used. The verbose mode also shows
when the password was created and modified.
TOTP support
TOTP is one from of Two-Factor Authentication (2FA), currently used by many popular websites (Facebook, Mastodon, etc). Once a website asks you to scan a QR code for TOTP purposes, just ask for the TOTP shared secret and then add it to cpm using:
cpm create -m mymachine -u myuser -p "MY TOTP SHARED SECRET" -t totp
When searching, only the TOTP shared secret is shown by default:
cpm facebook
id: 1, machine: facebook.com, service: http, user: myuser, password type: plain, password: 7U1FvIzubR95Itg
id: 2, machine: facebook.com, service: http, user: myuser, password type: TOTP shared secret, password: ...
You can generate the current TOTP code using:
cpm --totp facebook
id: 2, machine: facebook.com, service: http, user: myuser, password type: TOTP code, password: ...
You can make this interaction easier using:
alias 2fa='cpm --totp'
And then you can generate the current TOTP code just by:
2fa facebook
id: 2, machine: facebook.com, service: http, user: myuser, password type: TOTP code, password: ...
Update and deletion
Update is quite similar to creation. If you want to update a password to a new, generated value, you can do so by using:
cpm update -p -
Notice the trailing hyphen.
You'll have to specify the ID:
Id: 2
Updated 1 password
Generated password: aDu3WwGlVP60HEn
You can also specify more parameters for cpm update
:
cpm update -i 2 -p -
In which case the command is not interactive:
Updated 1 password
Generated password: Ilsd08zGov5JyBR
You can use cpm search
to find the password ID.
The rest of the cpm update
parameters allow explicitly setting the
machine/service/user/type/password of an ID to a new, specified value.
Finally if you want to delete a password, you can do so by using:
cpm delete
You'll have to specify the ID:
Id: 2
Deleted 1 password
You can also specify a parameter for cpm delete
:
cpm delete -i 2
In which case the command is not interactive:
Deleted 1 password
Again, you can use cpm search
to find the password ID.
An alternative for deletion is to just mark the password as archived:
cpm update -i ... --archived true
Advanced topics
Distributed usage
One big downside of mobile-based TOTP apps is that you can't login to machines if you loose your
phone, and the TOTP shared secrets on those devices are not backed up. cpm
supports distributed
storage of passwords in a way that's similar to single-master replication in DBMS terms.
One possible setup is to have a central machine where you edit your cpm database, e.g. your home
router which is usually available or your VPS in some hosting. Then you can replicate the cpm
database to your other devices by configuring a virtual cpm
remote machine in your .ssh/config
on the other machines:
Host cpm
Hostname myserver.example.com
Finally pull the remote database to your local one, using:
cpm pull
This allows searching in your passwords even when you're offline. Keep in mind that editing the database on the slaves is not a good idea as the next pull will overwrite your local changes.
Toolkit integration
In case you have scripts to generate your local configuration files containing passwords from
templates, cpm
can be integrated into such a workflow, using the quiet mode of the search
subcommand. For example, if you have an app password at your mail provider, and you want to generate
your mutt configuration, you can query just the password from cpm
using:
cpm -q -m accounts.example.com -u $USER-mail-$HOSTNAME
Importing the old CPM XML database
In case you used the old cpm
tool, it used to store its data at ~/.cpmdb
as an XML file,
compressed and encrypted. If you want to import that into turtle-cpm's database, you can do so
using:
cpm import
Inspecting the encrypted database manually
In case you want to inspect the SQLite database of cpm
manually, you need to decrypt it yourself,
using (assuming an empty XDG_STATE_HOME
environment variable):
gpg --decrypt -a -o decrypted.db ~/.local/state/cpm/passwords.db
After this, you can inspect the database using a GUI like:
sqlitebrowser decrypted.db
Don't forget to delete the decrypted database after you're done with your investigation.
Reference documentation
Apart from this guide, reference documentation is available in cpm
itself. You can learn about the
possible subcommands using:
cpm -h
You can also check all the available options for one given subcommand using e.g.:
cpm create -h
An alternative to this is the manual pages under man/
, which provide the same information.
Re-sharing TOTP shared secrets
TOTP shared secrets are typically transferred as QR codes, though there is usually a fallback option
to get the shared secret string itself, which is what cpm
can manage. However, the QR code also
contains other information about the shared secret, and there are tools like
2fa-qr that allow obtaining the full otpauth://
URL from the
QR code image. cpm
supports storing these full URLs as well, they look something like this:
otpauth://totp/Myserver:myuser?secret=...&digits=6&algorithm=SHA1&issuer=Myserver&period=30
Where Myserver is some server-side app name and myuser is your user name.
The benefit of storing the full URL in the cpm
database is that later you can re-share them as QR
codes using e.g.:
cpm -t totp --qrcode facebook
machine: facebook.com, service: http, user: myuser, password type: TOTP shared secret, password:
...
The following lines will be a QR code you can scan with a mobile app.
Development notes
Updating dependencies
Ideally CI checks everything before a commit hits main, but run
go get -u && go mod tidy
from time to time and make sure Go dependencies are reasonably up to date.
Shell completion
Changes to the shell completion can be tested, without restarting the shell using:
source <(cpm completion bash)
Go debugging
To run a single test:
go test -run=TestInsert ./...
Changelog
main
- create / update: passwords now have a create / modify date, search shows these in verbose mode
24.8
- search / update: passwords can be now archived, search hides these by default without deleting the password
- drop compatibility with cpm < 7.5: update from old versions to 24.2 first
24.2
- create / update: new
-y
switch to generate more secure passwords (3 instead of 0 numeric symbols)
7.6
create
/create -n
now confirms if the password was actually created or it only would be created.- pwgen installation is not necessary,
cpm
now uses go-password instead. update
now has only a single way to select which password to update: the ID has to be specified using-i
or interactively. This allows updating the password or type to a specified value while only specifying an ID.delete
now has only a single way to select which password to delete: the ID has to be specified using-i
or interactively.- oathtool installation is no longer necessary,
cpm
now uses otp instead.
7.5
- update: new
-i
switch to edit themachine
,service
oruser
of a password without changing the password itself sync
is renamed topull
, since it's a remote -> local copy only- delete: new
-i
switch to delete a password based on the search result
7.4
- added shell completion support
7.3
- create: new
-n
switch, introducing a dry run mode to see what style of password would be generated - update and delete: new
-n
switch, showing how many passwords would be updated/deleted (typically 0 or 1), without writing the database
7.2
- in case the
XDG_STATE_HOME
environment variable is set to a custom value, it is now respected
7.1
- when specifying TOTP shared secrets, it is now supported to specify
otpauth://
URLs - new
cpm --qrcode
option to show the TOTP shared secret as a qr code
7.0
- new
version
subcommand that shows the version number
6.0
- create, update and delete: add interactive mode in case
--machine
or--user
is not specified - search: add interactive mode when no search terms are specified
5.0
scripts/cpmsync.sh
is now a built-in subcommand,cpm sync
. No need to install it manually anymore.cpm search
no longer encrypts the database at the end, to be a little bit faster.- create/search/update/delete's -t flag now has a proper type, so it errors on invalid values (other
than
plain
ortotp
)
4.0
- New password generation during update, the password flag is now optional.
- The service flag is now optional in general, and defaults to "http".
3.0
- Added overview documentation to augment the existing automatically generated reference
documentation. (
cpm -h
,cpm create -h
, etc.) - New quiet mode during search, to consume the output from scripts
- Added manpages
- New password generation during create, the password flag is now optional.
2.0
- While encrypting the database, the
gpg
invocation now defaults to the self recipient, so no need to specify a UID manually. - Search now shows both plain passwords and TOTP shared secrets by default, so in case a site only has a TOTP shared secret, there is a search result instead of confusing empty output.
- The decrypted database is removed from disk even in case of application failure.
- More tests: 100% statement coverage.
1.0
- Initial release
Contributors
Contributing
turtle-cpm is free and open source. You can find the source code on GitHub and issues and feature requests can be posted on the issue tracker. If you'd like to contribute, please consider opening a pull request.
Reporting problems
If you post a bugreport in the issue tracker, please always describe a single problem in one issue.
Here is what to include in a bugreport:
Reproducer steps
- First step
- Second step
- Third step
Actual result A description of what happens currently.
Expected behavior A description of what you expected to happen.
Version information
The output of cpm version
.