From 6cbb431459e9a0db73264c4144937a136fdb5b83 Mon Sep 17 00:00:00 2001 From: Vineet Kumar Date: Fri, 22 May 2026 16:45:27 -0400 Subject: add random password/username generation --- kasi.el | 55 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/kasi.el b/kasi.el index f2ca588..1031afd 100644 --- a/kasi.el +++ b/kasi.el @@ -44,35 +44,68 @@ (defvar kasi-version "1.0") -(defun kasi-filename-short (file) +(defun kasi--filename-short (file) "Returns shortened name of filename." (file-name-sans-extension (file-relative-name file kasi-dir))) -(defun kasi-filename () +(defun kasi--filename () "Returns full filename of the secret file." (let* ((filenames (file-expand-wildcards (format "%s/*/*" kasi-dir))) (options (mapcar (lambda (f) - (kasi-filename-short f)) + (kasi--filename-short f)) filenames)) (selected (completing-read "File: " options)) (file (elt filenames (seq-position options selected)))) file)) -(defun kasi-get (file elem) +(defun kasi--get (file elem) "Returns element from secret file." (car (with-temp-buffer (insert-file-contents file) (alist-get elem (read (current-buffer)))))) -(defun kasi-totp (file) +(defun kasi--totp (file) "Returns current TOTP code from secret file." - (let* ((totp-secret (kasi-get file 'totp)) + (let* ((totp-secret (kasi--get file 'totp)) (totp-code (totp (base32-hex-decode totp-secret)))) (kill-new totp-code) (message (format "TOTP %s for %s copied to kill ring" totp-code - (kasi-filename-short file))))) + (kasi--filename-short file))))) + +(defun kasi--random-string (length charset) + "Generate a random string of LENGTH using characters from CHARSET. +Uses /dev/urandom for cryptographic security." + ;; I have not seen any other built-in way to get cryptographically + ;; random outputs in Emacs. + (let* ((bytes (with-temp-buffer + (call-process "dd" nil (current-buffer) nil + "if=/dev/urandom" "bs=1" (format "count=%d" (* length 4))) + (buffer-string))) + (charset-len (length charset)) + (result "")) + (dotimes (i length) + (setq result (concat result + (char-to-string + (aref charset + (% (aref bytes i) + charset-len)))))) + result)) + +;;;###autoload +(defun kasi-generate-password (&optional length) + "Generate a random password of LENGTH (default 32)." + (interactive "P") + (let ((charset "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~")) + (message (kasi--random-string (or length 32) charset)))) + +;;;###autoload +(defun kasi-generate-username (&optional length) + "Generate a random username of LENGTH (default 12)." + (interactive "P") + (let ((charset "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")) + (message (kasi--random-string (or length 12) charset)))) ;;;###autoload (defun kasi (command file) @@ -83,15 +116,15 @@ username email totp))) - (kasi-filename))) + (kasi--filename))) (pcase command ('edit (find-file-other-window file)) - ('totp (kasi-totp file)) + ('totp (kasi--totp file)) ((or 'password 'username 'email) (progn - (kill-new (kasi-get file command)) + (kill-new (kasi--get file command)) (message (format "Copied %s for %s to kill ring." command - (kasi-filename-short file))))))) + (kasi--filename-short file))))))) (provide 'kasi) -- cgit v1.2.3