commit 6c959c3ee4bba035e6ad0e8e71cb7526f503e43b
Author: Oswald Buddenhagen <[email protected]>
Date: Sat Dec 13 18:01:52 2014 +0100
fix handling of unsolicited BYE responses
they can come in at any time, after which we must expect the connection
to be closed (and not complain about it).
src/drv_imap.c | 49 +++++++++++++++++++++++++----------------------
src/socket.c | 19 ++++++-----------
src/socket.h | 9 ++++++++
3 files changed, 42 insertions(+), 35 deletions(-)
diff --git a/src/drv_imap.c b/src/drv_imap.c
index f52992d..7f8f821 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -1203,10 +1203,9 @@ imap_socket_read( void *aux )
imap_store_t *ctx = (imap_store_t *)aux;
struct imap_cmd *cmdp, **pcmdp;
char *cmd, *arg, *arg1, *p;
- int resp, resp2, tag, greeted;
+ int resp, resp2, tag;
conn_iovec_t iov[2];
- greeted = ctx->greeting;
for (;;) {
if (ctx->parse_list_sts.level) {
resp = parse_list_continue( ctx, 0 );
@@ -1236,18 +1235,30 @@ imap_socket_read( void *aux )
break;
}
- if (!strcmp( "NAMESPACE", arg )) {
- resp = parse_list( ctx, cmd,
parse_namespace_rsp );
- goto listret;
- } else if (ctx->greeting == GreetingPending && !strcmp(
"PREAUTH", arg )) {
- ctx->greeting = GreetingPreauth;
+ if (ctx->greeting == GreetingPending && !strcmp(
"PREAUTH", arg )) {
parse_response_code( ctx, 0, cmd );
+ ctx->greeting = GreetingPreauth;
+ dogreet:
+ imap_ref( ctx );
+ imap_open_store_greeted( ctx );
+ if (imap_deref( ctx ))
+ return;
} else if (!strcmp( "OK", arg )) {
- ctx->greeting = GreetingOk;
parse_response_code( ctx, 0, cmd );
+ if (ctx->greeting == GreetingPending) {
+ ctx->greeting = GreetingOk;
+ goto dogreet;
+ }
} else if (!strcmp( "BYE", arg )) {
- ctx->greeting = GreetingBad;
- parse_response_code( ctx, 0, cmd );
+ if (ctx->conn.state != SCK_CLOSING) {
+ ctx->conn.state = SCK_CLOSING;
+ ctx->greeting = GreetingBad;
+ error( "IMAP error: unexpected BYE
response: %s\n", cmd );
+ }
+ /* We just wait for the server to close the
connection now. */
+ } else if (ctx->greeting == GreetingPending) {
+ error( "IMAP error: bogus greeting response
%s\n", arg );
+ break;
} else if (!strcmp( "NO", arg )) {
warn( "Warning from IMAP server: %s\n", cmd );
} else if (!strcmp( "BAD", arg )) {
@@ -1257,6 +1268,9 @@ imap_socket_read( void *aux )
} else if (!strcmp( "LIST", arg )) {
resp = parse_list( ctx, cmd, parse_list_rsp );
goto listret;
+ } else if (!strcmp( "NAMESPACE", arg )) {
+ resp = parse_list( ctx, cmd,
parse_namespace_rsp );
+ goto listret;
} else if ((arg1 = next_arg( &cmd ))) {
if (!strcmp( "EXISTS", arg1 ))
ctx->gen.count = atoi( arg );
@@ -1270,12 +1284,6 @@ imap_socket_read( void *aux )
error( "IMAP error: unrecognized untagged
response '%s'\n", arg );
break; /* this may mean anything, so prefer not
to spam the log */
}
- if (greeted == GreetingPending) {
- imap_ref( ctx );
- imap_open_store_greeted( ctx );
- if (imap_deref( ctx ))
- return;
- }
continue;
} else if (!ctx->in_progress) {
error( "IMAP error: unexpected reply: %s %s\n", arg,
cmd ? cmd : "" );
@@ -1462,6 +1470,7 @@ imap_cleanup( void )
for (ctx = unowned; ctx; ctx = nctx) {
nctx = ctx->next;
set_bad_callback( ctx, (void (*)(void *))imap_cancel_store, ctx
);
+ ((imap_store_t *)ctx)->conn.state = SCK_CLOSING;
imap_exec( (imap_store_t *)ctx, 0, imap_cleanup_p2, "LOGOUT" );
}
}
@@ -1470,7 +1479,7 @@ static void
imap_cleanup_p2( imap_store_t *ctx,
struct imap_cmd *cmd ATTR_UNUSED, int response )
{
- if (response != RESP_CANCEL)
+ if (response == RESP_NO)
imap_cancel_store( &ctx->gen );
}
@@ -1583,12 +1592,6 @@ imap_open_store_tlsstarted1( int ok, void *aux )
static void
imap_open_store_greeted( imap_store_t *ctx )
{
- if (ctx->greeting == GreetingBad) {
- error( "IMAP error: unknown greeting response\n" );
- imap_open_store_bail( ctx );
- return;
- }
-
if (!ctx->caps)
imap_exec( ctx, 0, imap_open_store_p2, "CAPABILITY" );
else
diff --git a/src/socket.c b/src/socket.c
index b300910..56e041a 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -43,14 +43,6 @@
# include <openssl/x509v3.h>
#endif
-enum {
- SCK_CONNECTING,
-#ifdef HAVE_LIBSSL
- SCK_STARTTLS,
-#endif
- SCK_READY
-};
-
static void
socket_fail( conn_t *conn )
{
@@ -74,10 +66,12 @@ ssl_return( const char *func, conn_t *conn, int ret )
case SSL_ERROR_SYSCALL:
case SSL_ERROR_SSL:
if (!(err = ERR_get_error())) {
- if (ret == 0)
- error( "Socket error: secure %s %s: unexpected
EOF\n", func, conn->name );
- else
+ if (ret == 0) {
+ if (conn->state != SCK_CLOSING)
+ error( "Socket error: secure %s %s:
unexpected EOF\n", func, conn->name );
+ } else {
sys_error( "Socket error: secure %s %s", func,
conn->name );
+ }
} else {
error( "Socket error: secure %s %s: %s\n", func,
conn->name, ERR_error_string( err, 0 ) );
}
@@ -588,7 +582,8 @@ do_read( conn_t *sock, char *buf, int len )
sys_error( "Socket error: read from %s", sock->name );
socket_fail( sock );
} else if (!n) {
- error( "Socket error: read from %s: unexpected EOF\n",
sock->name );
+ if (sock->state != SCK_CLOSING)
+ error( "Socket error: read from %s: unexpected
EOF\n", sock->name );
socket_fail( sock );
return -1;
}
diff --git a/src/socket.h b/src/socket.h
index a420e49..20c3033 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -29,6 +29,15 @@
#include <zlib.h>
#endif
+enum {
+ SCK_CONNECTING,
+#ifdef HAVE_LIBSSL
+ SCK_STARTTLS,
+#endif
+ SCK_READY,
+ SCK_CLOSING
+};
+
#ifdef HAVE_LIBSSL
typedef struct ssl_st SSL;
typedef struct ssl_ctx_st SSL_CTX;
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel