(require 'nnoo)
(require 'netrc)
(require 'utf7)
+(require 'tls)
(require 'parse-time)
(autoload 'auth-source-forget-user-or-password "auth-source")
#'upcase
(nnimap-find-parameter
"CAPABILITY" (cdr (nnimap-command "CAPABILITY")))))
- (when (eq nnimap-stream 'starttls)
- (nnimap-command "STARTTLS")
- (starttls-negotiate (nnimap-process nnimap-object)))
(when nnimap-server-port
(push (format "%s" nnimap-server-port) ports))
+ ;; If this is a STARTTLS-capable server, then sever the
+ ;; connection and start a STARTTLS connection instead.
+ (when (and (eq nnimap-stream 'network)
+ (member "STARTTLS" (nnimap-capabilities nnimap-object)))
+ (let ((nnimap-stream 'starttls))
+ (let ((tls-process
+ (nnimap-open-connection buffer)))
+ ;; If the STARTTLS connection was successful, we
+ ;; kill our first non-encrypted connection. If it
+ ;; wasn't successful, we just use our unencrypted
+ ;; connection.
+ (when (memq (process-status tls-process) '(open run))
+ (delete-process (nnimap-process nnimap-object))
+ (kill-buffer (current-buffer))
+ (return tls-process)))))
(unless (equal connection-result "PREAUTH")
(if (not (setq credentials
(if (eq nnimap-authenticator 'anonymous)
(when nnimap-object
(when (member "QRESYNC" (nnimap-capabilities nnimap-object))
(nnimap-command "ENABLE QRESYNC"))
- t)))))))
+ (nnimap-process nnimap-object))))))))
(defun nnimap-extend-tls-programs ()
(let ((programs tls-program)
(unless (consp programs)
(setq programs (list programs)))
(dolist (program programs)
- (push
- (with-temp-buffer
- (insert program)
- (goto-char (point-min))
- (or (search-forward " " nil t)
- (goto-char (point-max)))
- (insert " %s ")
- (buffer-string))
- result))
+ (when (assoc (car (split-string program)) tls-starttls-switches)
+ (push (if (not (string-match "%s" program))
+ (concat program " " "%s")
+ program)
+ result)))
(nreverse result)))
(defun nnimap-find-parameter (parameter elems)
(nnimap-update-info info (cdr (assoc group flags))))))
(defun nnimap-update-info (info marks)
- (when marks
+ (when (and marks
+ ;; Ignore groups with no UIDNEXT values.
+ (nth 4 marks))
(destructuring-bind (existing flags high low uidnext start-article
permanent-flags) marks
(let ((group (gnus-info-group info))
(goto-char (point-min))
(while (and (memq (process-status process)
'(open run))
- (not (re-search-forward "^\\* .*\n" nil t)))
+ (not (re-search-forward "^[*.] .*\n" nil t)))
(nnheader-accept-process-output process)
(goto-char (point-min)))
(forward-line -1)
- (and (looking-at "\\* \\([A-Z0-9]+\\)")
+ (and (looking-at "[*.] \\([A-Z0-9]+\\)")
(match-string 1))))
(defun nnimap-wait-for-response (sequence &optional messagep)