Build Your Own Password Manager

This is a (work-in-progress) tutorial that will teach you shell scripting by showing you how to build the pass password manager in small steps.

Assumptions

  • Basic shell knowledge (cd, ls)
  • Basic programming experience (variables, functions, conditionals, loops)
  • Basic understanding of git will help in the section where we add git support (not too important)

The Plan

  1. A password generator
  • Step 1: echo "correcthorsebatterystaple"
  • Generate a random string
  • The generate command
  • The version command
  • The help command
  1. Storing plaintext passwords
  • Save generated password to $PREFIX
  • The show command
  • Make show the default command
  • The insert command
  • The rm command
  • The mv command
  • The cp command
  1. Encryption
  • The init command
  • GPG options and whether to use gpg2
  • gpg_winpath() for Cygwin
  • set_gpg_recipients()
  • Encrypt with generate and insert commands
  • Decrypt with show command
  • Reencrypt using init command
  1. Copy to clipboard
  • Generic clip()
  • Cygwin clip()
  • macOS clip()
  • -c option for generate and show commands
  • Clear clipboard after 45 seconds
  • Reset 45-second timer before starting a new one
  • Restore previous clipboard contents
  1. Getopt
  • Find GNU getopt for the platform
  • Use it for -c/--clip switch
  • More switches
  1. QR codes
  • Generic qrcode()
  • macOS qrcode()
  • -q option for generate and show commands
  1. Secure text editing
  • The edit command
  • Generic tmpdir()
  • macOS tmpdir()
  • FreeBSD $SHRED
  • OpenBSD tmpdir()
  1. Listing and searching
  • The ls command
  • The find command
  • The grep command
  1. Git
  • The git command
  • set_git()
  • git_add_file()
  • git_commit()
  • Add git support to generate and insert commands
  • Add git support to edit, rm, mv, cp commands
  1. Completion
  • bash completion
  • zsh completion
  • fish completion
  1. Signing and verification
  • Sign .gpg_id in init command
  • verify_file()
  • Sign git commits
  1. Multiple users
  • --path option for init command
  1. User extensions
  • cmd_extension()
  • An example: pass-update