Make passphrase generation synchronous
This offers better options for testing.
This commit is contained in:
parent
22b72c8460
commit
f39f845e74
1 changed files with 42 additions and 55 deletions
97
dispass.el
97
dispass.el
|
@ -7,6 +7,7 @@
|
||||||
;; Version: 1.1.2
|
;; Version: 1.1.2
|
||||||
;; Keywords: processes
|
;; Keywords: processes
|
||||||
;; URL: http://projects.ryuslash.org/dispass.el/
|
;; URL: http://projects.ryuslash.org/dispass.el/
|
||||||
|
;; Package-Requires: ((dash "1.0.0"))
|
||||||
|
|
||||||
;; Permission to use, copy, modify, and distribute this software for any
|
;; Permission to use, copy, modify, and distribute this software for any
|
||||||
;; purpose with or without fee is hereby granted, provided that the
|
;; purpose with or without fee is hereby granted, provided that the
|
||||||
|
@ -32,6 +33,8 @@
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'dash)
|
||||||
|
|
||||||
(defgroup dispass nil
|
(defgroup dispass nil
|
||||||
"Customization options for the DisPass wrapper."
|
"Customization options for the DisPass wrapper."
|
||||||
:group 'external)
|
:group 'external)
|
||||||
|
@ -84,55 +87,20 @@ Uses `tabulated-list-mode-map' as its parent.")
|
||||||
'("dispass1" "dispass2")
|
'("dispass1" "dispass2")
|
||||||
"The list of algorithms supported by DisPass.")
|
"The list of algorithms supported by DisPass.")
|
||||||
|
|
||||||
(defun dispass-process-sentinel (proc status)
|
|
||||||
"Report PROC's status change to STATUS."
|
|
||||||
(let ((status (substring status 0 -1))
|
|
||||||
(buffer (process-buffer proc)))
|
|
||||||
(unless (string-equal status "finished")
|
|
||||||
(message "dispass %s" status))
|
|
||||||
|
|
||||||
(unless (eq (current-buffer) proc)
|
|
||||||
(kill-buffer buffer))))
|
|
||||||
|
|
||||||
(defun dispass-erase-buffer (buffer)
|
|
||||||
"Completely erase the contents of BUFFER."
|
|
||||||
(save-current-buffer
|
|
||||||
(set-buffer buffer)
|
|
||||||
(buffer-disable-undo buffer)
|
|
||||||
(kill-buffer buffer)))
|
|
||||||
|
|
||||||
(defun dispass-label-at-point ()
|
(defun dispass-label-at-point ()
|
||||||
"When in `dispass-labels-mode', get the label at `point'."
|
"When in `dispass-labels-mode', get the label at `point'."
|
||||||
(let ((labels-mode-p (eq major-mode 'dispass-labels-mode)))
|
(let ((labels-mode-p (eq major-mode 'dispass-labels-mode)))
|
||||||
(tabulated-list-get-id)))
|
(tabulated-list-get-id)))
|
||||||
|
|
||||||
(defun dispass-process-filter-for (label)
|
(defun dispass--get-passphrase-matcher (label)
|
||||||
"Create a specialized filter for LABEL.
|
"Return a function that will get the passphrase for LABEL."
|
||||||
|
`(lambda (output)
|
||||||
|
(string-match ,(concat "^[ \t]*" label "[ \t]*\\(.+\\)$") output)
|
||||||
|
(substring output (match-beginning 1) (match-end 1))))
|
||||||
|
|
||||||
This filter checks if a password has been asked for or if the
|
(defun dispass-start-process (cmd label pass create length
|
||||||
label shows up in a line, which will be the line with the
|
|
||||||
passphrase that has been generated."
|
|
||||||
`(lambda (proc string)
|
|
||||||
"Process STRING coming from PROC."
|
|
||||||
(cond ((string-match "^\\(Password[^:]*\\|Again\\): ?$" string)
|
|
||||||
(process-send-string
|
|
||||||
proc
|
|
||||||
(concat (read-passwd
|
|
||||||
(concat (replace-regexp-in-string
|
|
||||||
"^[ \t\n]+\\|[ \t\n]+$" "" string) " ")
|
|
||||||
nil) "\n")))
|
|
||||||
|
|
||||||
((string-match (concat "^[ \t]*" ,label "[ \t]*\\(.+\\)$")
|
|
||||||
string)
|
|
||||||
(let ((buffer (process-buffer proc)))
|
|
||||||
(with-current-buffer buffer
|
|
||||||
(insert (match-string 1 string))
|
|
||||||
(clipboard-kill-ring-save (point-min) (point-max))
|
|
||||||
(message "Password copied to clipboard.")))))))
|
|
||||||
|
|
||||||
(defun dispass-start-process (cmd label create length
|
|
||||||
&optional algo seqno args)
|
&optional algo seqno args)
|
||||||
"Ask DisPass call CMD for LABEL.
|
"Ask DisPass call CMD for LABEL and PASS.
|
||||||
|
|
||||||
When CREATE is non-nil send along the -c switch to make it ask
|
When CREATE is non-nil send along the -c switch to make it ask
|
||||||
for a password twice. When LENGTH is an integer and greater than
|
for a password twice. When LENGTH is an integer and greater than
|
||||||
|
@ -142,7 +110,7 @@ algorithm be used by DisPass to generate the passphrase. SEQNO
|
||||||
asks DisPass to use SEQNO as a sequence number.
|
asks DisPass to use SEQNO as a sequence number.
|
||||||
|
|
||||||
If specified add ARGS to the command."
|
If specified add ARGS to the command."
|
||||||
(let ((args `(,cmd ,@args "-o"))
|
(let ((args `(,cmd ,@args "-o" "-p" ,pass))
|
||||||
proc)
|
proc)
|
||||||
(when create
|
(when create
|
||||||
(setq args (append args '("-v"))))
|
(setq args (append args '("-v"))))
|
||||||
|
@ -160,11 +128,9 @@ If specified add ARGS to the command."
|
||||||
(when dispass-labelfile
|
(when dispass-labelfile
|
||||||
(setq args (append `("-f" ,dispass-labelfile) args)))
|
(setq args (append `("-f" ,dispass-labelfile) args)))
|
||||||
|
|
||||||
(message "%s" `(,@args ,label))
|
(shell-command-to-string
|
||||||
(setq proc (apply 'start-process "dispass" "*dispass*"
|
(apply #'concat
|
||||||
dispass-executable `(,@args ,label)))
|
(-interpose " " `(,dispass-executable ,@args ,label))))))
|
||||||
(set-process-sentinel proc 'dispass-process-sentinel)
|
|
||||||
(set-process-filter proc (dispass-process-filter-for label))))
|
|
||||||
|
|
||||||
(defun dispass-get-labels ()
|
(defun dispass-get-labels ()
|
||||||
"Get the list of labels and their information."
|
"Get the list of labels and their information."
|
||||||
|
@ -210,24 +176,45 @@ If specified add ARGS to the command."
|
||||||
" list --script")))
|
" list --script")))
|
||||||
(goto-char (point-min)))
|
(goto-char (point-min)))
|
||||||
|
|
||||||
|
(defun dispass--verified-password ()
|
||||||
|
"Ask for and verify a password."
|
||||||
|
(let ((passwd (read-passwd "Password: ")))
|
||||||
|
(if (and (equal passwd (read-passwd "Password (again): ")))
|
||||||
|
passwd
|
||||||
|
(error "Passwords don't match"))))
|
||||||
|
|
||||||
|
(defun dispass--generate (label pass create length algo seqno)
|
||||||
|
"Call `dispass-start-process' to generate a passphrase.
|
||||||
|
|
||||||
|
The LABEL, PASS, CREATE, LENGTH, ALGO and SEQNO arguments have
|
||||||
|
the same meanings as when passed to `dispass-start-process'.
|
||||||
|
|
||||||
|
The result is put in the `kill-ring'."
|
||||||
|
(kill-new
|
||||||
|
(funcall (dispass--get-passphrase-matcher label)
|
||||||
|
(dispass-start-process "generate" label pass create length
|
||||||
|
algo seqno)))
|
||||||
|
(message "Passphrase copied to kill ring"))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun dispass-create (label &optional length algo seqno)
|
(defun dispass-create (label pass &optional length algo seqno)
|
||||||
"Create a new password for LABEL.
|
"Create a new password for LABEL using PASS.
|
||||||
|
|
||||||
Optionally also specify to make the passphrase LENGTH long, use
|
Optionally also specify to make the passphrase LENGTH long, use
|
||||||
the ALGO algorithm with sequence number SEQNO."
|
the ALGO algorithm with sequence number SEQNO."
|
||||||
(interactive (list
|
(interactive (list
|
||||||
(read-from-minibuffer "Label: ")
|
(read-from-minibuffer "Label: ")
|
||||||
|
(dispass--verified-password)
|
||||||
current-prefix-arg
|
current-prefix-arg
|
||||||
(completing-read "Algorithm: " dispass-algorithms)
|
(completing-read "Algorithm: " dispass-algorithms)
|
||||||
(read-from-minibuffer
|
(read-from-minibuffer
|
||||||
"Sequence no. (1): " nil nil t nil "1")))
|
"Sequence no. (1): " nil nil t nil "1")))
|
||||||
(let ((length (or length dispass-default-length)))
|
(let ((length (or length dispass-default-length)))
|
||||||
(dispass-start-process "generate" label t length algo seqno)))
|
(dispass--generate label pass t length algo seqno)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun dispass (label &optional length algo seqno)
|
(defun dispass (label pass &optional length algo seqno)
|
||||||
"Recreate a passphrase for LABEL.
|
"Recreate a passphrase for LABEL using PASS.
|
||||||
|
|
||||||
Optionally also specify to make the passphrase LENGTH long, use
|
Optionally also specify to make the passphrase LENGTH long, use
|
||||||
the ALGO algorithm with sequence number SEQNO. This is useful
|
the ALGO algorithm with sequence number SEQNO. This is useful
|
||||||
|
@ -236,6 +223,7 @@ not to have LABEL added to your labelfile for some other reason."
|
||||||
(interactive (list
|
(interactive (list
|
||||||
(completing-read
|
(completing-read
|
||||||
"Label: " (dispass-get-labels))
|
"Label: " (dispass-get-labels))
|
||||||
|
(read-passwd "Password: ")
|
||||||
current-prefix-arg))
|
current-prefix-arg))
|
||||||
(when (and (called-interactively-p 'any)
|
(when (and (called-interactively-p 'any)
|
||||||
(not (member label (dispass-get-labels))))
|
(not (member label (dispass-get-labels))))
|
||||||
|
@ -243,8 +231,7 @@ not to have LABEL added to your labelfile for some other reason."
|
||||||
(setq seqno (read-from-minibuffer
|
(setq seqno (read-from-minibuffer
|
||||||
"Sequence no. (1): " nil nil t nil "1")))
|
"Sequence no. (1): " nil nil t nil "1")))
|
||||||
(let ((length (or length dispass-default-length)))
|
(let ((length (or length dispass-default-length)))
|
||||||
(dispass-start-process
|
(dispass--generate label pass nil length algo seqno)))
|
||||||
"generate" label nil length algo seqno)))
|
|
||||||
|
|
||||||
;; Labels management
|
;; Labels management
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
|
Loading…
Reference in a new issue