diff options
| author | Julien Danjou | 2010-10-06 13:13:11 +0000 |
|---|---|---|
| committer | Katsumi Yamaoka | 2010-10-06 13:13:11 +0000 |
| commit | 1d8e1f787db65c09d7d2394d5644b63a3bd2f7df (patch) | |
| tree | 9e7588cfaeee568c25210947dc48949ccacb0be8 | |
| parent | 66627fa93ccb57773210dc8968f185140e008d30 (diff) | |
| download | emacs-1d8e1f787db65c09d7d2394d5644b63a3bd2f7df.tar.gz emacs-1d8e1f787db65c09d7d2394d5644b63a3bd2f7df.zip | |
sieve-manage: use auth-source.
| -rw-r--r-- | doc/misc/sieve.texi | 8 | ||||
| -rw-r--r-- | lisp/gnus/ChangeLog | 2 | ||||
| -rw-r--r-- | lisp/gnus/sieve-manage.el | 213 | ||||
| -rw-r--r-- | lisp/gnus/sieve.el | 16 |
4 files changed, 77 insertions, 162 deletions
diff --git a/doc/misc/sieve.texi b/doc/misc/sieve.texi index edf429aea77..b17c262b757 100644 --- a/doc/misc/sieve.texi +++ b/doc/misc/sieve.texi | |||
| @@ -264,10 +264,6 @@ in the @code{sieve} group (@kbd{M-x customize-group RET sieve RET}): | |||
| 264 | 264 | ||
| 265 | @table @code | 265 | @table @code |
| 266 | 266 | ||
| 267 | @item sieve-manage-default-user | ||
| 268 | @vindex sieve-manage-default-user | ||
| 269 | Sets the default username. | ||
| 270 | |||
| 271 | @item sieve-manage-default-port | 267 | @item sieve-manage-default-port |
| 272 | @vindex sieve-manage-default-port | 268 | @vindex sieve-manage-default-port |
| 273 | Sets the default port to use, the suggested port number is @code{2000}. | 269 | Sets the default port to use, the suggested port number is @code{2000}. |
| @@ -296,10 +292,6 @@ Check if a server is open or not. | |||
| 296 | @findex sieve-manage-close | 292 | @findex sieve-manage-close |
| 297 | Close a server connection. | 293 | Close a server connection. |
| 298 | 294 | ||
| 299 | @item sieve-manage-authenticate | ||
| 300 | @findex sieve-manage-authenticate | ||
| 301 | Authenticate to the server. | ||
| 302 | |||
| 303 | @item sieve-manage-capability | 295 | @item sieve-manage-capability |
| 304 | @findex sieve-manage-capability | 296 | @findex sieve-manage-capability |
| 305 | Return a list of capabilities the server supports. | 297 | Return a list of capabilities the server supports. |
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 3ef57f26e86..5e6a1e488f8 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog | |||
| @@ -77,6 +77,8 @@ | |||
| 77 | 77 | ||
| 78 | 2010-10-05 Julien Danjou <julien@danjou.info> | 78 | 2010-10-05 Julien Danjou <julien@danjou.info> |
| 79 | 79 | ||
| 80 | * sieve-manage.el (sieve-sasl-auth): Use auth-source to authenticate. | ||
| 81 | |||
| 80 | * gnus-html.el (gnus-html-wash-images): Rescale image from cid too. | 82 | * gnus-html.el (gnus-html-wash-images): Rescale image from cid too. |
| 81 | (gnus-html-maximum-image-size): Add this function. | 83 | (gnus-html-maximum-image-size): Add this function. |
| 82 | (gnus-html-put-image): Use gnus-html-maximum-image-size. | 84 | (gnus-html-put-image): Use gnus-html-maximum-image-size. |
diff --git a/lisp/gnus/sieve-manage.el b/lisp/gnus/sieve-manage.el index 69f21b0112f..370a53d4ac9 100644 --- a/lisp/gnus/sieve-manage.el +++ b/lisp/gnus/sieve-manage.el | |||
| @@ -43,7 +43,6 @@ | |||
| 43 | ;; `sieve-manage-close' | 43 | ;; `sieve-manage-close' |
| 44 | ;; close a server connection. | 44 | ;; close a server connection. |
| 45 | ;; | 45 | ;; |
| 46 | ;; `sieve-manage-authenticate' | ||
| 47 | ;; `sieve-manage-listscripts' | 46 | ;; `sieve-manage-listscripts' |
| 48 | ;; `sieve-manage-deletescript' | 47 | ;; `sieve-manage-deletescript' |
| 49 | ;; `sieve-manage-getscript' | 48 | ;; `sieve-manage-getscript' |
| @@ -51,11 +50,6 @@ | |||
| 51 | ;; | 50 | ;; |
| 52 | ;; and that's it. Example of a managesieve session in *scratch*: | 51 | ;; and that's it. Example of a managesieve session in *scratch*: |
| 53 | ;; | 52 | ;; |
| 54 | ;; (setq my-buf (sieve-manage-open "my.server.com")) | ||
| 55 | ;; " *sieve* my.server.com:2000*" | ||
| 56 | ;; | ||
| 57 | ;; (sieve-manage-authenticate "myusername" "mypassword" my-buf) | ||
| 58 | ;; 'auth | ||
| 59 | ;; | 53 | ;; |
| 60 | ;; (sieve-manage-listscripts my-buf) | 54 | ;; (sieve-manage-listscripts my-buf) |
| 61 | ;; ("vacation" "testscript" ("splitmail") "badscript") | 55 | ;; ("vacation" "testscript" ("splitmail") "badscript") |
| @@ -87,6 +81,7 @@ | |||
| 87 | (require 'starttls)) | 81 | (require 'starttls)) |
| 88 | (autoload 'sasl-find-mechanism "sasl") | 82 | (autoload 'sasl-find-mechanism "sasl") |
| 89 | (autoload 'starttls-open-stream "starttls") | 83 | (autoload 'starttls-open-stream "starttls") |
| 84 | (autoload 'auth-source-user-or-password "auth-source") | ||
| 90 | 85 | ||
| 91 | ;; User customizable variables: | 86 | ;; User customizable variables: |
| 92 | 87 | ||
| @@ -100,11 +95,6 @@ | |||
| 100 | :type 'string | 95 | :type 'string |
| 101 | :group 'sieve-manage) | 96 | :group 'sieve-manage) |
| 102 | 97 | ||
| 103 | (defcustom sieve-manage-default-user (user-login-name) | ||
| 104 | "Default username to use." | ||
| 105 | :type 'string | ||
| 106 | :group 'sieve-manage) | ||
| 107 | |||
| 108 | (defcustom sieve-manage-server-eol "\r\n" | 98 | (defcustom sieve-manage-server-eol "\r\n" |
| 109 | "The EOL string sent from the server." | 99 | "The EOL string sent from the server." |
| 110 | :type 'string | 100 | :type 'string |
| @@ -174,8 +164,6 @@ Must be a name of a stream in `sieve-manage-stream-alist'." | |||
| 174 | sieve-manage-port | 164 | sieve-manage-port |
| 175 | sieve-manage-auth | 165 | sieve-manage-auth |
| 176 | sieve-manage-stream | 166 | sieve-manage-stream |
| 177 | sieve-manage-username | ||
| 178 | sieve-manage-password | ||
| 179 | sieve-manage-process | 167 | sieve-manage-process |
| 180 | sieve-manage-client-eol | 168 | sieve-manage-client-eol |
| 181 | sieve-manage-server-eol | 169 | sieve-manage-server-eol |
| @@ -186,8 +174,6 @@ Must be a name of a stream in `sieve-manage-stream-alist'." | |||
| 186 | (defvar sieve-manage-auth nil) | 174 | (defvar sieve-manage-auth nil) |
| 187 | (defvar sieve-manage-server nil) | 175 | (defvar sieve-manage-server nil) |
| 188 | (defvar sieve-manage-port nil) | 176 | (defvar sieve-manage-port nil) |
| 189 | (defvar sieve-manage-username nil) | ||
| 190 | (defvar sieve-manage-password nil) | ||
| 191 | (defvar sieve-manage-state 'closed | 177 | (defvar sieve-manage-state 'closed |
| 192 | "Managesieve state. | 178 | "Managesieve state. |
| 193 | Valid states are `closed', `initial', `nonauth', and `auth'.") | 179 | Valid states are `closed', `initial', `nonauth', and `auth'.") |
| @@ -201,61 +187,6 @@ Valid states are `closed', `initial', `nonauth', and `auth'.") | |||
| 201 | (unless (featurep 'xemacs) | 187 | (unless (featurep 'xemacs) |
| 202 | '(set-buffer-multibyte nil))) | 188 | '(set-buffer-multibyte nil))) |
| 203 | 189 | ||
| 204 | (declare-function password-read "password-cache" (prompt &optional key)) | ||
| 205 | (declare-function password-cache-add "password-cache" (key password)) | ||
| 206 | (declare-function password-cache-remove "password-cache" (key)) | ||
| 207 | |||
| 208 | ;; Uses the dynamically bound `reason' variable. | ||
| 209 | (defvar reason) | ||
| 210 | (defun sieve-manage-interactive-login (buffer loginfunc) | ||
| 211 | "Login to server in BUFFER. | ||
| 212 | LOGINFUNC is passed a username and a password, it should return t if | ||
| 213 | it was successful authenticating itself to the server, nil otherwise. | ||
| 214 | Returns t if login was successful, nil otherwise." | ||
| 215 | (with-current-buffer buffer | ||
| 216 | (make-local-variable 'sieve-manage-username) | ||
| 217 | (make-local-variable 'sieve-manage-password) | ||
| 218 | (let (user passwd ret reason passwd-key) | ||
| 219 | (condition-case () | ||
| 220 | (while (or (not user) (not passwd)) | ||
| 221 | (setq user (or sieve-manage-username | ||
| 222 | (read-from-minibuffer | ||
| 223 | (concat "Managesieve username for " | ||
| 224 | sieve-manage-server ": ") | ||
| 225 | (or user sieve-manage-default-user))) | ||
| 226 | passwd-key (concat "managesieve:" user "@" sieve-manage-server | ||
| 227 | ":" sieve-manage-port) | ||
| 228 | passwd (or sieve-manage-password | ||
| 229 | (password-read (concat "Managesieve password for " | ||
| 230 | user "@" sieve-manage-server | ||
| 231 | ": ") | ||
| 232 | passwd-key))) | ||
| 233 | (when (y-or-n-p "Store password for this session? ") | ||
| 234 | (password-cache-add passwd-key (copy-sequence passwd))) | ||
| 235 | (when (and user passwd) | ||
| 236 | (if (funcall loginfunc user passwd) | ||
| 237 | (setq ret t | ||
| 238 | sieve-manage-username user) | ||
| 239 | (if reason | ||
| 240 | (message "Login failed (reason given: %s)..." reason) | ||
| 241 | (message "Login failed...")) | ||
| 242 | (password-cache-remove passwd-key) | ||
| 243 | (setq sieve-manage-password nil) | ||
| 244 | (setq passwd nil) | ||
| 245 | (setq reason nil) | ||
| 246 | (sit-for 1)))) | ||
| 247 | (quit (with-current-buffer buffer | ||
| 248 | (password-cache-remove passwd-key) | ||
| 249 | (setq user nil | ||
| 250 | passwd nil | ||
| 251 | sieve-manage-password nil))) | ||
| 252 | (error (with-current-buffer buffer | ||
| 253 | (password-cache-remove passwd-key) | ||
| 254 | (setq user nil | ||
| 255 | passwd nil | ||
| 256 | sieve-manage-password nil)))) | ||
| 257 | ret))) | ||
| 258 | |||
| 259 | (defun sieve-manage-erase (&optional p buffer) | 190 | (defun sieve-manage-erase (&optional p buffer) |
| 260 | (let ((buffer (or buffer (current-buffer)))) | 191 | (let ((buffer (or buffer (current-buffer)))) |
| 261 | (and sieve-manage-log | 192 | (and sieve-manage-log |
| @@ -336,70 +267,72 @@ Returns t if login was successful, nil otherwise." | |||
| 336 | process))) | 267 | process))) |
| 337 | 268 | ||
| 338 | ;; Authenticators | 269 | ;; Authenticators |
| 339 | |||
| 340 | (defun sieve-sasl-auth (buffer mech) | 270 | (defun sieve-sasl-auth (buffer mech) |
| 341 | "Login to server using the SASL MECH method." | 271 | "Login to server using the SASL MECH method." |
| 342 | (message "sieve: Authenticating using %s..." mech) | 272 | (message "sieve: Authenticating using %s..." mech) |
| 343 | (if (sieve-manage-interactive-login | 273 | (with-current-buffer buffer |
| 344 | buffer | 274 | (let* ((user-password (auth-source-user-or-password |
| 345 | (lambda (user passwd) | 275 | '("login" "password") |
| 346 | (let (client step tag data rsp) | 276 | sieve-manage-server |
| 347 | (setq client (sasl-make-client (sasl-find-mechanism (list mech)) | 277 | "sieve" nil t)) |
| 348 | user "sieve" sieve-manage-server)) | 278 | (client (sasl-make-client (sasl-find-mechanism (list mech)) |
| 349 | (setq sasl-read-passphrase (function (lambda (prompt) passwd))) | 279 | (car user-password) "sieve" sieve-manage-server)) |
| 350 | (setq step (sasl-next-step client nil)) | 280 | (sasl-read-passphrase |
| 351 | (setq tag | 281 | ;; We *need* to copy the password, because sasl will modify it |
| 352 | (sieve-manage-send | 282 | ;; somehow. |
| 353 | (concat | 283 | `(lambda (prompt) ,(copy-sequence (cadr user-password)))) |
| 354 | "AUTHENTICATE \"" | 284 | (step (sasl-next-step client nil)) |
| 355 | mech | 285 | (tag (sieve-manage-send |
| 356 | "\"" | 286 | (concat |
| 357 | (and (sasl-step-data step) | 287 | "AUTHENTICATE \"" |
| 358 | (concat | 288 | mech |
| 359 | " \"" | 289 | "\"" |
| 360 | (base64-encode-string | 290 | (and (sasl-step-data step) |
| 361 | (sasl-step-data step) | 291 | (concat |
| 362 | 'no-line-break) | 292 | " \"" |
| 363 | "\""))))) | 293 | (base64-encode-string |
| 364 | (catch 'done | 294 | (sasl-step-data step) |
| 365 | (while t | 295 | 'no-line-break) |
| 366 | (setq rsp nil) | 296 | "\""))))) |
| 367 | (goto-char (point-min)) | 297 | data rsp) |
| 368 | (while (null (or (progn | 298 | (catch 'done |
| 369 | (setq rsp (sieve-manage-is-string)) | 299 | (while t |
| 370 | (if (not (and rsp (looking-at | 300 | (setq rsp nil) |
| 371 | sieve-manage-server-eol))) | 301 | (goto-char (point-min)) |
| 372 | (setq rsp nil) | 302 | (while (null (or (progn |
| 373 | (goto-char (match-end 0)) | 303 | (setq rsp (sieve-manage-is-string)) |
| 374 | rsp)) | 304 | (if (not (and rsp (looking-at |
| 375 | (setq rsp (sieve-manage-is-okno)))) | 305 | sieve-manage-server-eol))) |
| 376 | (accept-process-output sieve-manage-process 1) | 306 | (setq rsp nil) |
| 377 | (goto-char (point-min))) | 307 | (goto-char (match-end 0)) |
| 378 | (sieve-manage-erase) | 308 | rsp)) |
| 379 | (when (sieve-manage-ok-p rsp) | 309 | (setq rsp (sieve-manage-is-okno)))) |
| 380 | (when (string-match "^SASL \"\\([^\"]+\\)\"" (cadr rsp)) | 310 | (accept-process-output sieve-manage-process 1) |
| 381 | (sasl-step-set-data | 311 | (goto-char (point-min))) |
| 382 | step (base64-decode-string (match-string 1 (cadr rsp))))) | 312 | (sieve-manage-erase) |
| 383 | (if (and (setq step (sasl-next-step client step)) | 313 | (when (sieve-manage-ok-p rsp) |
| 384 | (setq data (sasl-step-data step))) | 314 | (when (and (cadr rsp) |
| 385 | ;; We got data for server but it's finished | 315 | (string-match "^SASL \"\\([^\"]+\\)\"" (cadr rsp))) |
| 386 | (error "Server not ready for SASL data: %s" data) | 316 | (sasl-step-set-data |
| 387 | ;; The authentication process is finished. | 317 | step (base64-decode-string (match-string 1 (cadr rsp))))) |
| 388 | (throw 'done t))) | 318 | (if (and (setq step (sasl-next-step client step)) |
| 389 | (unless (stringp rsp) | 319 | (setq data (sasl-step-data step))) |
| 390 | (apply 'error "Server aborted SASL authentication: %s %s %s" | 320 | ;; We got data for server but it's finished |
| 391 | rsp)) | 321 | (error "Server not ready for SASL data: %s" data) |
| 392 | (sasl-step-set-data step (base64-decode-string rsp)) | 322 | ;; The authentication process is finished. |
| 393 | (setq step (sasl-next-step client step)) | 323 | (throw 'done t))) |
| 394 | (sieve-manage-send | 324 | (unless (stringp rsp) |
| 395 | (if (sasl-step-data step) | 325 | (error "Server aborted SASL authentication: %s" (caddr rsp))) |
| 396 | (concat "\"" | 326 | (sasl-step-set-data step (base64-decode-string rsp)) |
| 397 | (base64-encode-string (sasl-step-data step) | 327 | (setq step (sasl-next-step client step)) |
| 398 | 'no-line-break) | 328 | (sieve-manage-send |
| 399 | "\"") | 329 | (if (sasl-step-data step) |
| 400 | ""))))))) | 330 | (concat "\"" |
| 401 | (message "sieve: Authenticating using %s...done" mech) | 331 | (base64-encode-string (sasl-step-data step) |
| 402 | (message "sieve: Authenticating using %s...failed" mech))) | 332 | 'no-line-break) |
| 333 | "\"") | ||
| 334 | "")))) | ||
| 335 | (message "sieve: Login using %s...done" mech)))) | ||
| 403 | 336 | ||
| 404 | (defun sieve-manage-cram-md5-p (buffer) | 337 | (defun sieve-manage-cram-md5-p (buffer) |
| 405 | (sieve-manage-capability "SASL" "CRAM-MD5" buffer)) | 338 | (sieve-manage-capability "SASL" "CRAM-MD5" buffer)) |
| @@ -534,24 +467,6 @@ If BUFFER is nil, the current buffer is used." | |||
| 534 | (sieve-manage-erase) | 467 | (sieve-manage-erase) |
| 535 | t)) | 468 | t)) |
| 536 | 469 | ||
| 537 | (defun sieve-manage-authenticate (&optional user passwd buffer) | ||
| 538 | "Authenticate to server in BUFFER, using current buffer if nil. | ||
| 539 | It uses the authenticator specified when opening the server. If the | ||
| 540 | authenticator requires username/passwords, they are queried from the | ||
| 541 | user and optionally stored in the buffer. If USER and/or PASSWD is | ||
| 542 | specified, the user will not be questioned and the username and/or | ||
| 543 | password is remembered in the buffer." | ||
| 544 | (with-current-buffer (or buffer (current-buffer)) | ||
| 545 | (if (not (eq sieve-manage-state 'nonauth)) | ||
| 546 | (eq sieve-manage-state 'auth) | ||
| 547 | (make-local-variable 'sieve-manage-username) | ||
| 548 | (make-local-variable 'sieve-manage-password) | ||
| 549 | (if user (setq sieve-manage-username user)) | ||
| 550 | (if passwd (setq sieve-manage-password passwd)) | ||
| 551 | (if (funcall (nth 2 (assq sieve-manage-auth | ||
| 552 | sieve-manage-authenticator-alist)) buffer) | ||
| 553 | (setq sieve-manage-state 'auth))))) | ||
| 554 | |||
| 555 | (defun sieve-manage-capability (&optional name value buffer) | 470 | (defun sieve-manage-capability (&optional name value buffer) |
| 556 | "Check if capability NAME of server BUFFER match VALUE. | 471 | "Check if capability NAME of server BUFFER match VALUE. |
| 557 | If it does, return the server value of NAME. If not returns nil. | 472 | If it does, return the server value of NAME. If not returns nil. |
diff --git a/lisp/gnus/sieve.el b/lisp/gnus/sieve.el index 7b014da2f83..e988cb759de 100644 --- a/lisp/gnus/sieve.el +++ b/lisp/gnus/sieve.el | |||
| @@ -320,11 +320,17 @@ Server : " server ":" (or port "2000") " | |||
| 320 | (insert "\n")))) | 320 | (insert "\n")))) |
| 321 | 321 | ||
| 322 | (defun sieve-open-server (server &optional port) | 322 | (defun sieve-open-server (server &optional port) |
| 323 | ;; open server | 323 | (with-current-buffer |
| 324 | (set (make-local-variable 'sieve-manage-buffer) | 324 | ;; open server |
| 325 | (sieve-manage-open server)) | 325 | (set (make-local-variable 'sieve-manage-buffer) |
| 326 | ;; authenticate | 326 | (sieve-manage-open server)) |
| 327 | (sieve-manage-authenticate nil nil sieve-manage-buffer)) | 327 | ;; authenticate |
| 328 | (if (eq sieve-manage-state 'nonauth) | ||
| 329 | (if (funcall (nth 2 (assq sieve-manage-auth | ||
| 330 | sieve-manage-authenticator-alist)) | ||
| 331 | (current-buffer)) | ||
| 332 | (setq sieve-manage-state 'auth)) | ||
| 333 | (eq sieve-manage-state 'auth)))) | ||
| 328 | 334 | ||
| 329 | (defun sieve-refresh-scriptlist () | 335 | (defun sieve-refresh-scriptlist () |
| 330 | (interactive) | 336 | (interactive) |