mutt stable branch with some hacks
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

STARTTLS patch from Brendan Cully.

+174 -64
+3
acconfig.h
··· 36 36 */ 37 37 #undef NFS_ATTRIBUTE_HACK 38 38 39 + /* Define to `int*' if <unistd.h> doesn't have it. */ 40 + #undef socklen_t 41 + 39 42 /* Include code for socket support. Set automatically if you enable pop or 40 43 * IMAP */ 41 44 #undef USE_SOCKET
+6 -2
configure.in
··· 558 558 559 559 if test "$need_socket" = "yes" 560 560 then 561 + AC_MSG_CHECKING([for socklen_t]) 562 + AC_EGREP_HEADER(socklen_t, sys/socket.h, AC_MSG_RESULT([yes]), 563 + AC_MSG_RESULT([no]) 564 + AC_DEFINE(socklen_t, int*)) 561 565 AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) 562 566 AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) 563 567 AC_CHECK_FUNCS(getaddrinfo) ··· 630 634 ]) 631 635 AM_CONDITIONAL(USE_GSS, test x$need_gss = xyes) 632 636 633 - AC_ARG_WITH(ssl, [ --with-ssl[=PFX] Compile in SSL socket support for POP/IMAP], 637 + AC_ARG_WITH(ssl, [ --with-ssl[=PFX] Compile in SSL support for POP/IMAP], 634 638 [ if test "$with_ssl" != "no" 635 639 then 636 640 if test "$need_socket" != "yes"; then ··· 664 668 AM_CONDITIONAL(USE_SSL, test x$need_ssl = xyes) 665 669 666 670 dnl SSL support via NSS 667 - AC_ARG_WITH(nss, [ --with-nss[=PFX] Compile in SSL socket support for POP/IMAP via NSS], 671 + AC_ARG_WITH(nss, [ --with-nss[=PFX] Compile in SSL support for POP/IMAP via NSS], 668 672 [ if test "$with_nss" != no 669 673 then 670 674 if test "$need_socket" != "yes"; then
+1 -1
imap/auth.c
··· 48 48 imap_auth_t* authenticator = imap_authenticators; 49 49 int r = -1; 50 50 51 - while (authenticator) 51 + while (*authenticator) 52 52 { 53 53 if ((r = (*authenticator)(idata)) != IMAP_AUTH_UNAVAIL) 54 54 return r;
+33 -1
imap/imap.c
··· 29 29 #include "browser.h" 30 30 #include "message.h" 31 31 #include "imap_private.h" 32 + #ifdef USE_SSL 33 + # include "mutt_ssl.h" 34 + #endif 32 35 33 36 #include <unistd.h> 34 37 #include <ctype.h> ··· 309 312 int imap_open_connection (IMAP_DATA* idata) 310 313 { 311 314 char buf[LONG_STRING]; 315 + int rc; 312 316 313 317 if (mutt_socket_open (idata->conn) < 0) 314 318 { ··· 324 328 325 329 if (mutt_strncmp ("* OK", idata->cmd.buf, 4) == 0) 326 330 { 327 - if (imap_check_capabilities (idata) || imap_authenticate (idata)) 331 + /* TODO: Parse new tagged CAPABILITY data (* OK [CAPABILITY...]) */ 332 + if (imap_check_capabilities (idata)) 333 + goto bail; 334 + #if defined(USE_SSL) && !defined(USE_NSS) 335 + /* Attempt STARTTLS if available. TODO: make STARTTLS configurable. */ 336 + if (mutt_bit_isset (idata->capabilities, STARTTLS)) 337 + { 338 + if ((rc = imap_exec (idata, "STARTTLS", IMAP_CMD_FAIL_OK)) == -1) 339 + goto bail; 340 + if (rc != -2) 341 + { 342 + if (mutt_ssl_starttls (idata->conn)) 343 + { 344 + dprint (1, (debugfile, "imap_open_connection: STARTTLS failed\n")); 345 + goto bail; 346 + } 347 + else 348 + { 349 + /* RFC 2595 demands we recheck CAPABILITY after TLS is negotiated. */ 350 + if (imap_exec (idata, "CAPABILITY", 0)) 351 + goto bail; 352 + } 353 + } 354 + } 355 + #endif 356 + if (imap_authenticate (idata)) 328 357 goto bail; 358 + if (idata->conn->ssf) 359 + dprint (2, (debugfile, "Communication encrypted at %d bits\n", 360 + idata->conn->ssf)); 329 361 } 330 362 else if (mutt_strncmp ("* PREAUTH", idata->cmd.buf, 9) == 0) 331 363 {
+4 -3
imap/message.c
··· 1 1 /* 2 2 * Copyright (C) 1996-9 Brandon Long <blong@fiction.net> 3 - * Copyright (C) 1999-2000 Brendan Cully <brendan@kublai.com> 3 + * Copyright (C) 1999-2001 Brendan Cully <brendan@kublai.com> 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify 6 6 * it under the terms of the GNU General Public License as published by ··· 89 89 90 90 for (msgno = msgbegin; msgno <= msgend ; msgno++) 91 91 { 92 - mutt_message (_("Fetching message headers... [%d/%d]"), msgno + 1, 93 - msgend + 1); 92 + if (ReadInc && (!msgno || ((msgno+1) % ReadInc == 0))) 93 + mutt_message (_("Fetching message headers... [%d/%d]"), msgno + 1, 94 + msgend + 1); 94 95 95 96 if (msgno + 1 > fetchlast) 96 97 {
+9 -10
mutt_sasl.c
··· 1 1 /* 2 - * Copyright (C) 2000 Brendan Cully <brendan@kublai.com> 2 + * Copyright (C) 2000-1 Brendan Cully <brendan@kublai.com> 3 3 * 4 4 * This program is free software; you can redistribute it and/or modify 5 5 * it under the terms of the GNU General Public License as published by ··· 21 21 #include "mutt.h" 22 22 #include "account.h" 23 23 #include "mutt_sasl.h" 24 - #ifdef USE_SSL 25 - # include "mutt_ssl.h" 26 - #endif 27 24 #include "mutt_socket.h" 28 25 29 26 #include <sasl.h> 27 + #include <sys/socket.h> 30 28 #include <netinet/in.h> 31 - #include <netdb.h> 32 29 33 30 /* arbitrary. SASL will probably use a smaller buffer anyway. OTOH it's 34 31 * been a while since I've had access to an SASL server which negotiated ··· 129 126 socklen_t size; 130 127 131 128 size = sizeof (local); 132 - if (getsockname (conn->fd, &local, &size)) 129 + if (getsockname (conn->fd, (struct sockaddr*) &local, &size)) 133 130 return -1; 134 131 135 132 size = sizeof(remote); 136 - if (getpeername(conn->fd, &remote, &size)) 133 + if (getpeername(conn->fd, (struct sockaddr*) &remote, &size)) 137 134 return -1; 138 135 139 136 #ifdef SASL_IP_LOCAL ··· 178 175 if (conn->account.flags & M_ACCT_SSL) 179 176 { 180 177 memset (&extprops, 0, sizeof (extprops)); 181 - extprops.ssf = mutt_ssl_get_ssf (conn); 178 + extprops.ssf = conn->ssf; 182 179 dprint (2, (debugfile, "External SSF: %d\n", extprops.ssf)); 183 180 if (sasl_setprop (*saslconn, SASL_SSF_EXTERNAL, &extprops) != SASL_OK) 184 181 { ··· 271 268 sasldata->saslconn = saslconn; 272 269 /* get ssf so we know whether we have to (en|de)code read/write */ 273 270 sasl_getprop (saslconn, SASL_SSF, (void**) &sasldata->ssf); 274 - dprint (2, (debugfile, "SASL protection strength: %u\n", *sasldata->ssf)); 271 + dprint (3, (debugfile, "SASL protection strength: %u\n", *sasldata->ssf)); 272 + /* Add SASL SSF to transport SSF */ 273 + conn->ssf += *sasldata->ssf; 275 274 sasl_getprop (saslconn, SASL_MAXOUTBUF, (void**) &sasldata->pbufsize); 276 - dprint (2, (debugfile, "SASL protection buffer size: %u\n", *sasldata->pbufsize)); 275 + dprint (3, (debugfile, "SASL protection buffer size: %u\n", *sasldata->pbufsize)); 277 276 278 277 /* clear input buffer */ 279 278 sasldata->buf = NULL;
+5 -2
mutt_socket.h
··· 1 1 /* 2 2 * Copyright (C) 1998 Brandon Long <blong@fiction.net> 3 - * Copyright (C) 1999-2000 Brendan Cully <brendan@kublai.com> 3 + * Copyright (C) 1999-2001 Brendan Cully <brendan@kublai.com> 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify 6 6 * it under the terms of the GNU General Public License as published by ··· 31 31 typedef struct _connection 32 32 { 33 33 ACCOUNT account; 34 + /* security strength factor, in bits */ 35 + unsigned int ssf; 36 + void *data; 37 + 34 38 char inbuf[LONG_STRING]; 35 39 int bufpos; 36 40 37 41 int fd; 38 42 int available; 39 - void *data; 40 43 41 44 struct _connection *next; 42 45
+112 -44
mutt_ssl.c
··· 68 68 } 69 69 sslsockdata; 70 70 71 - /* mutt_ssl_get_ssf: Return bit strength of connection encryption. SASL 72 - * uses this to determine how much additional protection to provide, 73 - * if necessary. */ 74 - int mutt_ssl_get_ssf (CONNECTION* conn) 71 + /* local prototypes */ 72 + int ssl_init (void); 73 + static int add_entropy (const char *file); 74 + static int ssl_check_certificate (sslsockdata * data); 75 + static int ssl_socket_read (CONNECTION * conn); 76 + static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len); 77 + static int ssl_socket_open (CONNECTION * conn); 78 + static int ssl_socket_close (CONNECTION * conn); 79 + int ssl_negotiate (sslsockdata*); 80 + 81 + /* mutt_ssl_starttls: Negotiate TLS over an already opened connection. 82 + * TODO: Merge this code better with ssl_socket_open. */ 83 + int mutt_ssl_starttls (CONNECTION* conn) 75 84 { 76 - sslsockdata* ssldata = (sslsockdata*) conn->sockdata; 85 + sslsockdata* ssldata; 77 86 int maxbits; 78 87 79 - return SSL_CIPHER_get_bits (SSL_get_current_cipher (ssldata->ssl), &maxbits); 80 - } 88 + if (ssl_init()) 89 + goto bail; 90 + 91 + ssldata = (sslsockdata*) safe_calloc (1, sizeof (sslsockdata)); 92 + /* the ssl_use_xxx protocol options don't apply. We must use TLS in TLS. */ 93 + if (! (ssldata->ctx = SSL_CTX_new (TLSv1_client_method ()))) 94 + { 95 + dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL_CTX\n")); 96 + goto bail_ssldata; 97 + } 81 98 99 + if (! (ssldata->ssl = SSL_new (ssldata->ctx))) 100 + { 101 + dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL\n")); 102 + goto bail_ctx; 103 + } 82 104 83 - static int add_entropy (const char *file); 105 + if (SSL_set_fd (ssldata->ssl, conn->fd) != 1) 106 + { 107 + dprint (1, (debugfile, "mutt_ssl_starttls: Error setting fd\n")); 108 + goto bail_ssl; 109 + } 110 + 111 + if (ssl_negotiate (ssldata)) 112 + goto bail_ssl; 113 + 114 + /* hmm. watch out if we're starting TLS over any method other than raw. */ 115 + conn->sockdata = ssldata; 116 + conn->read = ssl_socket_read; 117 + conn->write = ssl_socket_write; 118 + conn->close = ssl_socket_close; 119 + 120 + conn->ssf = SSL_CIPHER_get_bits (SSL_get_current_cipher (ssldata->ssl), 121 + &maxbits); 122 + 123 + return 0; 124 + 125 + bail_ssl: 126 + FREE (&ssldata->ssl); 127 + bail_ctx: 128 + FREE (&ssldata->ctx); 129 + bail_ssldata: 130 + FREE (&ssldata); 131 + bail: 132 + return -1; 133 + } 134 + 84 135 /* 85 136 * OpenSSL library needs to be fed with sufficient entropy. On systems 86 137 * with /dev/urandom, this is done transparently by the library itself, ··· 94 145 int ssl_init (void) 95 146 { 96 147 char path[_POSIX_PATH_MAX]; 148 + static unsigned char init_complete = 0; 97 149 98 - if (HAVE_ENTROPY()) return 0; 99 - 100 - /* load entropy from files */ 101 - add_entropy (SslEntropyFile); 102 - add_entropy (RAND_file_name (path, sizeof (path))); 150 + if (init_complete) 151 + return 0; 152 + 153 + if (! HAVE_ENTROPY()) 154 + { 155 + /* load entropy from files */ 156 + add_entropy (SslEntropyFile); 157 + add_entropy (RAND_file_name (path, sizeof (path))); 103 158 104 - /* load entropy from egd sockets */ 159 + /* load entropy from egd sockets */ 105 160 #ifdef HAVE_RAND_EGD 106 - add_entropy (getenv ("EGDSOCKET")); 107 - snprintf (path, sizeof(path), "%s/.entropy", NONULL(Homedir)); 108 - add_entropy (path); 109 - add_entropy ("/tmp/entropy"); 161 + add_entropy (getenv ("EGDSOCKET")); 162 + snprintf (path, sizeof(path), "%s/.entropy", NONULL(Homedir)); 163 + add_entropy (path); 164 + add_entropy ("/tmp/entropy"); 110 165 #endif 111 166 112 - /* shuffle $RANDFILE (or ~/.rnd if unset) */ 113 - RAND_write_file (RAND_file_name (path, sizeof (path))); 114 - mutt_clear_error (); 115 - if (HAVE_ENTROPY()) return 0; 167 + /* shuffle $RANDFILE (or ~/.rnd if unset) */ 168 + RAND_write_file (RAND_file_name (path, sizeof (path))); 169 + mutt_clear_error (); 170 + if (! HAVE_ENTROPY()) 171 + { 172 + mutt_error (_("Failed to find enough entropy on your system")); 173 + sleep (2); 174 + return -1; 175 + } 176 + } 116 177 117 - mutt_error (_("Failed to find enough entropy on your system")); 118 - sleep (2); 119 - return -1; 178 + /* I don't think you can do this just before reading the error. The call 179 + * itself might clobber the last SSL error. */ 180 + SSL_load_error_strings(); 181 + SSL_library_init(); 182 + init_complete = 1; 183 + return 0; 120 184 } 121 185 122 186 static int add_entropy (const char *file) ··· 161 225 return -1; 162 226 } 163 227 164 - static int ssl_check_certificate (sslsockdata * data); 165 - 166 - static int ssl_socket_read (CONNECTION * conn); 167 - static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len); 168 - static int ssl_socket_open (CONNECTION * conn); 169 - static int ssl_socket_close (CONNECTION * conn); 170 228 171 229 int ssl_socket_setup (CONNECTION * conn) 172 230 { ··· 199 257 int ssl_socket_open (CONNECTION * conn) 200 258 { 201 259 sslsockdata *data; 202 - int err; 260 + int maxbits; 203 261 204 262 if (raw_socket_open (conn) < 0) 205 263 return -1; ··· 207 265 data = (sslsockdata *) safe_calloc (1, sizeof (sslsockdata)); 208 266 conn->sockdata = data; 209 267 210 - SSL_library_init(); 211 268 data->ctx = SSL_CTX_new (SSLv23_client_method ()); 212 269 213 270 /* disable SSL protocols as needed */ ··· 227 284 data->ssl = SSL_new (data->ctx); 228 285 SSL_set_fd (data->ssl, conn->fd); 229 286 230 - if ((err = SSL_connect (data->ssl)) != 1) 287 + if (ssl_negotiate(data)) 288 + { 289 + ssl_socket_close (conn); 290 + return -1; 291 + } 292 + 293 + conn->ssf = SSL_CIPHER_get_bits (SSL_get_current_cipher (data->ssl), 294 + &maxbits); 295 + 296 + return 0; 297 + } 298 + 299 + /* ssl_negotiate: After SSL state has been initialised, attempt to negotiate 300 + * SSL over the wire, including certificate checks. */ 301 + int ssl_negotiate (sslsockdata* ssldata) 302 + { 303 + if (SSL_connect (ssldata->ssl) != 1) 231 304 { 232 305 unsigned long e; 233 - SSL_load_error_strings(); 234 306 while ((e = ERR_get_error()) != 0) 235 307 { 236 - mutt_error ("%s", ERR_reason_error_string(e)); 308 + mutt_error ("SSL failed: %s", ERR_reason_error_string(e)); 237 309 sleep (1); 238 310 } 239 - ssl_socket_close (conn); 240 311 return -1; 241 312 } 242 313 243 - data->cert = SSL_get_peer_certificate (data->ssl); 244 - if (!data->cert) 314 + ssldata->cert = SSL_get_peer_certificate (ssldata->ssl); 315 + if (!ssldata->cert) 245 316 { 246 317 mutt_error (_("Unable to get certificate from peer")); 247 318 sleep (1); 248 319 return -1; 249 320 } 250 321 251 - if (!ssl_check_certificate (data)) 252 - { 253 - ssl_socket_close (conn); 322 + if (!ssl_check_certificate (ssldata)) 254 323 return -1; 255 - } 256 324 257 325 mutt_message (_("SSL connection using %s (%s)"), 258 - SSL_get_cipher_version (data->ssl), SSL_get_cipher_name (data->ssl)); 326 + SSL_get_cipher_version (ssldata->ssl), SSL_get_cipher_name (ssldata->ssl)); 259 327 sleep (1); 260 328 261 329 return 0;
+1 -1
mutt_ssl.h
··· 24 24 extern char *SslCertFile; 25 25 extern char *SslEntropyFile; 26 26 27 - int mutt_ssl_get_ssf (CONNECTION* conn); 27 + int mutt_ssl_starttls (CONNECTION* conn); 28 28 29 29 extern int ssl_socket_setup (CONNECTION *conn); 30 30