summaryrefslogtreecommitdiff
path: root/lisp/vm-crypto.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/vm-crypto.el')
-rwxr-xr-xlisp/vm-crypto.el230
1 files changed, 230 insertions, 0 deletions
diff --git a/lisp/vm-crypto.el b/lisp/vm-crypto.el
new file mode 100755
index 0000000..2213c3a
--- /dev/null
+++ b/lisp/vm-crypto.el
@@ -0,0 +1,230 @@
+;;; vm-crypto.el --- Encryption and related functions for VM
+;;
+;; This file is part of VM
+;;
+;; Copyright (C) 2001 Kyle E. Jones
+;; Copyright (C) 2003-2006 Robert Widhopf-Fenk
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License along
+;; with this program; if not, write to the Free Software Foundation, Inc.,
+;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+;;; Code:
+
+(provide 'vm-crypto)
+
+(eval-when-compile
+ (require 'vm-misc)
+ (require 'vm-folder)
+ )
+
+;; compatibility
+(fset 'vm-pop-md5 'vm-md5-string)
+
+;;;###autoload
+(defun vm-md5-region (start end)
+ (if (fboundp 'md5)
+ (md5 (current-buffer) start end)
+ (let ((buffer nil)
+ (retval nil)
+ (curbuf (current-buffer)))
+ (unwind-protect
+ (save-excursion
+ (setq buffer (vm-make-work-buffer))
+ (set-buffer buffer)
+ (insert-buffer-substring curbuf start end)
+ ;; call-process-region calls write-region.
+ ;; don't let it do CR -> LF translation.
+ (setq selective-display nil)
+ (setq retval
+ (call-process-region (point-min) (point-max)
+ vm-pop-md5-program
+ t buffer nil))
+ (if (not (equal retval 0))
+ (progn
+ (error "%s failed: exited with code %s"
+ vm-pop-md5-program retval)))
+ ;; md5sum generates extra output even when summing stdin.
+ (goto-char (point-min))
+ (if (re-search-forward " [ *]?-\n" nil t)
+ (replace-match ""))
+
+ (goto-char (point-min))
+ (if (or (re-search-forward "[^0-9a-f\n]" nil t)
+ (< (point-max) 32))
+ (error "%s produced bogus MD5 digest '%s'"
+ vm-pop-md5-program
+ (vm-buffer-substring-no-properties (point-min)
+ (point-max))))
+ ;; MD5 digest is 32 chars long
+ ;; mddriver adds a newline to make neaten output for tty
+ ;; viewing, make sure we leave it behind.
+ (vm-buffer-substring-no-properties (point-min) (+ (point-min) 32)))
+ (and buffer (kill-buffer buffer))))))
+
+;; output is in hex
+;;;###autoload
+(defun vm-md5-string (string)
+ (if (fboundp 'md5)
+ (md5 string)
+ (vm-with-string-as-temp-buffer
+ string (function
+ (lambda ()
+ (goto-char (point-min))
+ (insert (vm-md5-region (point-min) (point-max)))
+ (delete-region (point) (point-max)))))))
+
+;; output is the raw digest bits, not hex
+;;;###autoload
+(defun vm-md5-raw-string (s)
+ (setq s (vm-md5-string s))
+ (let ((raw (make-string 16 0))
+ (i 0) n
+ (hex-digit-alist '((?0 . 0) (?1 . 1) (?2 . 2) (?3 . 3)
+ (?4 . 4) (?5 . 5) (?6 . 6) (?7 . 7)
+ (?8 . 8) (?9 . 9) (?A . 10) (?B . 11)
+ (?C . 12) (?D . 13) (?E . 14) (?F . 15)
+ ;; some mailer uses lower-case hex
+ ;; digits despite this being forbidden
+ ;; by the MIME spec.
+ (?a . 10) (?b . 11) (?c . 12) (?d . 13)
+ (?e . 14) (?f . 15))))
+ (while (< i 32)
+ (setq n (+ (* (cdr (assoc (aref s i) hex-digit-alist)) 16)
+ (cdr (assoc (aref s (1+ i)) hex-digit-alist))))
+ (aset raw (/ i 2) n)
+ (setq i (+ i 2)))
+ raw ))
+
+;;;###autoload
+(defun vm-xor-string (s1 s2)
+ (let ((len (length s1))
+ result (i 0))
+ (if (/= len (length s2))
+ (error "strings not of equal length"))
+ (setq result (make-string len 0))
+ (while (< i len)
+ (aset result i (logxor (aref s1 i) (aref s2 i)))
+ (setq i (1+ i)))
+ result ))
+
+;;;###autoload
+(defun vm-setup-ssh-tunnel (host port)
+ (let (local-port process done)
+ (while (not done)
+ (setq local-port (+ 1025 (random (- 65536 1025)))
+ process nil)
+ (condition-case nil
+ (progn
+ (setq process
+ (open-network-stream "TEST-CONNECTION" nil
+ "127.0.0.1" local-port))
+ (vm-process-kill-without-query process))
+ (error nil))
+ (cond ((null process)
+ (setq process
+ (apply 'start-process
+ (format "SSH tunnel to %s:%s" host port)
+ (vm-make-work-buffer)
+ vm-ssh-program
+ (nconc
+ (list "-L"
+ (format "%d:%s:%s" local-port host port))
+ (copy-sequence vm-ssh-program-switches)
+ (list host vm-ssh-remote-command)))
+ done t)
+ (vm-process-kill-without-query process)
+ (set-process-sentinel process 'vm-process-sentinel-kill-buffer))
+ (t
+ (delete-process process))))
+
+ ;; wait for some output from vm-ssh-remote-command. this
+ ;; ensures that when we return the ssh connection is ready to
+ ;; do port-forwarding.
+ (accept-process-output process)
+
+ local-port ))
+
+(defun vm-generate-random-data-file (n-octets)
+ (let ((file (vm-make-tempfile))
+ work-buffer (i n-octets))
+ (unwind-protect
+ (save-excursion
+ (setq work-buffer (vm-make-work-buffer))
+ (set-buffer work-buffer)
+ (while (> i 0)
+ (insert-char (random 256) 1)
+ (setq i (1- i)))
+ (write-region (point-min) (point-max) file nil 0))
+ (and work-buffer (kill-buffer work-buffer)))
+ file ))
+
+;;;###autoload
+(defun vm-setup-stunnel-random-data-if-needed ()
+ (cond ((null vm-stunnel-random-data-method) nil)
+ ((eq vm-stunnel-random-data-method 'generate)
+ (if (and (stringp vm-stunnel-random-data-file)
+ (file-readable-p vm-stunnel-random-data-file))
+ nil
+ (setq vm-stunnel-random-data-file
+ (vm-generate-random-data-file (* 4 1024)))))))
+
+;;;###autoload
+(defun vm-tear-down-stunnel-random-data ()
+ (if (stringp vm-stunnel-random-data-file)
+ (vm-error-free-call 'delete-file vm-stunnel-random-data-file))
+ (setq vm-stunnel-random-data-file nil))
+
+(defun vm-stunnel-random-data-args ()
+ (cond ((null vm-stunnel-random-data-method) nil)
+ ((eq vm-stunnel-random-data-method 'generate)
+ (list "-R" vm-stunnel-random-data-file))
+ (t nil)))
+
+;;;###autoload
+(defun vm-stunnel-configuration-args (host port)
+ (if (eq vm-stunnel-wants-configuration-file 'unknown)
+ (setq vm-stunnel-wants-configuration-file
+ (not (eq (call-process vm-stunnel-program nil nil nil "-h") 0))))
+ (if (not vm-stunnel-wants-configuration-file)
+ (nconc (vm-stunnel-random-data-args)
+ (list "-W" "-c" "-r"
+ (format "%s:%s" host port)))
+ (let ((work-buffer nil)
+ (workfile (vm-stunnel-configuration-file)))
+ (unwind-protect
+ (save-excursion
+ (setq work-buffer (vm-make-work-buffer))
+ (set-buffer work-buffer)
+ (if (and vm-stunnel-program-additional-configuration-file
+ (stringp vm-stunnel-program-additional-configuration-file)
+ (file-readable-p
+ vm-stunnel-program-additional-configuration-file))
+ (insert-file-contents
+ vm-stunnel-program-additional-configuration-file))
+ (insert "client = yes\n")
+ (insert "RNDfile = " vm-stunnel-random-data-file "\n")
+ (insert "RNDoverwrite = no\n")
+ (insert "connect = " (format "%s:%s" host port) "\n")
+ (write-region (point-min) (point-max) workfile nil 0))
+ (and work-buffer (kill-buffer work-buffer)))
+ (list workfile) )))
+
+(defun vm-stunnel-configuration-file ()
+ (if vm-stunnel-configuration-file
+ vm-stunnel-configuration-file
+ (setq vm-stunnel-configuration-file (vm-make-tempfile))
+ (vm-register-global-garbage-files (list vm-stunnel-configuration-file))
+ vm-stunnel-configuration-file))
+
+;;; vm-crypto.el ends here