commit 491a9c9bb679b85f9c2ad7fe036a61830c254c8b
parent 84f87e2cf4dba5f25bc11c119ead3b1af947e628
Author: Riaz <riaz@riazj.com>
Date: Thu, 24 Jul 2025 07:08:25 -0700
Write article about writing a password manager
Diffstat:
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/articles/pw.html b/articles/pw.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>Write a Password Manager in POSIX Shell | Riaz's Website</title>
+<link rel="stylesheet" href="/style.css">
+<link rel="icon" href="data:,">
+<meta name="description" content="How to write a simple password manager in POSIX shell that is more minimal than pass">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+</head>
+<body>
+<h1>Write a Password Manager in POSIX Shell</h1>
+<hr>
+<article>
+<p><a href="https://www.passwordstore.org/">pass</a> is over 600 SLOC, yet I don't use its nested hierarchy, git integration, nor password generation.</p>
+<p>To encrypt and decrypt, pass does nothing too fancy that is a major security issue by omission. This is the code for showing a password</p>
+<pre>
+if [[ -f $passfile ]]; then
+ if [[ $clip -eq 0 && $qrcode -eq 0 ]]; then
+ pass="$($GPG -d "${GPG_OPTS[@]}" "$passfile" | $BASE64)" || exit $?
+ echo "$pass" | $BASE64 -d
+</pre>
+<pre>
+# This base64 business is because bash cannot store binary data in a shell
+# variable. Specifically, it cannot store nulls nor (non-trivally) store
+# trailing new lines.
+</pre>
+<p>and encrypting a password.</p>
+<pre>
+if [[ $multiline -eq 1 ]]; then
+ echo "Enter contents of $path and press Ctrl+D when finished:"
+ echo
+ $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" || die "Password encryption aborted."
+</pre>
+<p>Combining these two GPG commands sets the foundation for a bare bones and hackable password manager. I currently use <a href="/git/dotfiles/file/.local/bin/pw.html">the one I wrote</a>, inspired by dcat on GitHub. <a href="/git/dotfiles/file/.local/bin/pwm.html">This one-liner</a> allows for integration with dmenu: <code>pw get "$(pw ls | dmenu -l 10)" | xdotool type --clearmodifiers --file -</code>.</p>
+</article>
+<footer>
+<hr>
+<a href="/">Home Page</a></footer>
+</body>
+</html>
diff --git a/articles/technology-i-use.html b/articles/technology-i-use.html
@@ -25,7 +25,6 @@
</li>
<li>Text Editor: <a href="https://martanne.github.io/vis/">Vis</a></li>
<li>Document Viewer: <a href="https://pwmt.org/projects/zathura/">zathura</a></li>
-<li>Password Manager: <a href="https://www.passwordstore.org/">pass</a></li>
<li>Window Manager: <a href="https://dwm.suckless.org/">dwm</a></li>
<li>Terminal: <a href="https://st.suckless.org/">st</a></li>
<li><a href="https://github.com/astier/xhidecursor">xhidecursor</a>: hide the cursor on keypress</li>
diff --git a/index.html b/index.html
@@ -15,6 +15,7 @@
<nav><a href="git/">Code</a> | <a href="contact">Contact</a> | <a href="links">Links</a></nav>
<h2>Articles</h2>
<ul>
+<li><time datetime="2025-07-24">2025 Jul 24</time> <a href="/articles/pw">Write a Password Manager in POSIX Shell</a></li>
<li><time datetime="2025-07-19">2025 Jul 19</time> <a href="/articles/tldr">Simple TLDR Client Written in POSIX Shell</a></li>
<li><time datetime="2025-06-08">2025 Jun 08</time> <a href="/articles/dictionaries">Notes on Offline English Dictionaries</a></li>
<li><time datetime="2025-02-27">2025 Feb 27</time> <a href="/articles/format-html">I Quit Using Prettier to Format HTML</a></li>