1 ;;; vm-crypto.el --- Encryption and related functions for VM
3 ;; Copyright (C) 2001 Kyle E. Jones
4 ;; Copyright (C) 2003-2006 Robert Widhopf-Fenk
6 ;; This program is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2 of the License, or
9 ;; (at your option) any later version.
11 ;; This program is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License along
17 ;; with this program; if not, write to the Free Software Foundation, Inc.,
18 ;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 (fset 'vm-pop-md5 'vm-md5-string)
26 (defun vm-md5-region (start end)
28 (md5 (current-buffer) start end)
31 (curbuf (current-buffer)))
34 (setq buffer (vm-make-work-buffer))
36 (insert-buffer-substring curbuf start end)
37 ;; call-process-region calls write-region.
38 ;; don't let it do CR -> LF translation.
39 (setq selective-display nil)
41 (call-process-region (point-min) (point-max)
44 (if (not (equal retval 0))
46 (error "%s failed: exited with code %s"
47 vm-pop-md5-program retval)))
48 ;; md5sum generates extra output even when summing stdin.
49 (goto-char (point-min))
50 (if (re-search-forward " [ *]?-\n" nil t)
53 (goto-char (point-min))
54 (if (or (re-search-forward "[^0-9a-f\n]" nil t)
56 (error "%s produced bogus MD5 digest '%s'"
58 (vm-buffer-substring-no-properties (point-min)
60 ;; MD5 digest is 32 chars long
61 ;; mddriver adds a newline to make neaten output for tty
62 ;; viewing, make sure we leave it behind.
63 (vm-buffer-substring-no-properties (point-min) (+ (point-min) 32)))
64 (and buffer (kill-buffer buffer))))))
68 (defun vm-md5-string (string)
71 (vm-with-string-as-temp-buffer
74 (goto-char (point-min))
75 (insert (vm-md5-region (point-min) (point-max)))
76 (delete-region (point) (point-max)))))))
78 ;; output is the raw digest bits, not hex
80 (defun vm-md5-raw-string (s)
81 (setq s (vm-md5-string s))
82 (let ((raw (make-string 16 0))
84 (hex-digit-alist '((?0 . 0) (?1 . 1) (?2 . 2) (?3 . 3)
85 (?4 . 4) (?5 . 5) (?6 . 6) (?7 . 7)
86 (?8 . 8) (?9 . 9) (?A . 10) (?B . 11)
87 (?C . 12) (?D . 13) (?E . 14) (?F . 15)
88 ;; some mailer uses lower-case hex
89 ;; digits despite this being forbidden
91 (?a . 10) (?b . 11) (?c . 12) (?d . 13)
92 (?e . 14) (?f . 15))))
94 (setq n (+ (* (cdr (assoc (aref s i) hex-digit-alist)) 16)
95 (cdr (assoc (aref s (1+ i)) hex-digit-alist))))
101 (defun vm-xor-string (s1 s2)
102 (let ((len (length s1))
104 (if (/= len (length s2))
105 (error "strings not of equal length"))
106 (setq result (make-string len 0))
108 (aset result i (logxor (aref s1 i) (aref s2 i)))
113 (defun vm-setup-ssh-tunnel (host port)
114 (let (local-port process done)
116 (setq local-port (+ 1025 (random (- 65536 1025)))
121 (open-network-stream "TEST-CONNECTION" nil
122 "127.0.0.1" local-port))
123 (process-kill-without-query process))
125 (cond ((null process)
127 (apply 'start-process
128 (format "SSH tunnel to %s:%s" host port)
129 (vm-make-work-buffer)
133 (format "%d:%s:%s" local-port host port))
134 (copy-sequence vm-ssh-program-switches)
135 (list host vm-ssh-remote-command)))
137 (process-kill-without-query process)
138 (set-process-sentinel process 'vm-process-sentinel-kill-buffer))
140 (delete-process process))))
142 ;; wait for some output from vm-ssh-remote-command. this
143 ;; ensures that when we return the ssh connection is ready to
144 ;; do port-forwarding.
145 (accept-process-output process)
149 (defun vm-generate-random-data-file (n-octets)
150 (let ((file (vm-make-tempfile))
151 work-buffer (i n-octets))
154 (setq work-buffer (vm-make-work-buffer))
155 (set-buffer work-buffer)
157 (insert-char (random 256) 1)
159 (write-region (point-min) (point-max) file nil 0))
160 (and work-buffer (kill-buffer work-buffer)))
164 (defun vm-setup-stunnel-random-data-if-needed ()
165 (cond ((null vm-stunnel-random-data-method) nil)
166 ((eq vm-stunnel-random-data-method 'generate)
167 (if (and (stringp vm-stunnel-random-data-file)
168 (file-readable-p vm-stunnel-random-data-file))
170 (setq vm-stunnel-random-data-file
171 (vm-generate-random-data-file (* 4 1024)))))))
174 (defun vm-tear-down-stunnel-random-data ()
175 (if (stringp vm-stunnel-random-data-file)
176 (vm-error-free-call 'delete-file vm-stunnel-random-data-file))
177 (setq vm-stunnel-random-data-file nil))
179 (defun vm-stunnel-random-data-args ()
180 (cond ((null vm-stunnel-random-data-method) nil)
181 ((eq vm-stunnel-random-data-method 'generate)
182 (list "-R" vm-stunnel-random-data-file))
186 (defun vm-stunnel-configuration-args (host port)
187 (if (eq vm-stunnel-wants-configuration-file 'unknown)
188 (setq vm-stunnel-wants-configuration-file
189 (not (eq (call-process vm-stunnel-program nil nil nil "-h") 0))))
190 (if (not vm-stunnel-wants-configuration-file)
191 (nconc (vm-stunnel-random-data-args)
193 (format "%s:%s" host port)))
194 (let ((work-buffer nil)
195 (workfile (vm-stunnel-configuration-file)))
198 (setq work-buffer (vm-make-work-buffer))
199 (set-buffer work-buffer)
200 (if (and vm-stunnel-program-additional-configuration-file
201 (stringp vm-stunnel-program-additional-configuration-file)
203 vm-stunnel-program-additional-configuration-file))
204 (insert-file-contents
205 vm-stunnel-program-additional-configuration-file))
206 (insert "client = yes\n")
207 (insert "RNDfile = " vm-stunnel-random-data-file "\n")
208 (insert "RNDoverwrite = no\n")
209 (insert "connect = " (format "%s:%s" host port) "\n")
210 (write-region (point-min) (point-max) workfile nil 0))
211 (and work-buffer (kill-buffer work-buffer)))
214 (defun vm-stunnel-configuration-file ()
215 (if vm-stunnel-configuration-file
216 vm-stunnel-configuration-file
217 (setq vm-stunnel-configuration-file (vm-make-tempfile))
218 (vm-register-global-garbage-files (list vm-stunnel-configuration-file))
219 vm-stunnel-configuration-file))
223 ;;; vm-crypto.el ends here