isync-brokenservers.diff (Jeremy Katz <katzj@linuxpower.org>)

adds support for disabling NAMESPACE, and disable various flavors of TLS/SSL
for use with some broken IMAP servers.
This commit is contained in:
Michael Elkins 2000-12-22 21:22:24 +00:00
parent 04fdf7d120
commit 074298d482
5 changed files with 120 additions and 22 deletions

2
README
View File

@ -26,6 +26,8 @@ maintained, and all flags are synchronized.
``isync'' has been tested with the following IMAP servers: ``isync'' has been tested with the following IMAP servers:
* Microsoft Exchange 2000 IMAP4rev1 server version 6.0.4417.0 * Microsoft Exchange 2000 IMAP4rev1 server version 6.0.4417.0
* Courier-IMAP 1.2.3
* WU-IMAP 2000
* Platforms * Platforms

55
imap.c
View File

@ -132,6 +132,14 @@ init_ssl (config_t * conf)
ERR_error_string (ERR_get_error (), 0)); ERR_error_string (ERR_get_error (), 0));
return -1; return -1;
} }
if (!conf->use_sslv2)
SSL_CTX_set_options (SSLContext, SSL_OP_NO_SSLv2);
if (!conf->use_sslv3)
SSL_CTX_set_options (SSLContext, SSL_OP_NO_SSLv3);
if (!conf->use_tlsv1)
SSL_CTX_set_options (SSLContext, SSL_OP_NO_TLSv1);
/* we check the result of the verification after SSL_connect() */ /* we check the result of the verification after SSL_connect() */
SSL_CTX_set_verify (SSLContext, SSL_VERIFY_NONE, 0); SSL_CTX_set_verify (SSLContext, SSL_VERIFY_NONE, 0);
return 0; return 0;
@ -169,22 +177,27 @@ buffer_gets (buffer_t * b, char **s)
for (;;) for (;;)
{ {
if (b->offset + 2 > b->bytes) /* make sure we have enough data to read the \r\n sequence */
if (b->offset + 1 >= b->bytes)
{ {
/* shift down used bytes */ if (start != 0)
*s = b->buf; {
/* shift down used bytes */
*s = b->buf;
assert (start <= b->bytes); assert (start <= b->bytes);
n = b->bytes - start; n = b->bytes - start;
if (n) if (n)
memmove (b->buf, b->buf + start, n); memmove (b->buf, b->buf + start, n);
b->offset = n; b->offset -= start;
start = 0; b->bytes = n;
start = 0;
}
n = n =
socket_read (b->sock, b->buf + b->offset, socket_read (b->sock, b->buf + b->bytes,
sizeof (b->buf) - b->offset); sizeof (b->buf) - b->bytes);
if (n <= 0) if (n <= 0)
{ {
@ -194,17 +207,18 @@ buffer_gets (buffer_t * b, char **s)
puts ("EOF"); puts ("EOF");
return -1; return -1;
} }
b->bytes = b->offset + n;
// printf ("buffer_gets:read %d bytes\n", n); b->bytes += n;
} }
if (b->buf[b->offset] == '\r') if (b->buf[b->offset] == '\r')
{ {
assert (b->offset + 1 < b->bytes);
if (b->buf[b->offset + 1] == '\n') if (b->buf[b->offset + 1] == '\n')
{ {
b->buf[b->offset] = 0; /* terminate the string */ b->buf[b->offset] = 0; /* terminate the string */
b->offset += 2; /* next line */ b->offset += 2; /* next line */
// assert (strchr (*s, '\r') == 0);
return 0; return 0;
} }
} }
@ -241,6 +255,8 @@ parse_fetch (imap_t * imap, list_t * list)
/* already saw this message */ /* already saw this message */
return 0; return 0;
} }
else if (uid > imap->maxuid)
imap->maxuid = uid;
} }
else else
puts ("Error, unable to parse UID"); puts ("Error, unable to parse UID");
@ -288,6 +304,15 @@ parse_fetch (imap_t * imap, list_t * list)
} }
} }
#if 0
if (uid == 221)
{
int loop = 1;
while (loop);
}
#endif
cur = calloc (1, sizeof (message_t)); cur = calloc (1, sizeof (message_t));
cur->next = imap->msgs; cur->next = imap->msgs;
imap->msgs = cur; imap->msgs = cur;
@ -522,12 +547,12 @@ imap_open (config_t * box, unsigned int minuid)
#endif #endif
puts ("Logging in..."); puts ("Logging in...");
ret = imap_exec (imap, "LOGIN %s %s", box->user, box->pass); ret = imap_exec (imap, "LOGIN \"%s\" \"%s\"", box->user, box->pass);
if (!ret) if (!ret)
{ {
/* get NAMESPACE info */ /* get NAMESPACE info */
if (!imap_exec (imap, "NAMESPACE")) if (box->use_namespace && !imap_exec (imap, "NAMESPACE"))
{ {
/* XXX for now assume personal namespace */ /* XXX for now assume personal namespace */
if (is_list (imap->ns_personal) && if (is_list (imap->ns_personal) &&

34
isync.1
View File

@ -160,6 +160,16 @@ large attachments. If
.I bytes .I bytes
is 0, the maximum file size is is 0, the maximum file size is
.B unlimited. .B unlimited.
..
.TP
\fBUseNamespace\fR \fIyes|no\fR
Selects whether
.B isync
should select mailboxes using the namespace given by the NAMESPACE command.
This is useful with broken IMAP servers. (Default:
.I yes
)
..
.TP .TP
\fBRequireSSL\fR \fIyes|no\fR \fBRequireSSL\fR \fIyes|no\fR
.B isync .B isync
@ -172,6 +182,30 @@ server can not be established. (Default:
\fBCertificateFile\fR \fIpath\fR \fBCertificateFile\fR \fIpath\fR
File containing X.509 CA certificates used to verify server identities. File containing X.509 CA certificates used to verify server identities.
.. ..
.TP
\fBUseSSLv2\fR \fIyes|no\fR
Should
.B isync
use SSLv2 for communication with the IMAP server over SSL? (Default:
.I yes
)
..
.TP
\fBUseSSLv3\fR \fIyes|no\fR
Should
.B isync
use SSLv3 for communication with the IMAP server over SSL? (Default:
.I yes
)
..
.TP
\fBUseTLSv1\fR \fIyes|no\fR
Should
.B isync
use TLSv1 for communication with the IMAP server over SSL? (Default:
.I yes
)
..
.P .P
Configuration commands that appear prior to the first Configuration commands that appear prior to the first
.B Mailbox .B Mailbox

View File

@ -60,7 +60,11 @@ struct config
char *cert_file; char *cert_file;
unsigned int use_imaps:1; unsigned int use_imaps:1;
unsigned int require_ssl:1; unsigned int require_ssl:1;
unsigned int use_sslv2:1;
unsigned int use_sslv3:1;
unsigned int use_tlsv1:1;
#endif #endif
unsigned int use_namespace:1;
}; };
/* struct representing local mailbox file */ /* struct representing local mailbox file */
@ -118,9 +122,6 @@ typedef struct
buffer_t *buf; /* input buffer for reading server output */ buffer_t *buf; /* input buffer for reading server output */
message_t *msgs; /* list of messages on the server */ message_t *msgs; /* list of messages on the server */
config_t *box; /* mailbox to open */ config_t *box; /* mailbox to open */
message_t *recent_msgs; /* list of recent messages - only contains
* UID to be used in a FETCH FLAGS command
*/
unsigned int deleted; /* # of deleted messages */ unsigned int deleted; /* # of deleted messages */
unsigned int uidvalidity; unsigned int uidvalidity;
unsigned int maxuid; unsigned int maxuid;

44
main.c
View File

@ -95,10 +95,14 @@ config_defaults (config_t * conf)
conf->box = global.box; conf->box = global.box;
conf->host = global.host; conf->host = global.host;
conf->max_size = global.max_size; conf->max_size = global.max_size;
conf->use_namespace = global.use_namespace;
#if HAVE_LIBSSL #if HAVE_LIBSSL
conf->require_ssl = global.require_ssl; conf->require_ssl = global.require_ssl;
conf->use_imaps = global.use_imaps; conf->use_imaps = global.use_imaps;
conf->cert_file = global.cert_file; conf->cert_file = global.cert_file;
conf->use_sslv2 = global.use_sslv2;
conf->use_sslv3 = global.use_sslv3;
conf->use_tlsv1 = global.use_tlsv1;
#endif #endif
} }
@ -138,9 +142,9 @@ load_config (char *where)
if (buf[0] == '#') if (buf[0] == '#')
continue; continue;
p = buf; p = buf;
while (*p && !isspace ((unsigned char)*p)) while (*p && !isspace ((unsigned char) *p))
p++; p++;
while (isspace ((unsigned char)*p)) while (isspace ((unsigned char) *p))
p++; p++;
if (!strncasecmp ("mailbox", buf, 7)) if (!strncasecmp ("mailbox", buf, 7))
{ {
@ -213,6 +217,13 @@ load_config (char *where)
else else
global.max_size = atol (p); global.max_size = atol (p);
} }
else if (!strncasecmp ("UseNamespace", buf, 12))
{
if (*cur)
(*cur)->use_namespace = (strcasecmp (p, "yes") == 0);
else
global.use_namespace = (strcasecmp (p, "yes") == 0);
}
#if HAVE_LIBSSL #if HAVE_LIBSSL
else if (!strncasecmp ("CertificateFile", buf, 15)) else if (!strncasecmp ("CertificateFile", buf, 15))
{ {
@ -228,6 +239,27 @@ load_config (char *where)
else else
global.require_ssl = (strcasecmp (p, "yes") == 0); global.require_ssl = (strcasecmp (p, "yes") == 0);
} }
else if (!strncasecmp ("UseSSLv2", buf, 8))
{
if (*cur)
(*cur)->use_sslv2 = (strcasecmp (p, "yes") == 0);
else
global.use_sslv2 = (strcasecmp (p, "yes") == 0);
}
else if (!strncasecmp ("UseSSLv3", buf, 8))
{
if (*cur)
(*cur)->use_sslv3 = (strcasecmp (p, "yes") == 0);
else
global.use_sslv3 = (strcasecmp (p, "yes") == 0);
}
else if (!strncasecmp ("UseTLSv1", buf, 8))
{
if (*cur)
(*cur)->use_tlsv1 = (strcasecmp (p, "yes") == 0);
else
global.use_tlsv1 = (strcasecmp (p, "yes") == 0);
}
#endif #endif
else if (buf[0]) else if (buf[0])
printf ("%s:%d:unknown command:%s", path, line, buf); printf ("%s:%d:unknown command:%s", path, line, buf);
@ -255,7 +287,7 @@ next_arg (char **s)
return 0; return 0;
if (!*s) if (!*s)
return 0; return 0;
while (isspace ((unsigned char)**s)) while (isspace ((unsigned char) **s))
(*s)++; (*s)++;
if (!**s) if (!**s)
{ {
@ -263,7 +295,7 @@ next_arg (char **s)
return 0; return 0;
} }
ret = *s; ret = *s;
while (**s && !isspace ((unsigned char)**s)) while (**s && !isspace ((unsigned char) **s))
(*s)++; (*s)++;
if (**s) if (**s)
*(*s)++ = 0; *(*s)++ = 0;
@ -293,11 +325,15 @@ main (int argc, char **argv)
global.box = "INBOX"; global.box = "INBOX";
global.user = strdup (pw->pw_name); global.user = strdup (pw->pw_name);
global.max_size = 0; global.max_size = 0;
global.use_namespace = 1;
#if HAVE_LIBSSL #if HAVE_LIBSSL
/* this will probably annoy people, but its the best default just in /* this will probably annoy people, but its the best default just in
* case people forget to turn it on * case people forget to turn it on
*/ */
global.require_ssl = 1; global.require_ssl = 1;
global.use_sslv2 = 1;
global.use_sslv3 = 1;
global.use_tlsv1 = 1;
#endif #endif
#if HAVE_GETOPT_LONG #if HAVE_GETOPT_LONG