view lisp/net/sasl.el @ 110121:5a6b4fafaa52

Sync with Tramp 2.1.19. * net/tramp-cmds.el (tramp-cleanup-all-connections) (tramp-reporter-dump-variable, tramp-load-report-modules) (tramp-append-tramp-buffers): Use `tramp-compat-funcall'. (tramp-bug): Recommend setting of `tramp-verbose' to 9. * net/tramp-compat.el (top): Do not autoload `tramp-handle-file-remote-p'. Load tramp-util.el and tramp-vc.el only when `start-file-process' is not bound. (byte-compile-not-obsolete-vars): Define if not bound. (tramp-compat-funcall): New defmacro. (tramp-compat-line-beginning-position) (tramp-compat-line-end-position) (tramp-compat-temporary-file-directory) (tramp-compat-make-temp-file, tramp-compat-file-attributes) (tramp-compat-copy-file, tramp-compat-copy-directory) (tramp-compat-delete-file, tramp-compat-delete-directory) (tramp-compat-number-sequence, tramp-compat-process-running-p): Use it. (tramp-advice-file-expand-wildcards): Do not use `tramp-handle-file-remote-p'. (tramp-compat-make-temp-file): Simplify fallback implementation. (tramp-compat-copy-file): Add PRESERVE-SELINUX-CONTEXT. (tramp-compat-copy-tree): Remove function. (tramp-compat-delete-file): New defun. (tramp-compat-delete-directory): Provide implementation for older Emacsen. (tramp-compat-file-attributes): Handle only `wrong-number-of-arguments' error. * net/tramp-fish.el (tramp-fish-handle-copy-file): Add PRESERVE_SELINUX_CONTEXT. (tramp-fish-handle-delete-file): Add TRASH arg. (tramp-fish-handle-directory-files-and-attributes): Do not use `tramp-fish-handle-file-attributes. (tramp-fish-handle-file-local-copy) (tramp-fish-handle-insert-file-contents) (tramp-fish-maybe-open-connection): Use `with-progress-reporter'. * net/tramp-gvfs.el (top): Require url-util. (tramp-gvfs-mount-point): Remove. (tramp-gvfs-file-name-handler-alist): Add `file-selinux-context' and `set-file-selinux-context'. (tramp-gvfs-stringify-dbus-message, tramp-gvfs-send-command) (tramp-gvfs-handle-file-selinux-context) (tramp-gvfs-handle-set-file-selinux-context): New defuns. (with-tramp-dbus-call-method): Format trace message. (tramp-gvfs-handle-copy-file): Handle PRESERVE-SELINUX-CONTEXT. (tramp-gvfs-handle-copy-file, tramp-gvfs-handle-rename-file): Implement backup call, when operation on local files fails. Use progress reporter. Flush properties of changed files. (tramp-gvfs-handle-delete-file): Add TRASH arg. Use `tramp-compat-delete-file'. (tramp-gvfs-handle-expand-file-name): Expand "~/". (tramp-gvfs-handle-make-directory): Make more traces. (tramp-gvfs-handle-write-region): Protect deleting tmpfile. (tramp-gvfs-url-file-name): Hexify file name in url. (tramp-gvfs-fuse-file-name): Take also prefix (like dav shares) into account for the resulting file name. (tramp-gvfs-handler-askquestion): Preserve current message, in order to let progress reporter continue afterwards. (Bug#6257) Return dummy mountpoint, when the answer is "no". See `tramp-gvfs-maybe-open-connection'. (tramp-gvfs-handler-mounted-unmounted) (tramp-gvfs-connection-mounted-p): Test also for new mountspec attribute "default_location". Set "prefix" property. Handle default-location. (tramp-gvfs-mount-spec): Return both prefix and mountspec. (tramp-gvfs-maybe-open-connection): Test, whether mountpoint exists. Raise an error, if not (due to a corresponding answer "no" in interactive questions, for example). Use `tramp-compat-funcall'. * net/tramp-imap.el (top): Autoload `epg-make-context'. (tramp-imap-handle-copy-file): Add PRESERVE-SELINUX-CONTEXT. (tramp-imap-do-copy-or-rename-file) (tramp-imap-handle-insert-file-contents) (tramp-imap-handle-file-local-copy): Use `with-progress-reporter'. (tramp-imap-handle-delete-file): Add TRASH arg. * net/tramp-smb.el (tramp-smb-handle-copy-file): Add PRESERVE-SELINUX-CONTEXT. (tramp-smb-handle-copy-file) (tramp-smb-handle-file-local-copy, tramp-smb-handle-rename-file) (tramp-smb-handle-write-region, tramp-smb-maybe-open-connection): Use `with-progress-reporter'. (tramp-smb-handle-delete-file): Add TRASH arg. * net/tramp.el (tramp-methods): Move hostname to the end in all ssh `tramp-login-args'. Add `tramp-async-args' attribute where appropriate. (tramp-verbose): Describe verbose level 9. (tramp-completion-function-alist) (tramp-file-name-regexp, tramp-chunksize) (tramp-local-coding-commands, tramp-remote-coding-commands) (with-connection-property, tramp-completion-mode-p) (tramp-action-process-alive, tramp-action-out-of-band) (tramp-check-for-regexp, tramp-file-name-p, tramp-equal-remote) (tramp-exists-file-name-handler): Fix docstring. (tramp-remote-process-environment): Use `format' instead of `concat'. Protect version string by apostroph. (tramp-shell-prompt-pattern): Do not use a shy group in case of XEmacs. (tramp-file-name-regexp-unified) (tramp-completion-file-name-regexp-unified): On W32 systems, do not regard the volume letter as remote filename. (Bug#5447) (tramp-perl-file-attributes) (tramp-perl-directory-files-and-attributes): Don't pass "$3". (tramp-vc-registered-read-file-names): Read input as here-document, otherwise the command could exceed maximum length of command line. (tramp-file-name-handler-alist): Add `file-selinux-context' and `set-file-selinux-context'. (tramp-debug-message): Add `tramp-compat-funcall' to ignored backtrace functions. (tramp-error-with-buffer): Don't show the connection buffer when we are in completion mode. (tramp-progress-reporter-update, tramp-remote-selinux-p) (tramp-handle-file-selinux-context) (tramp-handle-set-file-selinux-context, tramp-process-sentinel) (tramp-connectable-p, tramp-open-shell, tramp-get-remote-trash): New defuns. (with-progress-reporter): New defmacro. (tramp-debug-outline-regexp): New defconst. (top, tramp-rfn-eshadow-setup-minibuffer) (tramp-rfn-eshadow-update-overlay, tramp-handle-set-file-times) (tramp-handle-dired-compress-file, tramp-handle-shell-command) (tramp-completion-mode-p, tramp-check-for-regexp) (tramp-open-connection-setup-interactive-shell) (tramp-compute-multi-hops, tramp-read-passwd, tramp-clear-passwd) (tramp-time-diff, tramp-coding-system-change-eol-conversion) (tramp-set-process-query-on-exit-flag, tramp-unload-tramp): Use `tramp-compat-funcall'. (tramp-handle-make-symbolic-link): Flush file properties. (tramp-handle-load, tramp-handle-file-local-copy) (tramp-handle-insert-file-contents, tramp-handle-write-region) (tramp-handle-vc-registered, tramp-maybe-send-script) (tramp-find-shell): Use `with-progress-reporter'. (tramp-do-file-attributes-with-stat): Add space in format string, in order to work around a bug in pdksh. Reported by Gilles Pion <gpion@lfdj.com>. (tramp-handle-verify-visited-file-modtime): Do not send a command when the connection is not established. (tramp-handle-set-file-times): Simplify the check for utc. (tramp-handle-directory-files-and-attributes) (tramp-get-remote-path): Use `copy-tree'. (tramp-completion-handle-file-name-all-completions): Ensure, that non remote files are still checked. Oops. (tramp-handle-copy-file, tramp-do-copy-or-rename-file): Handle PRESERVE-SELINUX-CONTEXT. (tramp-do-copy-or-rename-file): Add progress reporter. (tramp-do-copy-or-rename-file-directly): Do not use `tramp-handle-file-remote-p'. (tramp-do-copy-or-rename-file-out-of-band): Use `tramp-compat-delete-directory'. (tramp-do-copy-or-rename-file-out-of-band) (tramp-compute-multi-hops, tramp-maybe-open-connection): Use `format-spec-make'. (tramp-handle-delete-file): Add TRASH arg. (tramp-handle-dired-uncache): Flush directory cache, not only file cache. (tramp-handle-expand-file-name) (tramp-completion-handle-file-name-all-completions) (tramp-completion-handle-file-name-completion): Use `tramp-connectable-p'. (tramp-handle-start-file-process): Set connection property "vec". Use it, in order to invalidate file caches. Check only for `remote-tty' process property. Implement tty setting. (Bug#4604, Bug#6360) (tramp-file-name-for-operation): Add `call-process-region' and `set-file-selinux-context'. (tramp-find-foreign-file-name-handler) (tramp-advice-make-auto-save-file-name) (tramp-set-auto-save-file-modes): Remove superfluous check for `stringp'. This is done inside `tramp-tramp-file-p'. (tramp-file-name-handler): Trace 'quit. Catch the error for some operations when we are in completion mode. This gives the user the chance to correct the file name in the minibuffer. (tramp-completion-mode-p): Use `non-essential'. (tramp-handle-file-name-all-completions): Backward/ XEmacs compatibility: Use `completion-ignore-case' if `read-file-name-completion-ignore-case' does not exist. (tramp-get-debug-buffer): Use `tramp-debug-outline-regexp'. (tramp-find-shell, tramp-open-connection-setup-interactive-shell): `tramp-open-shell'. (tramp-action-password): Hide password prompt before next run. (tramp-process-actions): Widen connection buffer for the trace. (tramp-open-connection-setup-interactive-shell): Set `remote-tty' process property. Trace stty settings if `tramp-verbose' >= 9. Apply workaround for IRIX64 bug. Move argument of last `tramp-send-command' where it belongs to. (tramp-maybe-open-connection): Use `async-args' and `gw-args' in front of `login-args'. (tramp-get-ls-command, tramp-get-ls-command-with-dired): Run tests on "/dev/null" instead of "/". (tramp-get-ls-command-with-dired): Make test for "--dired" stronger. (tramp-set-auto-save-file-modes): Adapt version check. (tramp-set-process-query-on-exit-flag): Fix wrong parentheses. (tramp-handle-process-file): Call the program in a subshell, in order to preserve working directory. (tramp-handle-shell-command): Don't use hard-wired "/bin/sh" but `tramp-remote-sh' from `tramp-methods'. (tramp-get-ls-command): Make test for "--color=never" stronger. (tramp-check-for-regexp): Use (forward-line 1). * net/trampver.el: Update release number. * net/tramp-gvfs.el (tramp-gvfs-handle-copy-file): Do not pass empty argument to gvfs-copy. * net/tramp-compat.el (tramp-compat-delete-file): Rewrite to handle new TRASH arg of `delete-file'. * net/tramp.el (tramp-handle-insert-directory): Don't use `forward-word', its default syntax could be changed. Implement compression for inline methods. * net/tramp.el (tramp-inline-compress-start-size): New defcustom. (tramp-copy-size-limit): Allow also nil. (tramp-inline-compress-commands): New defconst. (tramp-find-inline-compress, tramp-get-inline-compress) (tramp-get-inline-coding): New defuns. (tramp-get-remote-coding, tramp-get-local-coding): Remove, replaced by `tramp-get-inline-coding'. (tramp-handle-file-local-copy, tramp-handle-write-region) (tramp-method-out-of-band-p): Use `tramp-get-inline-coding'. Detect ssh 'ControlMaster' argument automatically in some cases. * net/tramp.el (tramp-detect-ssh-controlmaster): New defun. (tramp-default-method): Use it. * net/tramp.el (tramp-file-name-for-operation): Add file-selinux-context.
author Michael Albinus <michael.albinus@gmx.de>
date Thu, 26 Aug 2010 21:23:02 +0200
parents 1d1d5d9bd884
children 8d09094063d0 376148b31b5e
line wrap: on
line source

;;; sasl.el --- SASL client framework

;; Copyright (C) 2000, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.

;; Author: Daiki Ueno <ueno@unixuser.org>
;; Keywords: SASL

;; This file is part of GNU Emacs.

;; GNU Emacs 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 3 of the License, or
;; (at your option) any later version.

;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; This module provides common interface functions to share several
;; SASL mechanism drivers.  The toplevel is designed to be mostly
;; compatible with [Java-SASL].
;;
;; [SASL] J. Myers, "Simple Authentication and Security Layer (SASL)",
;;	RFC 2222, October 1997.
;;
;; [Java-SASL] R. Weltman & R. Lee, "The Java SASL Application Program
;;	Interface", draft-weltman-java-sasl-03.txt, March 2000.

;;; Code:

(defvar sasl-mechanisms
  '("CRAM-MD5" "DIGEST-MD5" "PLAIN" "LOGIN" "ANONYMOUS"
    "NTLM" "SCRAM-MD5"))

(defvar sasl-mechanism-alist
  '(("CRAM-MD5" sasl-cram)
    ("DIGEST-MD5" sasl-digest)
    ("PLAIN" sasl-plain)
    ("LOGIN" sasl-login)
    ("ANONYMOUS" sasl-anonymous)
    ("NTLM" sasl-ntlm)
    ("SCRAM-MD5" sasl-scram)))

(defvar sasl-unique-id-function #'sasl-unique-id-function)

(put 'sasl-error 'error-message "SASL error")
(put 'sasl-error 'error-conditions '(sasl-error error))

(defun sasl-error (datum)
  (signal 'sasl-error (list datum)))

;;; @ SASL client
;;;

(defun sasl-make-client (mechanism name service server)
  "Return a newly allocated SASL client.
NAME is name of the authorization.  SERVICE is name of the service desired.
SERVER is the fully qualified host name of the server to authenticate to."
  (vector mechanism name service server (make-symbol "sasl-client-properties")))

(defun sasl-client-mechanism (client)
  "Return the authentication mechanism driver of CLIENT."
  (aref client 0))

(defun sasl-client-name (client)
  "Return the authorization name of CLIENT, a string."
  (aref client 1))

(defun sasl-client-service (client)
  "Return the service name of CLIENT, a string."
  (aref client 2))

(defun sasl-client-server (client)
  "Return the server name of CLIENT, a string."
  (aref client 3))

(defun sasl-client-set-properties (client plist)
  "Destructively set the properties of CLIENT.
The second argument PLIST is the new property list."
  (setplist (aref client 4) plist))

(defun sasl-client-set-property (client property value)
  "Add the given PROPERTY/VALUE to CLIENT."
  (put (aref client 4) property value))

(defun sasl-client-property (client property)
  "Return the value of the PROPERTY of CLIENT."
  (get (aref client 4) property))

(defun sasl-client-properties (client)
  "Return the properties of CLIENT."
  (symbol-plist (aref client 4)))

;;; @ SASL mechanism
;;;

(defun sasl-make-mechanism (name steps)
  "Make an authentication mechanism.
NAME is a IANA registered SASL mechanism name.
STEPS is list of continuation functions."
  (vector name
	  (mapcar
	   (lambda (step)
	     (let ((symbol (make-symbol (symbol-name step))))
	       (fset symbol (symbol-function step))
	       symbol))
	   steps)))

(defun sasl-mechanism-name (mechanism)
  "Return name of MECHANISM, a string."
  (aref mechanism 0))

(defun sasl-mechanism-steps (mechanism)
  "Return the authentication steps of MECHANISM, a list of functions."
  (aref mechanism 1))

(defun sasl-find-mechanism (mechanisms)
  "Retrieve an appropriate mechanism object from MECHANISMS hints."
  (let* ((sasl-mechanisms sasl-mechanisms)
	 (mechanism
	  (catch 'done
	    (while sasl-mechanisms
	      (if (member (car sasl-mechanisms) mechanisms)
		  (throw 'done (nth 1 (assoc (car sasl-mechanisms)
					     sasl-mechanism-alist))))
	      (setq sasl-mechanisms (cdr sasl-mechanisms))))))
    (if mechanism
	(require mechanism))
    (get mechanism 'sasl-mechanism)))

;;; @ SASL authentication step
;;;

(defun sasl-step-data (step)
  "Return the data which STEP holds, a string."
  (aref step 1))

(defun sasl-step-set-data (step data)
  "Store DATA string to STEP."
  (aset step 1 data))

(defun sasl-next-step (client step)
  "Evaluate the challenge and prepare an appropriate next response.
The data type of the value and 2nd argument STEP is nil or opaque
authentication step which holds the reference to the next action and
the current challenge.  At the first time STEP should be set to nil."
  (let* ((steps
	  (sasl-mechanism-steps
	   (sasl-client-mechanism client)))
	 (function
	  (if (vectorp step)
	      (nth 1 (memq (aref step 0) steps))
	    (car steps))))
    (if function
	(vector function (funcall function client step)))))

(defvar sasl-read-passphrase nil)
(defun sasl-read-passphrase (prompt)
  (if (not sasl-read-passphrase)
      (if (functionp 'read-passwd)
	  (setq sasl-read-passphrase 'read-passwd)
	(if (load "passwd" t)
	    (setq sasl-read-passphrase 'read-passwd)
	  (autoload 'ange-ftp-read-passwd "ange-ftp")
	  (setq sasl-read-passphrase 'ange-ftp-read-passwd))))
  (funcall sasl-read-passphrase prompt))

(defun sasl-unique-id ()
  "Compute a data string which must be different each time.
It contain at least 64 bits of entropy."
  (concat (funcall sasl-unique-id-function)(funcall sasl-unique-id-function)))

(defvar sasl-unique-id-char nil)

;; stolen (and renamed) from message.el
(defun sasl-unique-id-function ()
  ;; Don't use microseconds from (current-time), they may be unsupported.
  ;; Instead we use this randomly inited counter.
  (setq sasl-unique-id-char
	(% (1+ (or sasl-unique-id-char (logand (random t) (1- (lsh 1 20)))))
	   ;; (current-time) returns 16-bit ints,
	   ;; and 2^16*25 just fits into 4 digits i base 36.
	   (* 25 25)))
  (let ((tm (current-time)))
    (concat
     (sasl-unique-id-number-base36
      (+ (car   tm)
	 (lsh (% sasl-unique-id-char 25) 16)) 4)
     (sasl-unique-id-number-base36
      (+ (nth 1 tm)
	 (lsh (/ sasl-unique-id-char 25) 16)) 4))))

(defun sasl-unique-id-number-base36 (num len)
  (if (if (< len 0)
	  (<= num 0)
	(= len 0))
      ""
    (concat (sasl-unique-id-number-base36 (/ num 36) (1- len))
	    (char-to-string (aref "zyxwvutsrqponmlkjihgfedcba9876543210"
				  (% num 36))))))

;;; PLAIN (RFC2595 Section 6)
(defconst sasl-plain-steps
  '(sasl-plain-response))

(defun sasl-plain-response (client step)
  (let ((passphrase
	 (sasl-read-passphrase
	  (format "PLAIN passphrase for %s: " (sasl-client-name client))))
	(authenticator-name
	 (sasl-client-property
	  client 'authenticator-name))
	(name (sasl-client-name client)))
    (unwind-protect
	(if (and authenticator-name
		 (not (string= authenticator-name name)))
	    (concat authenticator-name "\0" name "\0" passphrase)
	  (concat "\0" name "\0" passphrase))
      (fillarray passphrase 0))))

(put 'sasl-plain 'sasl-mechanism
     (sasl-make-mechanism "PLAIN" sasl-plain-steps))

(provide 'sasl-plain)

;;; LOGIN (No specification exists)
(defconst sasl-login-steps
  '(ignore				;no initial response
    sasl-login-response-1
    sasl-login-response-2))

(defun sasl-login-response-1 (client step)
;;;  (unless (string-match "^Username:" (sasl-step-data step))
;;;    (sasl-error (format "Unexpected response: %s" (sasl-step-data step))))
  (sasl-client-name client))

(defun sasl-login-response-2 (client step)
;;;  (unless (string-match "^Password:" (sasl-step-data step))
;;;    (sasl-error (format "Unexpected response: %s" (sasl-step-data step))))
  (sasl-read-passphrase
   (format "LOGIN passphrase for %s: " (sasl-client-name client))))

(put 'sasl-login 'sasl-mechanism
     (sasl-make-mechanism "LOGIN" sasl-login-steps))

(provide 'sasl-login)

;;; ANONYMOUS (RFC2245)
(defconst sasl-anonymous-steps
  '(ignore				;no initial response
    sasl-anonymous-response))

(defun sasl-anonymous-response (client step)
  (or (sasl-client-property client 'trace)
      (sasl-client-name client)))

(put 'sasl-anonymous 'sasl-mechanism
     (sasl-make-mechanism "ANONYMOUS" sasl-anonymous-steps))

(provide 'sasl-anonymous)

(provide 'sasl)

;; arch-tag: 8b3326fa-4978-4fda-93e2-cb2c6255f887
;;; sasl.el ends here