From ab0b51a1fef87bcc643c3aaf2e635c811b28ccd8 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Tue, 15 Feb 2011 06:10:59 -0500
Subject: [PATCH] - Use only one from IMAP authentication methods to prevent login delays (1487784)

---
 program/include/rcube_imap_generic.php |   73 ++++++++++++++++++++++++++++++------
 1 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php
index 41f704d..cc590e0 100644
--- a/program/include/rcube_imap_generic.php
+++ b/program/include/rcube_imap_generic.php
@@ -759,6 +759,11 @@
             }
         }
 
+        // Send ID info
+        if (!empty($this->prefs['ident']) && $this->getCapability('ID')) {
+            $this->id($this->prefs['ident']);
+        }
+
         $auth_methods = array();
         $result       = null;
 
@@ -777,6 +782,13 @@
             else if (!$login_disabled) {
                 $auth_methods[] = 'LOGIN';
             }
+
+            // Use best (for security) supported authentication method
+            foreach (array('DIGEST-MD5', 'CRAM-MD5', 'CRAM_MD5', 'PLAIN', 'LOGIN') as $auth_method) {
+                if (in_array($auth_method, $auth_methods)) {
+                    break;
+                }
+            }
         }
         else {
             // Prevent from sending credentials in plain text when connection is not secure
@@ -786,32 +798,28 @@
                 return false;
             }
             // replace AUTH with CRAM-MD5 for backward compat.
-            $auth_methods[] = $auth_method == 'AUTH' ? 'CRAM-MD5' : $auth_method;
+            if ($auth_method == 'AUTH') {
+                $auth_method = 'CRAM-MD5';
+            }
         }
 
         // pre-login capabilities can be not complete
         $this->capability_readed = false;
 
         // Authenticate
-        foreach ($auth_methods as $method) {
-            switch ($method) {
+        switch ($auth_method) {
             case 'CRAM_MD5':
-                $method = 'CRAM-MD5';
+                $auth_method = 'CRAM-MD5';
             case 'CRAM-MD5':
             case 'DIGEST-MD5':
             case 'PLAIN':
-                $result = $this->authenticate($user, $password, $method);
+                $result = $this->authenticate($user, $password, $auth_method);
                 break;
             case 'LOGIN':
                 $result = $this->login($user, $password);
                 break;
             default:
-                $this->setError(self::ERROR_BAD, "Configuration error. Unknown auth method: $method");
-            }
-
-            if (is_resource($result)) {
-                break;
-            }
+                $this->setError(self::ERROR_BAD, "Configuration error. Unknown auth method: $auth_method");
         }
 
         // Connected and authenticated
@@ -1152,6 +1160,44 @@
         $index = $this->search($mailbox, 'ALL UNSEEN', false, array('COUNT'));
         if (is_array($index)) {
             return (int) $index['COUNT'];
+        }
+
+        return false;
+    }
+
+    /**
+     * Executes ID command (RFC2971)
+     *
+     * @param array $items Client identification information key/value hash
+     *
+     * @return array Server identification information key/value hash
+     * @access public
+     * @since 0.6
+     */
+    function id($items=array())
+    {
+        if (is_array($items) && !empty($items)) {
+            foreach ($items as $key => $value) {
+                $args[] = $this->escape($key);
+                $args[] = $this->escape($value);
+            }
+        }
+
+        list($code, $response) = $this->execute('ID', array(
+            !empty($args) ? '(' . implode(' ', (array) $args) . ')' : $this->escape(null)
+        ));
+
+
+        if ($code == self::ERROR_OK && preg_match('/\* ID /i', $response)) {
+            $response = substr($response, 5); // remove prefix "* ID "
+            $items    = $this->tokenizeResponse($response);
+            $result   = null;
+
+            for ($i=0, $len=count($items); $i<$len; $i += 2) {
+                $result[$items[$i]] = $items[$i+1];
+            }
+
+            return $result;
         }
 
         return false;
@@ -3270,10 +3316,11 @@
         else if ($string === '') {
             return '""';
         }
+        // need quoted-string? find special chars: SP, CTL, (, ), {, %, *, ", \, ]
+        // plus [ character as a workaround for DBMail's bug (#1487766)
         else if ($force_quotes ||
-            preg_match('/([\x00-\x20\x28-\x29\x7B\x25\x2A\x22\x5C\x5D\x7F]+)/', $string)
+            preg_match('/([\x00-\x20\x28-\x29\x7B\x25\x2A\x22\x5B\x5C\x5D\x7F]+)/', $string)
         ) {
-            // string: special chars: SP, CTL, (, ), {, %, *, ", \, ]
             return '"' . strtr($string, array('"'=>'\\"', '\\' => '\\\\')) . '"';
         }
 

--
Gitblit v1.9.1