As I mentioned a long time ago, I use pass as my password store. Recently I was thinking about a scenario where I lose access to my computer and backups and need to check emails. I decided that it would be beneficial to remember at least some of my passwords.
My idea is pretty simple. I’d prepare a list of passwords I want to remember, say
mail/private mail/job bank
(pass
uses a hierarchical structure of the passwords) and have a script pick one of them at random and ask me it. Then I can run that script once per day. (Theoretically, it would be better to use some spaced repetition algorithm, but it’s probably not worth the effort – I don’t expect I’d want to memorize more than a dozen passwords, so after a few weeks or so of using the SRA, I’d end up with way less than one repetition per month on average.)
So, let’s write some Elisp to make Emacs choose a password at random and ask me about it until I get it correctly. Let’s also make it KISS – it will just ask until the password is given correctly, no feedback like “type it again”, no quit after 3 attempts etc.
(setq passrep-password-list '("mail/private" "mail/job" "bank")) (defun passrep-ask-password (pass-name correct) "Ask the user about PASS-NAME. Return t if the user answered correctly." (let* ((typed (read-passwd (format "password %s: " pass-name))) (result (string= correct typed))) (clear-string typed) result)) (defun passrep-ask-password-until-correct () "Choose a password and ask until give correctly. If the user forgets the password, it is their responsibility to run `pass` in the terminal to recall it." (interactive) (let* ((pass-name (seq-random-elt passrep-password-list)) (correct (string-trim-right (shell-command-to-string (format "pass %s" pass-name))))) (while (not (passrep-ask-password pass-name correct))) (clear-string correct)))
No surprises here – the passrep-ask-password
function is repsonsible for asking the chosen password, and passrep-ask-password-until-correct
uses pass
to get the password and ask about it until given correctly. One interesting piece is the clear-string
function, which mutates the given string, filling it with zeros. This way the password will not hang around in Emacs memory after the whole exercise – even though the references to it are lost after passrep-ask-password-until-correct
is evaluated and the memory will be reclaimed by the garbage collector, the password will still be in RAM until the same place in memory is actually used for something else and overwritten. Since we have no control over that, it’s safer to fill the string explicitly with zeros before we lose the reference to it.
So, that’s it for today. And let me mention that this could be made much more interesting, for example by making Emacs use timers to remind me to actually run this command at least once per day. Actually, I am strongly considering adding something like this to the Elisp book. Let me know in the comments if you consider this a good idea!