]> granicus.if.org Git - mutt/commitdiff
Brendan Cully's latest STARTTLS patch.
authorThomas Roessler <roessler@does-not-exist.org>
Thu, 15 Feb 2001 16:37:25 +0000 (16:37 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Thu, 15 Feb 2001 16:37:25 +0000 (16:37 +0000)
13 files changed:
acconfig.h
configure.in
globals.h
imap/browse.c
imap/imap.c
imap/imap.h
imap/util.c
init.h
mutt.h
mutt_sasl.c
muttlib.c
pop_auth.c
url.c

index 42b6c934687622c7b0014b23de247a79cb104e20..1235a535c965efe354c289ea269686c67c84f475 100644 (file)
@@ -36,7 +36,7 @@
  */
 #undef NFS_ATTRIBUTE_HACK
 
-/* Define to `int*' if <unistd.h> doesn't have it. */
+/* Define to `int' if <sys/socket.h> doesn't have it. */
 #undef socklen_t
 
 /* Include code for socket support. Set automatically if you enable pop or
index 483af75bcc3e69d74b53fda1ac73ad7e164f68b4..5136400ff491e9418abac21d4595af65f1576d99 100644 (file)
@@ -561,7 +561,7 @@ then
        AC_MSG_CHECKING([for socklen_t])
        AC_EGREP_HEADER(socklen_t, sys/socket.h, AC_MSG_RESULT([yes]),
                AC_MSG_RESULT([no])
-               AC_DEFINE(socklen_t, int*))
+               AC_DEFINE(socklen_t, int))
        AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent))
        AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
        AC_CHECK_FUNCS(getaddrinfo)
index 45691a1e0713990e3cf7ff387f4d5e6998d4de2f..9a38542d2cec18a226a7518b0fe5c269b7ac054e 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -50,9 +50,10 @@ WHERE char *HdrFmt;
 WHERE char *Homedir;
 WHERE char *Hostname;
 #ifdef USE_IMAP
-WHERE char *ImapUser INITVAL (NULL);
-WHERE char *ImapPass INITVAL (NULL);
+WHERE char *ImapDelimChars INITVAL (NULL);
 WHERE char *ImapHomeNamespace INITVAL (NULL);
+WHERE char *ImapPass INITVAL (NULL);
+WHERE char *ImapUser INITVAL (NULL);
 #endif
 WHERE char *InReplyTo;
 WHERE char *Inbox;
index 7a31f63d6539694e9ab93930bb9c6afc558e0eda..1326bd922f16829fbb185632e4ce82266e85af65 100644 (file)
@@ -209,6 +209,8 @@ int imap_browse (char* path, struct browser_state* state)
   if (browse_add_list_result (idata, buf, state, 0))
     goto fail;
 
+  mutt_clear_error ();
+
   qsort(&(state->entry[nsup]),state->entrylen-nsup,sizeof(state->entry[0]),
        (int (*)(const void*,const void*)) compare_names);
   if (home_namespace)
index 2b4796011e47242b8c66a68f34b651456d9ef908..ba9d20136d7c2808c953975d415f40a87fe9ddfa 100644 (file)
@@ -332,23 +332,28 @@ int imap_open_connection (IMAP_DATA* idata)
     if (imap_check_capabilities (idata))
       goto bail;
 #if defined(USE_SSL) && !defined(USE_NSS)
-    /* Attempt STARTTLS if available. TODO: make STARTTLS configurable. */
+    /* Attempt STARTTLS if available and desired. */
     if (mutt_bit_isset (idata->capabilities, STARTTLS))
     {
-      if ((rc = imap_exec (idata, "STARTTLS", IMAP_CMD_FAIL_OK)) == -1)
+      if ((rc = query_quadoption (OPT_SSLSTARTTLS,
+        _("Secure connection with TLS?"))) == -1)
        goto bail;
-      if (rc != -2)
-      {
-       if (mutt_ssl_starttls (idata->conn))
-        {
-         dprint (1, (debugfile, "imap_open_connection: STARTTLS failed\n"));
+      if (rc == M_YES) {
+       if ((rc = imap_exec (idata, "STARTTLS", IMAP_CMD_FAIL_OK)) == -1)
          goto bail;
-       }
-       else
+       if (rc != -2)
        {
-         /* RFC 2595 demands we recheck CAPABILITY after TLS is negotiated. */
-         if (imap_exec (idata, "CAPABILITY", 0))
+         if (mutt_ssl_starttls (idata->conn))
+         {
+           dprint (1, (debugfile, "imap_open_connection: STARTTLS failed\n"));
            goto bail;
+         }
+         else
+         {
+           /* RFC 2595 demands we recheck CAPABILITY after TLS completes. */
+           if (imap_exec (idata, "CAPABILITY", 0))
+             goto bail;
+         }
        }
       }
     }
index a89ba032a29f60c2a05f41415004b9f4977941c7..b05dc18270f4e2053ea966a3ec9742e7a227f7f2 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
+ * Copyright (C) 2000-1 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
@@ -60,6 +61,7 @@ void imap_logout_all (void);
 
 /* util.c */
 int imap_parse_path (const char* path, IMAP_MBOX* mx);
+void imap_pretty_mailbox (char* path);
 
 int imap_wait_keepalive (pid_t pid);
 void imap_keepalive (void);
index c0cfa1d71cb9f421a4bbf2fc5f720b6b2514f0da..e43dfee2b9d1cccc87196ec2b13441a2efa049d6 100644 (file)
 
 #include <errno.h>
 
+/* -- public functions -- */
+
+/* imap_parse_path: given an IMAP mailbox name, return host, port
+ *   and a path IMAP servers will recognise.
+ * mx.mbox is malloc'd, caller must free it */
+int imap_parse_path (const char* path, IMAP_MBOX* mx)
+{
+  char tmp[128];
+  ciss_url_t url;
+  char *c;
+  int n;
+
+  /* Defaults */
+  mx->account.flags = 0;
+  mx->account.port = IMAP_PORT;
+  mx->account.type = M_ACCT_TYPE_IMAP;
+
+  c = safe_strdup (path);
+  url_parse_ciss (&url, c);
+  if (url.scheme == U_IMAP || url.scheme == U_IMAPS)
+  {
+    if (mutt_account_fromurl (&mx->account, &url) < 0)
+    {
+      FREE (&c);
+      return -1;
+    }
+
+    mx->mbox = safe_strdup (url.path);
+
+    if (url.scheme == U_IMAPS)
+      mx->account.flags |= M_ACCT_SSL;
+
+    FREE (&c);
+  }
+  /* old PINE-compatibility code */
+  else
+  {
+    FREE (&c);
+    if (sscanf (path, "{%128[^}]}", tmp) != 1) 
+      return -1;
+
+    c = strchr (path, '}');
+    if (!c)
+      return -1;
+    else
+      /* walk past closing '}' */
+      mx->mbox = safe_strdup (c+1);
+  
+    if ((c = strrchr (tmp, '@')))
+    {
+      *c = '\0';
+      strfcpy (mx->account.user, tmp, sizeof (mx->account.user));
+      strfcpy (tmp, c+1, sizeof (tmp));
+      mx->account.flags |= M_ACCT_USER;
+    }
+  
+    if ((n = sscanf (tmp, "%128[^:/]%128s", mx->account.host, tmp)) < 1)
+    {
+      dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path));
+      FREE (&mx->mbox);
+      return -1;
+    }
+  
+    if (n > 1) {
+      if (sscanf (tmp, ":%hd%128s", &(mx->account.port), tmp) >= 1)
+       mx->account.flags |= M_ACCT_PORT;
+      if (sscanf (tmp, "/%s", tmp) == 1)
+      {
+       if (!strncmp (tmp, "ssl", 3))
+         mx->account.flags |= M_ACCT_SSL;
+       else
+       {
+         dprint (1, (debugfile, "imap_parse_path: Unknown connection type in %s\n", path));
+         FREE (&mx->mbox);
+         return -1;
+       }
+      }
+    }
+  }
+  
+#ifdef USE_SSL
+  if (option (OPTIMAPFORCESSL))
+    mx->account.flags |= M_ACCT_SSL;
+#endif
+
+  if ((mx->account.flags & M_ACCT_SSL) && !(mx->account.flags & M_ACCT_PORT))
+    mx->account.port = IMAP_SSL_PORT;
+
+  return 0;
+}
+
+/* imap_pretty_mailbox: called by mutt_pretty_mailbox to make IMAP paths
+ *   look nice. */
+void imap_pretty_mailbox (char* path)
+{
+  IMAP_MBOX home, target;
+  ciss_url_t url;
+  char* delim;
+  int tlen;
+  int hlen = 0;
+  char home_match = 0;
+
+  if (imap_parse_path (path, &target) < 0)
+    return;
+
+  tlen = mutt_strlen (target.mbox);
+  /* check whether we can do '=' substitution */
+  if (! imap_parse_path (Maildir, &home))
+  {
+    hlen = mutt_strlen (home.mbox);
+    if (tlen && mutt_account_match (&home.account, &target.account) &&
+       !mutt_strncmp (home.mbox, target.mbox, hlen))
+    {
+      if (! hlen)
+       home_match = 1;
+      else
+       for (delim = ImapDelimChars; *delim != '\0'; delim++)
+         if (target.mbox[hlen] == *delim)
+           home_match = 1;
+    }
+    FREE (&home.mbox);
+  }
+
+  /* do the '=' substitution */
+  if (home_match) {
+    *path++ = '=';
+    /* copy remaining path, skipping delimiter */
+    if (! hlen)
+      hlen = -1;
+    memcpy (path, target.mbox + hlen + 1, tlen - hlen - 1);
+    path[tlen - hlen - 1] = '\0';
+  }
+  else
+  {
+    mutt_account_tourl (&target.account, &url);
+    url.path = target.mbox;
+    /* FIXME: That hard-coded constant is bogus. But we need the actual
+     *   size of the buffer from mutt_pretty_mailbox. And these pretty
+     *   operations usually shrink the result. Still... */
+    url_ciss_tostring (&url, path, 1024);
+  }
+
+  FREE (&target.mbox);
+}
+
+/* -- library functions -- */
+
 /* imap_continue: display a message and ask the user if she wants to
  *   go on. */
 int imap_continue (const char* msg, const char* resp)
@@ -204,95 +351,6 @@ time_t imap_parse_date (char *s)
   return (mutt_mktime (&t, 0) + tz);
 }
 
-/* imap_parse_path: given an IMAP mailbox name, return host, port
- *   and a path IMAP servers will recognise.
- * mx.mbox is malloc'd, caller must free it */
-int imap_parse_path (const char* path, IMAP_MBOX* mx)
-{
-  char tmp[128];
-  ciss_url_t url;
-  char *c;
-  int n;
-
-  /* Defaults */
-  mx->account.flags = 0;
-  mx->account.port = IMAP_PORT;
-  mx->account.type = M_ACCT_TYPE_IMAP;
-
-  c = safe_strdup (path);
-  url_parse_ciss (&url, c);
-  if (url.scheme == U_IMAP || url.scheme == U_IMAPS)
-  {
-    if (mutt_account_fromurl (&mx->account, &url) < 0)
-    {
-      FREE (&c);
-      return -1;
-    }
-
-    mx->mbox = safe_strdup (url.path);
-
-    if (url.scheme == U_IMAPS)
-      mx->account.flags |= M_ACCT_SSL;
-
-    FREE (&c);
-  }
-  /* old PINE-compatibility code */
-  else
-  {
-    FREE (&c);
-    if (sscanf (path, "{%128[^}]}", tmp) != 1) 
-      return -1;
-
-    c = strchr (path, '}');
-    if (!c)
-      return -1;
-    else
-      /* walk past closing '}' */
-      mx->mbox = safe_strdup (c+1);
-  
-    if ((c = strrchr (tmp, '@')))
-    {
-      *c = '\0';
-      strfcpy (mx->account.user, tmp, sizeof (mx->account.user));
-      strfcpy (tmp, c+1, sizeof (tmp));
-      mx->account.flags |= M_ACCT_USER;
-    }
-  
-    if ((n = sscanf (tmp, "%128[^:/]%128s", mx->account.host, tmp)) < 1)
-    {
-      dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path));
-      FREE (&mx->mbox);
-      return -1;
-    }
-  
-    if (n > 1) {
-      if (sscanf (tmp, ":%hd%128s", &(mx->account.port), tmp) >= 1)
-       mx->account.flags |= M_ACCT_PORT;
-      if (sscanf (tmp, "/%s", tmp) == 1)
-      {
-       if (!strncmp (tmp, "ssl", 3))
-         mx->account.flags |= M_ACCT_SSL;
-       else
-       {
-         dprint (1, (debugfile, "imap_parse_path: Unknown connection type in %s\n", path));
-         FREE (&mx->mbox);
-         return -1;
-       }
-      }
-    }
-  }
-  
-#ifdef USE_SSL
-  if (option (OPTIMAPFORCESSL))
-    mx->account.flags |= M_ACCT_SSL;
-#endif
-
-  if ((mx->account.flags & M_ACCT_SSL) && !(mx->account.flags & M_ACCT_PORT))
-    mx->account.port = IMAP_SSL_PORT;
-
-  return 0;
-}
-
 /* imap_qualify_path: make an absolute IMAP folder target, given IMAP_MBOX
  *   and relative path. */
 void imap_qualify_path (char *dest, size_t len, IMAP_MBOX *mx, char* path)
diff --git a/init.h b/init.h
index 914690fdf7f51debc4094b03ca6eecff2eb28e72..73b69b13c0ade84475002f7080e9c472dc9d1215 100644 (file)
--- a/init.h
+++ b/init.h
@@ -670,6 +670,13 @@ struct option_t MuttVars[] = {
   ** list.
   */
 #ifdef USE_IMAP
+  { "imap_delim_chars",                DT_STR, R_NONE, UL &ImapDelimChars, UL "/." },
+  /*
+  ** .pp
+  ** This contains the list of characters which you would like to treat
+  ** as folder separators for displaying IMAP paths. In particular it
+  ** helps in using the '=' shortcut for your \fIfolder\fP variable.
+  */
 # ifdef USE_SSL
   { "imap_force_ssl",          DT_BOOL, R_NONE, OPTIMAPFORCESSL, 0 },
   /*
@@ -678,6 +685,13 @@ struct option_t MuttVars[] = {
   ** connecting to IMAP servers.
   */
 # endif
+  { "imap_home_namespace",     DT_STR, R_NONE, UL &ImapHomeNamespace, UL 0},
+  /*
+  ** .pp
+  ** You normally want to see your personal folders alongside
+  ** your INBOX in the IMAP browser. If you see something else, you may set
+  ** this variable to the IMAP path to your folders.
+  */
   { "imap_list_subscribed",    DT_BOOL, R_NONE, OPTIMAPLSUB, 0 },
   /*
   ** .pp
@@ -685,13 +699,6 @@ struct option_t MuttVars[] = {
   ** only subscribed folders or all folders.  This can be toggled in the
   ** IMAP browser with the \fItoggle-subscribed\fP command.
   */
-  { "imap_user",       DT_STR,  R_NONE, UL &ImapUser, UL 0 },
-  /*
-  ** .pp
-  ** Your login name on the IMAP server.
-  ** .pp
-  ** This variable defaults to your user name on the local machine.
-  */
   { "imap_pass",       DT_STR,  R_NONE, UL &ImapPass, UL 0 },
   /*
   ** .pp
@@ -727,12 +734,12 @@ struct option_t MuttVars[] = {
   ** server which are out of the users' hands, you may wish to suppress
   ** them at some point.
   */
-  { "imap_home_namespace",     DT_STR, R_NONE, UL &ImapHomeNamespace, UL 0},
+  { "imap_user",       DT_STR,  R_NONE, UL &ImapUser, UL 0 },
   /*
   ** .pp
-  ** You normally want to see your personal folders alongside
-  ** your INBOX in the IMAP browser. If you see something else, you may set
-  ** this variable to the IMAP path to your folders.
+  ** Your login name on the IMAP server.
+  ** .pp
+  ** This variable defaults to your user name on the local machine.
   */
 #endif
   { "implicit_autoview", DT_BOOL,R_NONE, OPTIMPLICITAUTOVIEW, 0},
@@ -1343,6 +1350,15 @@ struct option_t MuttVars[] = {
 #endif /* HAVE_PGP */
   
 #if defined(USE_SSL)||defined(USE_NSS)
+# ifndef USE_NSS  
+  { "ssl_starttls", DT_QUAD, R_NONE, OPT_SSLSTARTTLS, M_YES },
+  /*
+  ** .pp
+  ** If set (the default), mutt will attempt to use STARTTLS on servers
+  ** advertising the capability. When unset, mutt will not attempt to
+  ** use STARTTLS regardless of the server's capabilities.
+  */
+# endif  
   { "certificate_file",        DT_PATH, R_NONE, UL &SslCertFile, 0 },
   /*
   ** .pp
diff --git a/mutt.h b/mutt.h
index 908ffe1ce68b11f9dca21b565bc3ec87f04b33d8..620c26e658f0cf1722f4b7624bbb05aba3f3c7ef 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -252,6 +252,10 @@ enum
   OPT_PGPTRADITIONAL, /* create old-style PGP messages */
 #endif
 
+#ifdef USE_SSL
+  OPT_SSLSTARTTLS,
+#endif
+
   OPT_PRINT,
   OPT_INCLUDE,
   OPT_DELETE,
index eb3e2ce4fd5b5ba232037c9ce9ee09d64455e5b9..1b1b7a40c5f8218a9c67fe8bbac99d1e8df4ec6d 100644 (file)
@@ -100,7 +100,7 @@ int mutt_sasl_client_new (CONNECTION* conn, sasl_conn_t** saslconn)
       service = "imap";
       break;
     case M_ACCT_TYPE_POP:
-      service = "pop";
+      service = "pop-3";
       break;
     default:
       dprint (1, (debugfile, "mutt_sasl_client_new: account type unset\n"));
index 42f8415b2a746060362233ed57e76716d569ade3..0d6e6b9564c9f43a12f7e7b51fc9aa88d44e6ae4 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -660,9 +660,20 @@ void mutt_pretty_mailbox (char *s)
 {
   char *p = s, *q = s;
   size_t len;
+  url_scheme_t scheme;
+
+  scheme = url_check_scheme (s);
+
+#ifdef USE_IMAP
+  if (scheme == U_IMAP || scheme == U_IMAPS)
+  {
+    imap_pretty_mailbox (s);
+    return;
+  }
+#endif
 
   /* if s is an url, only collapse path component */
-  if (url_check_scheme (s) != U_UNKNOWN)
+  if (scheme != U_UNKNOWN)
   {
     p = strchr(s, ':')+1;
     if (!strncmp (p, "//", 2))
index 72e6e0f31d50b16465b27b8a6e62b82716297ec8..09ec5e727fdb28d6ab77e9a89ccf9d4c7b3180e9 100644 (file)
@@ -48,10 +48,7 @@ static pop_auth_res_t pop_auth_sasl (POP_DATA *pop_data)
   if (!pop_data->auth_list)
     return POP_A_UNAVAIL;
 
-  if (mutt_sasl_start () != SASL_OK ||
-      sasl_client_new ("pop-3", pop_data->conn->account.host,
-      mutt_sasl_get_callbacks (&pop_data->conn->account),
-      SASL_SECURITY_LAYER, &saslconn) != SASL_OK)
+  if (mutt_sasl_client_new (pop_data->conn, &saslconn) < 0)
   {
     dprint (1, (debugfile, "pop_auth_sasl: Error allocating SASL connection.\n"));
     return POP_A_FAILURE;
diff --git a/url.c b/url.c
index d4f7a4d1c78e6898f1ee72ba44a5eb0123f0692b..d11ed7fc92480eba56be0a1fd8d97bb90cb91246 100644 (file)
--- a/url.c
+++ b/url.c
@@ -146,6 +146,8 @@ static char *ciss_parse_userhost (ciss_url_t *ciss, char *src)
   return path;
 }
 
+/* url_parse_ciss: Fill in ciss_url_t. char* elements are pointers into src,
+ *   which is modified by this call (duplicate it first if you need to). */
 int url_parse_ciss (ciss_url_t *ciss, char *src)
 {
   char *tmp;