isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit 5fee222f8408d5dd82b40d53c663b8ceffa13914
parent cab14608caa7b99478c86b526179b3990359ea1e
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Tue,  4 Aug 2020 14:48:58 +0200

Merge branch '1.3'

Diffstat:
Msrc/drv_imap.c | 17++++++-----------
Msrc/drv_proxy.c | 4+++-
Msrc/mbsync.1 | 32+++++++++++++++++++++-----------
Msrc/socket.c | 54++++++++++++++++++++++++++++++------------------------
Msrc/socket.h | 2+-
5 files changed, 61 insertions(+), 48 deletions(-)

diff --git a/src/drv_imap.c b/src/drv_imap.c @@ -1586,14 +1586,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 ) { @@ -1609,7 +1601,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 ); } @@ -1746,7 +1739,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; @@ -1921,7 +1916,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(); diff --git a/src/drv_proxy.c b/src/drv_proxy.c @@ -309,9 +309,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 diff --git 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. -.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). +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 +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 diff --git a/src/socket.c b/src/socket.c @@ -41,7 +41,7 @@ # include <openssl/err.h> # include <openssl/x509v3.h> # 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 @@ -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 @@ -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