]> granicus.if.org Git - mutt/commitdiff
I noticed that my mutt hung when I tried SASL DIGEST-MD5
authorBrendan Cully <brendan@kublai.com>
Wed, 16 Jul 2003 11:18:12 +0000 (11:18 +0000)
committerBrendan Cully <brendan@kublai.com>
Wed, 16 Jul 2003 11:18:12 +0000 (11:18 +0000)
authentication (I'm not sure when this started). I believe this
patch should solve that problem in a reliable way.

This patch also attempts to reuse connections even when
authentication fails, instead of just throwing away a perfectly good
socket.

account.c
account.h
imap/auth_sasl.c
imap/imap.c

index 3fda792be4679ed097d188f6d13a706499eeeef8..4f0ed881b083b58a27c737dddd5255bb05cf3322 100644 (file)
--- a/account.c
+++ b/account.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2000 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 2000-3 Brendan Cully <brendan@kublai.com>
  * 
  *     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
@@ -180,3 +180,8 @@ int mutt_account_getpass (ACCOUNT* account)
 
   return 0;
 }
+
+void mutt_account_unsetpass (ACCOUNT* account)
+{
+  account->flags &= !M_ACCT_PASS;
+}
index a6850a6c47fe603d9f8fca3ff09245bd8f55d42c..145e5145d757c40554a4f92d286240bb462777d1 100644 (file)
--- a/account.h
+++ b/account.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2000 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 2000-3 Brendan Cully <brendan@kublai.com>
  * 
  *     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
@@ -52,5 +52,6 @@ int mutt_account_fromurl (ACCOUNT* account, ciss_url_t* url);
 void mutt_account_tourl (ACCOUNT* account, ciss_url_t* url);
 int mutt_account_getuser (ACCOUNT* account);
 int mutt_account_getpass (ACCOUNT* account);
+void mutt_account_unsetpass (ACCOUNT* account);
 
 #endif /* _MUTT_ACCOUNT_H_ */
index 4a929c97d194001c6843d1eda9c81313405710d6..574043577c17397440b1aee874e96681d27bcc18 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2000-2 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 2000-3 Brendan Cully <brendan@kublai.com>
  * 
  *     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
@@ -109,7 +109,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata, const char* method)
     return IMAP_AUTH_UNAVAIL;
   }
 
-  mutt_message _("Authenticating (SASL)...");
+  mutt_message (_("Authenticating (%s)..."), mech);
 
   snprintf (buf, sizeof (buf), "AUTHENTICATE %s", mech);
   imap_cmd_start (idata, buf);
@@ -153,7 +153,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata, const char* method)
       client_start = 0;
 
     /* send out response, or line break if none needed */
-    if (pc)
+    if (olen)
     {
       if (sasl_encode64 (pc, olen, buf, sizeof (buf), &olen) != SASL_OK)
       {
@@ -168,7 +168,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata, const char* method)
 #endif
     }
     
-    if (olen || rc == SASL_CONTINUE)
+    if (irc == IMAP_CMD_RESPOND)
     {
       strfcpy (buf + olen, "\r\n", sizeof (buf) - olen);
       mutt_socket_write (idata->conn, buf);
index a70d223231da2eddff1fe583cf108550d4ecdac7..f10ae281cf3bb6dd207c63798b2d841ecaee02a6 100644 (file)
@@ -340,30 +340,48 @@ IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags)
 
   /* don't open a new connection if one isn't wanted */
   if (flags & M_IMAP_CONN_NONEW)
-    if (!idata || idata->state == IMAP_DISCONNECTED)
-      goto err_conn;
+  {
+    if (!idata)
+    {
+      mutt_socket_free (conn);
+      return NULL;
+    }
+    if (idata->state < IMAP_AUTHENTICATED)
+      return NULL;
+  }
   
   if (!idata)
   {
     /* The current connection is a new connection */
     if (! (idata = imap_new_idata ()))
-      goto err_conn;
+    {
+      mutt_socket_free (conn);
+      return NULL;
+    }
 
     conn->data = idata;
     idata->conn = conn;
   }
+
   if (idata->state == IMAP_DISCONNECTED)
-    if (imap_open_connection (idata) != 0)
-      goto err_idata;
+    imap_open_connection (idata);
+  if (idata->state == IMAP_CONNECTED)
+  {
+    if (!imap_authenticate (idata))
+    {
+      idata->state = IMAP_AUTHENTICATED;
+      if (idata->conn->ssf)
+       dprint (2, (debugfile, "Communication encrypted at %d bits\n",
+                   idata->conn->ssf));
+      imap_get_delim (idata);
+    }
+    else
+      mutt_account_unsetpass (&idata->conn->account);
+    
+    FREE (&idata->capstr);
+  }
   
   return idata;
-
- err_idata:
-  imap_free_idata (&idata);
- err_conn:
-  mutt_socket_free (conn);
-
-  return NULL;
 }
 
 int imap_open_connection (IMAP_DATA* idata)
@@ -375,8 +393,14 @@ int imap_open_connection (IMAP_DATA* idata)
 
   idata->state = IMAP_CONNECTED;
 
-  if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
-    goto bail;
+  if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE) {
+    mutt_error (_("Unexpected response received from server: %s"), idata->cmd.buf);
+    mutt_sleep (1);
+
+    mutt_socket_close (idata->conn);
+    idata->state = IMAP_DISCONNECTED;
+    return -1;
+  }
 
   if (ascii_strncasecmp ("* OK", idata->cmd.buf, 4) == 0)
   {
@@ -413,16 +437,13 @@ int imap_open_connection (IMAP_DATA* idata)
       }
     }
 #endif    
-    if (imap_authenticate (idata))
-      goto bail;
-    if (idata->conn->ssf)
-      dprint (2, (debugfile, "Communication encrypted at %d bits\n",
-       idata->conn->ssf));
   }
   else if (ascii_strncasecmp ("* PREAUTH", idata->cmd.buf, 9) == 0)
   {
+    idata->state = IMAP_AUTHENTICATED;
     if (imap_check_capabilities (idata) != 0)
       goto bail;
+    FREE (&idata->capstr);
   } 
   else
   {
@@ -430,17 +451,12 @@ int imap_open_connection (IMAP_DATA* idata)
     goto bail;
   }
 
-  FREE (&idata->capstr);
-  idata->state = IMAP_AUTHENTICATED;
-
-  imap_get_delim (idata);
   return 0;
 
  err_close_conn:
   mutt_socket_close (idata->conn);
  bail:
   FREE (&idata->capstr);
-  idata->state = IMAP_DISCONNECTED;
   return -1;
 }
 
@@ -520,6 +536,9 @@ int imap_open_mailbox (CONTEXT* ctx)
   /* we require a connection which isn't currently in IMAP_SELECTED state */
   if (!(idata = imap_conn_find (&(mx.account), M_IMAP_CONN_NOSELECT)))
     goto fail_noidata;
+  if (idata->state < IMAP_AUTHENTICATED)
+    goto fail;
+
   conn = idata->conn;
 
   /* once again the context is new */