From 09540b5648aecd1bd2e29db0b6201ca71381a058 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Sun, 2 Aug 2020 20:05:42 +0200 Subject: [PATCH 1/7] unbreak CertificateFile documentation the file may in fact contain CA certs. amends 7d9d3e15. --- src/mbsync.1 | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/mbsync.1 b/src/mbsync.1 index 6830508..dfdba79 100644 --- a/src/mbsync.1 +++ b/src/mbsync.1 @@ -379,17 +379,27 @@ if you want to trust only hand-picked certificates. \fBCertificateFile\fR \fIpath\fR File containing additional X.509 certificates used to verify server identities. -These certificates are always trusted, regardless of validity. +It may contain two types of certificates: +.RS +.IP Host +These certificates are matched only against the received server certificate +itself. +They are always trusted, regardless of validity. +A typical use case would be forcing acceptance of an expired certificate. .br -The certificates from this file are matched only against the received -server certificate itself; CA certificates are \fBnot\fR supported here. -Do \fBnot\fR specify the system's CA certificate store here; see -\fBSystemCertificates\fR instead. -.br -The contents for this file may be obtained using the -\fBmbsync-get-cert\fR tool; make sure to verify the fingerprints of the -certificates before trusting them, or transfer them securely from the -server's network (if it is trusted). +These certificates may be obtained using the \fBmbsync-get-cert\fR tool; +make sure to verify their fingerprints before trusting them, or transfer +them securely from the server's network (if it can be trusted beyond the +server itself). +.IP CA +These certificates are used as trust anchors when building the certificate +chain for the received server certificate. +They are used to supplant or supersede the system's trust store, depending +on the \fBSystemCertificates\fR setting; +it is not necessary and not recommended to specify the system's trust store +itself here. +The trust chains are fully validated. +.RE . .TP \fBClientCertificate\fR \fIpath\fR From 3651c30296cbe8995b8a9c1c839088fa03778540 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 28 Jul 2020 00:28:11 +0200 Subject: [PATCH 2/7] increase PassCmd output buffer even more apparently, some XOAUTH2 tokens are at 2.4K already, so make it 8K to be *really* safe for a while. REFMAIL: <20200716000515.GA2111668@lysator.liu.se> --- src/drv_imap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drv_imap.c b/src/drv_imap.c index 4ea86d6..d429bcb 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -1893,7 +1893,7 @@ ensure_password( imap_server_conf_t *srvc ) if (cmd) { FILE *fp; int ret; - char buffer[2048]; // Hopefully more than enough room for XOAUTH2, etc. tokens + char buffer[8192]; // Hopefully more than enough room for XOAUTH2, etc. tokens if (*cmd == '+') { flushn(); From 813ad67c5664019d198b5c0832c10142a20f2793 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 27 Jul 2020 22:48:41 +0200 Subject: [PATCH 3/7] fix simultaneously connecting to multiple hosts in non-IPv6 builds we need to deep-copy the struct hostent data, as otherwise the concurrent connects will overwrite each other's lookup results. this is a rather hypothetical fix, as the bug currently affects only channels connecting two IMAP accounts, and only if the first host's first address asynchronously fails to connect. --- src/socket.c | 52 +++++++++++++++++++++++++++++----------------------- src/socket.h | 2 +- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/socket.c b/src/socket.c index dbd781c..6078f99 100644 --- a/src/socket.c +++ b/src/socket.c @@ -430,6 +430,32 @@ socket_close_internal( conn_t *sock ) sock->fd = -1; } +#ifndef HAVE_IPV6 +struct addr_info { + struct addr_info *ai_next; + struct sockaddr_in ai_addr[1]; +}; + +#define freeaddrinfo(ai) free( ai ) + +static struct addr_info * +init_addrinfo( struct hostent *he ) +{ + uint naddr = 0; + for (char **addr = he->h_addr_list; *addr; addr++) + naddr++; + struct addr_info *caddr = nfcalloc( naddr * sizeof(struct addrinfo) ); + struct addr_info *ret, **caddrp = &ret; + for (char **addr = he->h_addr_list; *addr; addr++, caddr++) { + caddr->ai_addr->sin_family = AF_INET; + memcpy( &caddr->ai_addr->sin_addr.s_addr, *addr, sizeof(struct in_addr) ); + *caddrp = caddr; + caddrp = &caddr->ai_next; + } + return ret; +} +#endif + void socket_connect( conn_t *sock, void (*cb)( int ok, void *aux ) ) { @@ -479,8 +505,6 @@ socket_connect( conn_t *sock, void (*cb)( int ok, void *aux ) ) return; } info( "\vok\n" ); - - sock->curr_addr = sock->addrs; #else struct hostent *he; @@ -493,8 +517,9 @@ socket_connect( conn_t *sock, void (*cb)( int ok, void *aux ) ) } info( "\vok\n" ); - sock->curr_addr = he->h_addr_list; + sock->addrs = init_addrinfo( he ); #endif + sock->curr_addr = sock->addrs; socket_connect_one( sock ); } } @@ -506,16 +531,10 @@ socket_connect_one( conn_t *sock ) #ifdef HAVE_IPV6 struct addrinfo *ai; #else - struct { - struct sockaddr_in ai_addr[1]; - } ai[1]; + struct addr_info *ai; #endif -#ifdef HAVE_IPV6 if (!(ai = sock->curr_addr)) { -#else - if (!*sock->curr_addr) { -#endif error( "No working address found for %s\n", sock->conf->host ); socket_connect_bail( sock ); return; @@ -532,11 +551,6 @@ socket_connect_one( conn_t *sock ) #endif { struct sockaddr_in *in = ((struct sockaddr_in *)ai->ai_addr); -#ifndef HAVE_IPV6 - memset( in, 0, sizeof(*in) ); - in->sin_family = AF_INET; - in->sin_addr.s_addr = *((int *)*sock->curr_addr); -#endif in->sin_port = htons( sock->conf->port ); nfasprintf( &sock->name, "%s (%s:%hu)", sock->conf->host, inet_ntoa( in->sin_addr ), sock->conf->port ); @@ -579,11 +593,7 @@ socket_connect_next( conn_t *conn ) sys_error( "Cannot connect to %s", conn->name ); free( conn->name ); conn->name = 0; -#ifdef HAVE_IPV6 conn->curr_addr = conn->curr_addr->ai_next; -#else - conn->curr_addr++; -#endif socket_connect_one( conn ); } @@ -597,12 +607,10 @@ socket_connect_failed( conn_t *conn ) static void socket_connected( conn_t *conn ) { -#ifdef HAVE_IPV6 if (conn->addrs) { freeaddrinfo( conn->addrs ); conn->addrs = 0; } -#endif conf_notifier( &conn->notify, 0, POLLIN ); socket_expect_read( conn, 0 ); conn->state = SCK_READY; @@ -612,12 +620,10 @@ socket_connected( conn_t *conn ) static void socket_cleanup_names( conn_t *conn ) { -#ifdef HAVE_IPV6 if (conn->addrs) { freeaddrinfo( conn->addrs ); conn->addrs = 0; } -#endif free( conn->name ); conn->name = 0; } diff --git a/src/socket.h b/src/socket.h index f80c2ef..1fdd7aa 100644 --- a/src/socket.h +++ b/src/socket.h @@ -73,7 +73,7 @@ typedef struct { #ifdef HAVE_IPV6 struct addrinfo *addrs, *curr_addr; /* needed during connect */ #else - char **curr_addr; /* needed during connect */ + struct addr_info *addrs, *curr_addr; /* needed during connect */ #endif char *name; #ifdef HAVE_LIBSSL From c82397cf6e6c3c89b3b5bce6836bf17208abae70 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 3 Aug 2020 12:39:33 +0200 Subject: [PATCH 4/7] don't crash in proxy_invoke_bad_callback() we need to hold a ref to the proxy store, as after the bad_callback() it's otherwise likely gone. --- src/drv_proxy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/drv_proxy.c b/src/drv_proxy.c index 6a62f22..1188f1f 100644 --- a/src/drv_proxy.c +++ b/src/drv_proxy.c @@ -306,9 +306,11 @@ proxy_set_bad_callback( store_t *gctx, void (*cb)( void *aux ), void *aux ) static void proxy_invoke_bad_callback( proxy_store_t *ctx ) { + ctx->ref_count++; debug( "%sCallback enter bad store\n", ctx->label ); ctx->bad_callback( ctx->bad_callback_aux ); - debug( "%sCallback leave bad store\n", ctx->label ); \ + debug( "%sCallback leave bad store\n", ctx->label ); + proxy_store_deref( ctx ); } //# EXCLUDE alloc_store From 542e38dd49b4ac0ecf96637be289b6e71ac84990 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 4 Aug 2020 10:10:47 +0200 Subject: [PATCH 5/7] fix re-using server connections for new stores we failed to reset the box list pointer after freeing it, which would lead to a crash. we also failed to reset the listing status, which would lead to malfunction if we hadn't already crashed. this inlines imap_cleanup_store(), as there isn't much value in keeping it. the message list is already freed when disowning the store anyway. --- src/drv_imap.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/drv_imap.c b/src/drv_imap.c index d429bcb..fbf3072 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -1558,14 +1558,6 @@ get_cmd_result_p2( imap_store_t *ctx, imap_cmd_t *cmd, int response ) /******************* imap_cancel_store *******************/ - -static void -imap_cleanup_store( imap_store_t *ctx ) -{ - free_generic_messages( ctx->msgs ); - free_string_list( ctx->boxes ); -} - static void imap_cancel_store( store_t *gctx ) { @@ -1581,7 +1573,8 @@ imap_cancel_store( store_t *gctx ) free_list( ctx->ns_other ); free_list( ctx->ns_shared ); free_string_list( ctx->auth_mechs ); - imap_cleanup_store( ctx ); + free_generic_messages( ctx->msgs ); + free_string_list( ctx->boxes ); imap_deref( ctx ); } @@ -1718,7 +1711,9 @@ imap_alloc_store( store_conf_t *conf, const char *label ) for (ctxp = &unowned; (ctx = (imap_store_t *)*ctxp); ctxp = &ctx->gen.next) if (ctx->state != SST_BAD && ((imap_store_conf_t *)ctx->gen.conf)->server == srvc) { *ctxp = ctx->gen.next; - imap_cleanup_store( ctx ); + free_string_list( ctx->boxes ); + ctx->boxes = NULL; + ctx->listed = 0; /* One could ping the server here, but given that the idle timeout * is at least 30 minutes, this sounds pretty pointless. */ ctx->state = SST_HALF; From 30261fe6f17b24bd57008ffde9650cd1a13d9cbd Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 4 Aug 2020 11:17:56 +0200 Subject: [PATCH 6/7] fix version comparison in LibreSSL conditional the operator was exactly inverted. that means that it actually wouldn't compile with both older versions (that needed the aliases) and potentially new versions (that will hide the data members - still not the case as of 3.2). amends 8a40554f0. --- src/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socket.c b/src/socket.c index 6078f99..84449e7 100644 --- a/src/socket.c +++ b/src/socket.c @@ -41,7 +41,7 @@ # include # include # if OPENSSL_VERSION_NUMBER < 0x10100000L \ - || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070100fL) + || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070100fL) # define X509_OBJECT_get0_X509(o) ((o)->data.x509) # define X509_STORE_get0_objects(o) ((o)->objs) # endif From c97e650c241536b5fafcccd138428d1c7a22cdd7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 4 Aug 2020 14:44:17 +0200 Subject: [PATCH 7/7] bump version --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ca3ee33..188d712 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([isync], [1.3.2]) +AC_INIT([isync], [1.3.3]) AC_CONFIG_HEADERS([autodefs.h]) AM_INIT_AUTOMAKE