From: Thomas Roessler Date: Thu, 15 Feb 2001 16:37:25 +0000 (+0000) Subject: Brendan Cully's latest STARTTLS patch. X-Git-Tag: mutt-1-3-16-rel~16 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9bfbb6b1f09b1ebe255a2f66022d6b3fa9a07aaf;p=mutt Brendan Cully's latest STARTTLS patch. --- diff --git a/acconfig.h b/acconfig.h index 42b6c934..1235a535 100644 --- a/acconfig.h +++ b/acconfig.h @@ -36,7 +36,7 @@ */ #undef NFS_ATTRIBUTE_HACK -/* Define to `int*' if doesn't have it. */ +/* Define to `int' if doesn't have it. */ #undef socklen_t /* Include code for socket support. Set automatically if you enable pop or diff --git a/configure.in b/configure.in index 483af75b..5136400f 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/globals.h b/globals.h index 45691a1e..9a38542d 100644 --- 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; diff --git a/imap/browse.c b/imap/browse.c index 7a31f63d..1326bd92 100644 --- a/imap/browse.c +++ b/imap/browse.c @@ -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) diff --git a/imap/imap.c b/imap/imap.c index 2b479601..ba9d2013 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -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; + } } } } diff --git a/imap/imap.h b/imap/imap.h index a89ba032..b05dc182 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -1,5 +1,6 @@ /* * Copyright (C) 1996-8 Michael R. Elkins + * Copyright (C) 2000-1 Brendan Cully * * 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); diff --git a/imap/util.c b/imap/util.c index c0cfa1d7..e43dfee2 100644 --- a/imap/util.c +++ b/imap/util.c @@ -35,6 +35,153 @@ #include +/* -- 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 914690fd..73b69b13 100644 --- 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 908ffe1c..620c26e6 100644 --- 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, diff --git a/mutt_sasl.c b/mutt_sasl.c index eb3e2ce4..1b1b7a40 100644 --- a/mutt_sasl.c +++ b/mutt_sasl.c @@ -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")); diff --git a/muttlib.c b/muttlib.c index 42f8415b..0d6e6b95 100644 --- 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)) diff --git a/pop_auth.c b/pop_auth.c index 72e6e0f3..09ec5e72 100644 --- a/pop_auth.c +++ b/pop_auth.c @@ -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 d4f7a4d1..d11ed7fc 100644 --- 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;