From 30e93e676f4342d4beb00337e8220b6d84ac2534 Mon Sep 17 00:00:00 2001 From: rearman Date: Thu, 18 Sep 2025 11:47:51 -0400 Subject: [PATCH] Organize, add password generation Defun to generate password of arbitrary length, with option to omit special characters, and another to interactively insert the password into a file. No defun to copy to clipboard, since I'm assuming this will be mostly used while creating a pass(1) compliant gpg file. --- re/re-pass-alike.el | 79 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 10 deletions(-) diff --git a/re/re-pass-alike.el b/re/re-pass-alike.el index b9550fb..734baee 100644 --- a/re/re-pass-alike.el +++ b/re/re-pass-alike.el @@ -3,6 +3,8 @@ ;;; Code: +;; Generate totp code + (require 'bindat) (require 'gnutls) (require 'hexl) @@ -75,16 +77,6 @@ required for HMAC-TOTP." (symbol-name filename)) ".gpg")))) -(defun get-password (&optional filename) - "Return a password given a file where it is stored. -Assumes same structure as `pass(1)'." - (re/get-line-from-file (keyfile-string filename) 1)) - -(defun password-to-clipboard (&optional filename) - "Copy the returned password to the clipboard." - (interactive) - (kill-new (get-password filename))) - (defun get-totp (&optional filename) "Generate a totp code given a file with the secret hex string. If no filename given, prompt for one. @@ -98,5 +90,72 @@ Also assumes the file is in `~/.password-store' and has the `.gpg' extension." (interactive) (kill-new (get-totp filename))) + +;; Find password from pass(1) entry + +(defun get-password (&optional filename) + "Return a password given a file where it is stored. +Assumes same structure as `pass(1)'." + (re/get-line-from-file (keyfile-string filename) 1)) + +(defun password-to-clipboard (&optional filename) + "Copy the returned password to the clipboard." + (interactive) + (kill-new (get-password filename))) + + +;; Password generation + +(defconst *lowercase* + '("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" + "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z") + "List of strings containing the lowercase English alphabet.") + +(defconst *uppercase* + '("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" + "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z") + "List of strings containing the uppercase English alphabet.") + +(defconst *numbers* + '("0" "1" "2" "3" "4" "5" "6" "7" "8" "9") + "List of strings containing the single-digit numbers.") + +(defconst *special-characters* '("!" "?" "$" "%" "&" "'" "(" ")" "*" + "+" "," "-" "." "/" ":" ";" "<" "=" ">" + "?" "@" "[" "]" "^" "_" "{" "|" "}" "~") + "List of strings containing the special visible characters excluding \\ and \" .") + +(defun pw-get-char (&optional no-special-chars) + "Select a single character at random to be used in a password. +If `no-special-chars' is t, use only alpha-numeric characters." + (let ((selected-charset (append *lowercase* + *uppercase* + *numbers* + (when (null no-special-chars) + *special-characters*)))) + (elt selected-charset (random (length selected-charset))))) + +(defun pw-get-chars (password-length &optional no-special-chars) + "Generate a list of characters as strings to be made into a password. +If `no-special-chars' is t, use only alpha-numeric characters." + (append (list (pw-get-char no-special-chars)) + (when (> password-length 1) + (pw-get-chars (- password-length 1) no-special-chars)))) + +(defun generate-password (password-length &optional no-special-chars) + "Combine a list of randomly-selected characters into a single string of length given. +calls `pw-get-chars'. If `no-special-chars' is `t', use only alpha-numeric characters." + (apply #'concat (pw-get-chars password-length no-special-chars))) + +(defun insert-generated-password (&optional password-length) + "Insert a generated password into the current buffer. +Negative password-length (or negative arg) sets `no-special-chars' for `generate-password'." + (interactive "p") + (let ((len (if (or (null password-length) (= 1 (abs password-length))) + 16 + (abs password-length))) + (no-special-p (and (numberp password-length) (< password-length 0)))) + (insert (generate-password len no-special-p)))) + (provide 're-pass-alike) ;;; re-pass-alike.el ends here -- 2.39.5