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 or mybank 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 in commands/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 the machine, service or user of a password without changing the password itself
  • sync is renamed to pull, 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 or totp)

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

  1. First step
  2. Second step
  3. 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.