소스 검색

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.

Michael Elkins 24 년 전
부모
커밋
074298d482
5개의 변경된 파일120개의 추가작업 그리고 22개의 파일을 삭제
  1. 2 0
      README
  2. 40 15
      imap.c
  3. 34 0
      isync.1
  4. 4 3
      isync.h
  5. 40 4
      main.c

+ 2 - 0
README

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

+ 40 - 15
imap.c

@@ -132,6 +132,14 @@ init_ssl (config_t * conf)
 		ERR_error_string (ERR_get_error (), 0));
 	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() */
     SSL_CTX_set_verify (SSLContext, SSL_VERIFY_NONE, 0);
     return 0;
@@ -169,22 +177,27 @@ buffer_gets (buffer_t * b, char **s)
 
     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 */
-	    *s = b->buf;
+	    if (start != 0)
+	    {
+		/* shift down used bytes */
+		*s = b->buf;
 
-	    assert (start <= b->bytes);
-	    n = b->bytes - start;
+		assert (start <= b->bytes);
+		n = b->bytes - start;
 
-	    if (n)
-		memmove (b->buf, b->buf + start, n);
-	    b->offset = n;
-	    start = 0;
+		if (n)
+		    memmove (b->buf, b->buf + start, n);
+		b->offset -= start;
+		b->bytes = n;
+		start = 0;
+	    }
 
 	    n =
-		socket_read (b->sock, b->buf + b->offset,
-			     sizeof (b->buf) - b->offset);
+		socket_read (b->sock, b->buf + b->bytes,
+			     sizeof (b->buf) - b->bytes);
 
 	    if (n <= 0)
 	    {
@@ -194,17 +207,18 @@ buffer_gets (buffer_t * b, char **s)
 		    puts ("EOF");
 		return -1;
 	    }
-	    b->bytes = b->offset + n;
 
-//          printf ("buffer_gets:read %d bytes\n", n);
+	    b->bytes += n;
 	}
 
 	if (b->buf[b->offset] == '\r')
 	{
+	    assert (b->offset + 1 < b->bytes);
 	    if (b->buf[b->offset + 1] == '\n')
 	    {
 		b->buf[b->offset] = 0;	/* terminate the string */
 		b->offset += 2;	/* next line */
+//              assert (strchr (*s, '\r') == 0);
 		return 0;
 	    }
 	}
@@ -241,6 +255,8 @@ parse_fetch (imap_t * imap, list_t * list)
 			/* already saw this message */
 			return 0;
 		    }
+		    else if (uid > imap->maxuid)
+			imap->maxuid = uid;
 		}
 		else
 		    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->next = imap->msgs;
     imap->msgs = cur;
@@ -522,12 +547,12 @@ imap_open (config_t * box, unsigned int minuid)
 #endif
 
     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)
     {
 	/* get NAMESPACE info */
-	if (!imap_exec (imap, "NAMESPACE"))
+	if (box->use_namespace && !imap_exec (imap, "NAMESPACE"))
 	{
 	    /* XXX for now assume personal namespace */
 	    if (is_list (imap->ns_personal) &&

+ 34 - 0
isync.1

@@ -160,6 +160,16 @@ large attachments.  If
 .I bytes
 is 0, the maximum file size is
 .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
 \fBRequireSSL\fR \fIyes|no\fR
 .B isync
@@ -172,6 +182,30 @@ server can not be established.  (Default:
 \fBCertificateFile\fR \fIpath\fR
 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
 Configuration commands that appear prior to the first
 .B Mailbox

+ 4 - 3
isync.h

@@ -60,7 +60,11 @@ struct config
     char *cert_file;
     unsigned int use_imaps:1;
     unsigned int require_ssl:1;
+    unsigned int use_sslv2:1;
+    unsigned int use_sslv3:1;
+    unsigned int use_tlsv1:1;
 #endif
+    unsigned int use_namespace:1;
 };
 
 /* struct representing local mailbox file */
@@ -118,9 +122,6 @@ typedef struct
     buffer_t *buf;		/* input buffer for reading server output */
     message_t *msgs;		/* list of messages on the server */
     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 uidvalidity;
     unsigned int maxuid;

+ 40 - 4
main.c

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