Common Lisp: read password on a terminal (by hiding its input)



This content originally appeared on DEV Community and was authored by vindarel

We want to have a prompt asking for a password or other sensitive information:

> enter password:

and hide the characters we type:

> enter password: *****

A solution: call /bin/stty and enable/disable its echo:

(defun enable-echo ()
  (uiop:run-program '("/bin/stty" "echo") :input :interactive :output :interactive))

(defun disable-echo ()
  (uiop:run-program '("/bin/stty" "-echo") :input :interactive :output :interactive))
  ;; or:
  ;; (sb-ext:run-program "/bin/stty" '("-echo") :input t :output t))


(defun prompt (msg)
  (format t msg)
  (force-output)
  (read-line))

(defun pass-prompt ()
  (format t "password: ")
  (force-output)
  (disable-echo)
  (unwind-protect
      (read-line)
    (enable-echo)))

(eval-when (:execute)
  (let ((pass (pass-prompt)))
    (format t "~&I still know the pass was ~s~&" pass)))

Run this: sbcl --load read-password.lisp, and you get the above prompt.

Other libraries that help hiding sensitive information on other contexts (like, in the REPL output) are:

I used them and can recommend them.

Other libraries are to be found on awesome-cl.

That’s all!

Lisp?!


This content originally appeared on DEV Community and was authored by vindarel