aboutsummaryrefslogtreecommitdiffstats
path: root/dispass.el
blob: b4a7485e539a137a3703dc1a7fdf63672cd58524 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
;;; dispass.el --- Generate and disperse/dispell passwords

;; Copyright (C) 2012 Tom Willemsen <tom@ryuslash.org>

;; Author: Tom Willemsen <tom@ryuslash.org>
;; Created: Jun 8, 2012
;; Version: 0.1a7.2
;; Keywords: encryption, security

;; Permission to use, copy, modify, and distribute this software for any
;; purpose with or without fee is hereby granted, provided that the
;; above copyright notice and this permission notice appear in all
;; copies.

;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
;; WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
;; WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
;; AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
;; CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
;; OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
;; NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
;; CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

;;; Commentary:

;; dispass.el is an emacs wrapper around dispass
;; (http://dispass.babab.nl).

;;; Installation:

;; Place this file somewhere on your filesystem, either in your
;; `load-path' or somewhere else which you will have to add to your
;; `load-path', like so:

;;     (add-to-list 'load-path "/location/of/dispass.el")

;; And then `load', `require' or `autoload' it in your emacs init
;; file, for example:

;;     (require 'dispass)

;; _Or_ if you have package.el you could use `package-install-file'.

;;; Usage:

;; Using dispass.el is simple, once installed. Either call `dispass'
;; to recall a priviously generated password or call `dispass-create'
;; to generate a new password.

;; The only real difference between the two is that `dispass-create'
;; asks to confirm the password. Both will ask for a label.

;; Once a password has been generated it is inserted into the kill
;; ring and the system's clipboard so it can be easily inserted into
;; password field, this makes the generated password easy to see in
;; plaintext in the `kill-ring' variable, though.

;;; Change Log:

;; 0.1a7 - Initial release.

;; 0.1a7.1 - Don't show password, copy directly into the clipboard.

;; 0.1a7.2 - Kill buffer whenever we're finished with it.

;;; Code:

(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" (substring status 0 -1)))

    (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-process-filter-for (label)
  "Create a function that will process any lines whilst keeping
an eye out for LABEL."
  `(lambda (proc string)
     "Process STRING coming from PROC."
     (cond ((string-match "^\\(Password\\|Again\\): ?$" string)
            (process-send-string proc
                                 (concat (read-passwd string nil) "\n")))

           ((string-match (concat "^[ ]+" ,label " \\(.\\{30\\}\\)$")
                          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.")

                (unless (eq (process-status proc) 'run)
                  (kill-buffer buffer))))))))

(defun dispass-start-process (label &optional create)
  "Start dispass process. When CREATE is non-nil send along the
  -c switch to make it ask for a password twice."
  (let ((proc (start-process "dispass" "*dispass*" "dispass"
                             (if create "-co" "-o") label)))
    (set-process-sentinel proc 'dispass-process-sentinel)
    (set-process-filter proc (dispass-process-filter-for label))))

;;;###autoload
(defun dispass-create (label)
  (interactive "MLabel: ")
  "Create a new password for LABEL."
  (dispass-start-process label t))

;;;###autoload
(defun dispass (label)
  (interactive "MLabel: ")
  "Recreate a password previously used."
  (dispass-start-process label))

(provide 'dispass)

;;; dispass.el ends here