Skipped 15 existing revision(s) on branch 'master'.

commit 462fed556a4ccb57c1259570583d846d343cc628
Merge: a310e7e d0a8551
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Thu Oct 3 20:17:54 2019 +0200

    Merge branch '1.3'

 configure.ac         |   6 +--
 src/common.h         |   1 +
 src/drv_imap.c       |  28 +++++++----
 src/drv_proxy_gen.pl |   1 +
 src/mbsync.1         |  15 +++---
 src/socket.c         | 111 ++++++++++++++++++++++++++++++++-----------
 6 files changed, 114 insertions(+), 48 deletions(-)


===== Full diff against 1st parent =====

diff --git a/configure.ac b/configure.ac
index 880f17c..a4c002d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,14 +18,14 @@ fi
 
 need_perl=5.14
 AC_CACHE_CHECK([whether perl is recent enough], ob_cv_perl_ver, [
-    if $PERL -e "use v$need_perl;"; then
+    if $PERL -e "use v$need_perl;" 2> /dev/null; then
         ob_cv_perl_ver=yes
     else
         ob_cv_perl_ver=no
     fi
 ])
 if test "x$ob_cv_perl_ver" = "xno"; then
-    AC_MSG_ERROR([perl is too old])
+    AC_MSG_ERROR([perl is too old, need v$need_perl])
 fi
 
 AC_CACHE_CHECK([whether strftime supports %z], ob_cv_strftime_z,
@@ -94,7 +94,7 @@ if test "x$ob_cv_with_ssl" != xno; then
     sav_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS $SSL_LDFLAGS"
     AC_CHECK_LIB(dl, dlopen, [LIBDL=-ldl])
-    AC_CHECK_LIB(crypto, CRYPTO_lock, [LIBCRYPTO=-lcrypto])
+    AC_CHECK_LIB(crypto, X509_cmp, [LIBCRYPTO=-lcrypto])
     AC_CHECK_LIB(ssl, SSL_connect,
                  [SSL_LIBS="-lssl $LIBCRYPTO $LIBDL" have_ssl_paths=yes])
     LDFLAGS=$sav_LDFLAGS
diff --git a/src/common.h b/src/common.h
index c731126..d45929c 100644
--- a/src/common.h
+++ b/src/common.h
@@ -33,6 +33,7 @@
 typedef unsigned char uchar;
 typedef unsigned short ushort;
 typedef unsigned int uint;
+typedef unsigned long ulong;
 
 #define as(ar) (sizeof(ar)/sizeof(ar[0]))
 
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 58fc9d3..7bc88f6 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -953,7 +953,7 @@ parse_date( const char *str )
        struct tm datetime;
 
        memset( &datetime, 0, sizeof(datetime) );
-       if (!(end = strptime( str, "%d-%b-%Y %H:%M:%S ", &datetime )))
+       if (!(end = strptime( str, "%e-%b-%Y %H:%M:%S ", &datetime )))
                return -1;
        if ((date = timegm( &datetime )) == -1)
                return -1;
@@ -1203,17 +1203,16 @@ parse_response_code( imap_store_t *ctx, imap_cmd_t 
*cmd, char *s )
        return RESP_OK;
 }
 
+static int parse_list_rsp_p1( imap_store_t *, list_t *, char * );
 static int parse_list_rsp_p2( imap_store_t *, list_t *, char * );
 
 static int
 parse_list_rsp( imap_store_t *ctx, list_t *list, char *cmd )
 {
-       char *arg;
        list_t *lp;
 
        if (!is_list( list )) {
                free_list( list );
-         bad_list:
                error( "IMAP error: malformed LIST response\n" );
                return LIST_BAD;
        }
@@ -1223,10 +1222,19 @@ parse_list_rsp( imap_store_t *ctx, list_t *list, char 
*cmd )
                        return LIST_OK;
                }
        free_list( list );
-       if (!(arg = next_arg( &cmd )))
-               goto bad_list;
-       if (!ctx->delimiter[0])
-               ctx->delimiter[0] = arg[0];
+       return parse_list( ctx, cmd, parse_list_rsp_p1 );
+}
+
+static int
+parse_list_rsp_p1( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED )
+{
+       if (!is_opt_atom( list )) {
+               error( "IMAP error: malformed LIST response\n" );
+               free_list( list );
+               return LIST_BAD;
+       }
+       if (!ctx->delimiter[0] && is_atom( list ))
+               ctx->delimiter[0] = list->val[0];
        return parse_list( ctx, cmd, parse_list_rsp_p2 );
 }
 
@@ -1873,7 +1881,7 @@ ensure_password( imap_server_conf_t *srvc )
        if (cmd) {
                FILE *fp;
                int ret;
-               char buffer[80];
+               char buffer[2048];  // Hopefully more than enough room for 
XOAUTH2, etc. tokens
 
                if (*cmd == '+') {
                        flushn();
@@ -2079,7 +2087,7 @@ done_sasl_auth( imap_store_t *ctx, imap_cmd_t *cmd 
ATTR_UNUSED, int response )
                int rc = sasl_client_step( ctx->sasl, NULL, 0, &interact, &out, 
&out_len );
                if (process_sasl_step( ctx, rc, NULL, 0, interact, &out, 
&out_len ) < 0)
                        warn( "Warning: SASL reported failure despite 
successful IMAP authentication. Ignoring...\n" );
-               else if (out)
+               else if (out_len > 0)
                        warn( "Warning: SASL wants more steps despite 
successful IMAP authentication. Ignoring...\n" );
        }
 
@@ -2180,7 +2188,7 @@ imap_open_store_authenticate2( imap_store_t *ctx )
                free( enc );
                return;
          notsasl:
-               if (!ctx->sasl || sasl_listmech( ctx->sasl, NULL, "", "", "", 
&saslavail, NULL, NULL ) != SASL_OK)
+               if (!ctx->sasl || sasl_listmech( ctx->sasl, NULL, "", " ", "", 
&saslavail, NULL, NULL ) != SASL_OK)
                        saslavail = "(none)";  /* EXTERNAL is always there 
anyway. */
                if (!auth_login) {
                        error( "IMAP error: selected SASL mechanism(s) not 
available;\n"
diff --git a/src/drv_proxy_gen.pl b/src/drv_proxy_gen.pl
index f2ef3fd..c7119a6 100755
--- a/src/drv_proxy_gen.pl
+++ b/src/drv_proxy_gen.pl
@@ -109,6 +109,7 @@ sub type_to_format($)
 {
        $_ = shift;
        s/xint /\%\#x/g;
+       s/uint /\%u/g;
        s/int /\%d/g;
        s/const char \*/\%s/g;
        return $_;
diff --git a/src/mbsync.1 b/src/mbsync.1
index 4dcd5aa..8f6c58b 100644
--- a/src/mbsync.1
+++ b/src/mbsync.1
@@ -267,7 +267,7 @@ with DOS/Windows file systems.
 .TP
 \fBSubFolders\fR \fBVerbatim\fR|\fBMaildir++\fR|\fBLegacy\fR
 The on-disk folder naming style used for hierarchical mailboxes.
-This has option has no effect when \fBFlatten\fR is used.
+This option has no effect when \fBFlatten\fR is used.
 .br
 Suppose mailboxes with the canonical paths \fBtop/sub/subsub\fR and
 \fBINBOX/sub/subsub\fR, the styles will yield the following on-disk paths:
@@ -601,12 +601,13 @@ which in turn are overridden by command line switches.
 ..
 .TP
 \fBSyncState\fR {\fB*\fR|\fIpath\fR}
-Set the location of this Channel's synchronization state files. \fB*\fR means
-that the state should be saved in a file named .mbsyncstate in the
-Slave mailbox itself; this has the advantage that you needn't to care for the
-state file if you delete the mailbox, but it works only with Maildir mailboxes,
-obviously. Otherwise this is interpreted as a string to prepend to the Slave
-mailbox name to make up a complete path.
+Set the location of this Channel's synchronization state files.
+\fB*\fR means that the state should be saved in a file named .mbsyncstate
+in the Slave mailbox itself; this has the advantage that you do not need
+to handle the state file separately if you delete the mailbox, but it works
+only with Maildir mailboxes, obviously.
+Otherwise this is interpreted as a string to prepend to the Slave mailbox
+name to make up a complete path.
 .br
 This option can be used outside any section for a global effect. In this case
 the appended string is made up according to the pattern
diff --git a/src/socket.c b/src/socket.c
index e3fda42..950c956 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -63,6 +63,34 @@ socket_fail( conn_t *conn )
 }
 
 #ifdef HAVE_LIBSSL
+static void ATTR_PRINTFLIKE(1, 2)
+print_ssl_errors( const char *fmt, ... )
+{
+       char *action;
+       va_list va;
+       ulong err;
+
+       va_start( va, fmt );
+       nfvasprintf( &action, fmt, va );
+       va_end( va );
+       while ((err = ERR_get_error()))
+               error( "Error while %s: %s\n", action, ERR_error_string( err, 0 
) );
+       free( action );
+}
+
+static int
+print_ssl_socket_errors( const char *func, conn_t *conn )
+{
+       ulong err;
+       int num = 0;
+
+       while ((err = ERR_get_error())) {
+               error( "Socket error: secure %s %s: %s\n", func, conn->name, 
ERR_error_string( err, 0 ) );
+               num++;
+       }
+       return num;
+}
+
 static int
 ssl_return( const char *func, conn_t *conn, int ret )
 {
@@ -76,20 +104,20 @@ ssl_return( const char *func, conn_t *conn, int ret )
                FALLTHROUGH
        case SSL_ERROR_WANT_READ:
                return 0;
-       case SSL_ERROR_SYSCALL:
        case SSL_ERROR_SSL:
-               if (!(err = ERR_get_error())) {
-                       if (ret == 0) {
+               print_ssl_socket_errors( func, conn );
+               break;
+       case SSL_ERROR_SYSCALL:
+               if (print_ssl_socket_errors( func, conn ))
+                       break;
+               if (ret == 0) {
        case SSL_ERROR_ZERO_RETURN:
-                               /* Callers take the short path out, so signal 
higher layers from here. */
-                               conn->state = SCK_EOF;
-                               conn->read_callback( conn->callback_aux );
-                               return -1;
-                       }
-                       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 ) );
+                       /* Callers take the short path out, so signal higher 
layers from here. */
+                       conn->state = SCK_EOF;
+                       conn->read_callback( conn->callback_aux );
+                       return -1;
                }
+               sys_error( "Socket error: secure %s %s", func, conn->name );
                break;
        default:
                error( "Socket error: secure %s %s: unhandled SSL error %d\n", 
func, conn->name, err );
@@ -176,22 +204,29 @@ verify_cert_host( const server_conf_t *conf, conn_t *sock 
)
 
        trusted = (STACK_OF(X509_OBJECT) *)sock->conf->trusted_certs;
        for (i = 0; i < sk_X509_OBJECT_num( trusted ); i++) {
-               if (!X509_cmp( cert, X509_OBJECT_get0_X509( 
sk_X509_OBJECT_value( trusted, i ) ) ))
+               if (!X509_cmp( cert, X509_OBJECT_get0_X509( 
sk_X509_OBJECT_value( trusted, i ) ) )) {
+                       X509_free( cert );
                        return 0;
+               }
        }
 
        err = SSL_get_verify_result( sock->ssl );
        if (err != X509_V_OK) {
                error( "SSL error connecting %s: %s\n", sock->name, 
X509_verify_cert_error_string( err ) );
+               X509_free( cert );
                return -1;
        }
 
        if (!conf->host) {
                error( "SSL error connecting %s: Neither host nor matching 
certificate specified\n", sock->name );
+               X509_free( cert );
                return -1;
        }
 
-       return verify_hostname( cert, conf->host );
+       int ret = verify_hostname( cert, conf->host );
+
+       X509_free( cert );
+       return ret;
 }
 
 static int
@@ -203,7 +238,15 @@ init_ssl_ctx( const server_conf_t *conf )
        if (conf->SSLContext)
                return conf->ssl_ctx_valid;
 
-       mconf->SSLContext = SSL_CTX_new( SSLv23_client_method() );
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+       const SSL_METHOD *method = TLS_client_method();
+#else
+       const SSL_METHOD *method = SSLv23_client_method();
+#endif
+       if (!(mconf->SSLContext = SSL_CTX_new( method ))) {
+               print_ssl_errors( "initializing SSL context" );
+               return 0;
+       }
 
        if (!(conf->ssl_versions & SSLv3))
                options |= SSL_OP_NO_SSLv3;
@@ -221,25 +264,24 @@ init_ssl_ctx( const server_conf_t *conf )
        SSL_CTX_set_options( mconf->SSLContext, options );
 
        if (conf->cert_file && !SSL_CTX_load_verify_locations( 
mconf->SSLContext, conf->cert_file, 0 )) {
-               error( "Error while loading certificate file '%s': %s\n",
-                      conf->cert_file, ERR_error_string( ERR_get_error(), 0 ) 
);
+               print_ssl_errors( "loading certificate file '%s'", 
conf->cert_file );
                return 0;
        }
        mconf->trusted_certs = (_STACK *)sk_X509_OBJECT_dup( 
X509_STORE_get0_objects( SSL_CTX_get_cert_store( mconf->SSLContext ) ) );
-       if (mconf->system_certs && !SSL_CTX_set_default_verify_paths( 
mconf->SSLContext ))
-               warn( "Warning: Unable to load default certificate files: %s\n",
-                     ERR_error_string( ERR_get_error(), 0 ) );
+       if (mconf->system_certs && !SSL_CTX_set_default_verify_paths( 
mconf->SSLContext )) {
+               ulong err;
+               while ((err = ERR_get_error()))
+                       warn( "Warning: Unable to load default certificate 
files: %s\n", ERR_error_string( err, 0 ) );
+       }
 
        SSL_CTX_set_verify( mconf->SSLContext, SSL_VERIFY_NONE, NULL );
 
        if (conf->client_certfile && !SSL_CTX_use_certificate_chain_file( 
mconf->SSLContext, conf->client_certfile)) {
-               error( "Error while loading client certificate file '%s': %s\n",
-                      conf->client_certfile, ERR_error_string( 
ERR_get_error(), 0 ) );
+               print_ssl_errors( "loading client certificate file '%s'", 
conf->client_certfile );
                return 0;
        }
        if (conf->client_keyfile && !SSL_CTX_use_PrivateKey_file( 
mconf->SSLContext, conf->client_keyfile, SSL_FILETYPE_PEM)) {
-               error( "Error while loading client private key '%s': %s\n",
-                      conf->client_keyfile, ERR_error_string( ERR_get_error(), 
0 ) );
+               print_ssl_errors( "loading client private key '%s'", 
conf->client_keyfile );
                return 0;
        }
 
@@ -270,10 +312,21 @@ socket_start_tls( conn_t *conn, void (*cb)( int ok, void 
*aux ) )
        }
 
        init_wakeup( &conn->ssl_fake, ssl_fake_cb, conn );
-       conn->ssl = SSL_new( ((server_conf_t *)conn->conf)->SSLContext );
-       if (ssl_return( "set server name", conn, SSL_set_tlsext_host_name( 
conn->ssl, conn->conf->host ) ) < 0)
+       if (!(conn->ssl = SSL_new( ((server_conf_t *)conn->conf)->SSLContext 
))) {
+               print_ssl_errors( "initializing SSL connection" );
+               start_tls_p3( conn, 0 );
+               return;
+       }
+       if (!SSL_set_tlsext_host_name( conn->ssl, conn->conf->host )) {
+               print_ssl_errors( "setting SSL server host name" );
+               start_tls_p3( conn, 0 );
                return;
-       SSL_set_fd( conn->ssl, conn->fd );
+       }
+       if (!SSL_set_fd( conn->ssl, conn->fd )) {
+               print_ssl_errors( "setting SSL socket fd" );
+               start_tls_p3( conn, 0 );
+               return;
+       }
        SSL_set_mode( conn->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER );
        socket_expect_read( conn, 1 );
        conn->state = SCK_STARTTLS;
@@ -545,8 +598,10 @@ static void
 socket_connected( conn_t *conn )
 {
 #ifdef HAVE_IPV6
-       freeaddrinfo( conn->addrs );
-       conn->addrs = 0;
+       if (conn->addrs) {
+               freeaddrinfo( conn->addrs );
+               conn->addrs = 0;
+       }
 #endif
        conf_notifier( &conn->notify, 0, POLLIN );
        socket_expect_read( conn, 0 );


_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to