Merge branch '1.2'
Conflicts: src/drv_imap.c
This commit is contained in:
commit
ab955ffe6b
|
@ -641,6 +641,12 @@ next_arg( char **ps )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_opt_atom( list_t *list )
|
||||||
|
{
|
||||||
|
return list && list->val && list->val != LIST;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_atom( list_t *list )
|
is_atom( list_t *list )
|
||||||
{
|
{
|
||||||
|
@ -841,33 +847,50 @@ static int parse_namespace_rsp_p2( imap_store_t *, list_t *, char * );
|
||||||
static int parse_namespace_rsp_p3( imap_store_t *, list_t *, char * );
|
static int parse_namespace_rsp_p3( imap_store_t *, list_t *, char * );
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_namespace_rsp_fail( void )
|
parse_namespace_check( list_t *list )
|
||||||
{
|
{
|
||||||
|
if (!list)
|
||||||
|
goto bad;
|
||||||
|
if (list->val == NIL)
|
||||||
|
return 0;
|
||||||
|
if (list->val != LIST)
|
||||||
|
goto bad;
|
||||||
|
for (list = list->child; list; list = list->next) {
|
||||||
|
if (list->val != LIST)
|
||||||
|
goto bad;
|
||||||
|
if (!is_atom( list->child ))
|
||||||
|
goto bad;
|
||||||
|
if (!is_opt_atom( list->child->next ))
|
||||||
|
goto bad;
|
||||||
|
/* Namespace response extensions may follow here; we don't care. */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
bad:
|
||||||
error( "IMAP error: malformed NAMESPACE response\n" );
|
error( "IMAP error: malformed NAMESPACE response\n" );
|
||||||
return LIST_BAD;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_namespace_rsp( imap_store_t *ctx, list_t *list, char *s )
|
parse_namespace_rsp( imap_store_t *ctx, list_t *list, char *s )
|
||||||
{
|
{
|
||||||
if (!(ctx->ns_personal = list))
|
if (parse_namespace_check( (ctx->ns_personal = list) ))
|
||||||
return parse_namespace_rsp_fail();
|
return LIST_BAD;
|
||||||
return parse_list( ctx, s, parse_namespace_rsp_p2 );
|
return parse_list( ctx, s, parse_namespace_rsp_p2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_namespace_rsp_p2( imap_store_t *ctx, list_t *list, char *s )
|
parse_namespace_rsp_p2( imap_store_t *ctx, list_t *list, char *s )
|
||||||
{
|
{
|
||||||
if (!(ctx->ns_other = list))
|
if (parse_namespace_check( (ctx->ns_other = list) ))
|
||||||
return parse_namespace_rsp_fail();
|
return LIST_BAD;
|
||||||
return parse_list( ctx, s, parse_namespace_rsp_p3 );
|
return parse_list( ctx, s, parse_namespace_rsp_p3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_namespace_rsp_p3( imap_store_t *ctx, list_t *list, char *s ATTR_UNUSED )
|
parse_namespace_rsp_p3( imap_store_t *ctx, list_t *list, char *s ATTR_UNUSED )
|
||||||
{
|
{
|
||||||
if (!(ctx->ns_shared = list))
|
if (parse_namespace_check( (ctx->ns_shared = list) ))
|
||||||
return parse_namespace_rsp_fail();
|
return LIST_BAD;
|
||||||
return LIST_OK;
|
return LIST_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1964,7 +1987,9 @@ imap_open_store_authenticate2( imap_store_t *ctx )
|
||||||
imap_server_conf_t *srvc = cfg->server;
|
imap_server_conf_t *srvc = cfg->server;
|
||||||
string_list_t *mech, *cmech;
|
string_list_t *mech, *cmech;
|
||||||
int auth_login = 0;
|
int auth_login = 0;
|
||||||
|
int skipped_login = 0;
|
||||||
#ifdef HAVE_LIBSASL
|
#ifdef HAVE_LIBSASL
|
||||||
|
const char *saslavail;
|
||||||
char saslmechs[1024], *saslend = saslmechs;
|
char saslmechs[1024], *saslend = saslmechs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1976,19 +2001,20 @@ imap_open_store_authenticate2( imap_store_t *ctx )
|
||||||
if (!strcasecmp( cmech->string, "LOGIN" )) {
|
if (!strcasecmp( cmech->string, "LOGIN" )) {
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
if (ctx->conn.ssl || !any)
|
if (ctx->conn.ssl || !any)
|
||||||
|
#else
|
||||||
|
if (!any)
|
||||||
#endif
|
#endif
|
||||||
auth_login = 1;
|
auth_login = 1;
|
||||||
} else {
|
else
|
||||||
|
skipped_login = 1;
|
||||||
#ifdef HAVE_LIBSASL
|
#ifdef HAVE_LIBSASL
|
||||||
|
} else {
|
||||||
int len = strlen( cmech->string );
|
int len = strlen( cmech->string );
|
||||||
if (saslend + len + 2 > saslmechs + sizeof(saslmechs))
|
if (saslend + len + 2 > saslmechs + sizeof(saslmechs))
|
||||||
oob();
|
oob();
|
||||||
*saslend++ = ' ';
|
*saslend++ = ' ';
|
||||||
memcpy( saslend, cmech->string, len + 1 );
|
memcpy( saslend, cmech->string, len + 1 );
|
||||||
saslend += len;
|
saslend += len;
|
||||||
#else
|
|
||||||
error( "IMAP error: authentication mechanism %s is not supported\n", cmech->string );
|
|
||||||
goto bail;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2016,6 +2042,8 @@ imap_open_store_authenticate2( imap_store_t *ctx )
|
||||||
|
|
||||||
rc = sasl_client_new( "imap", srvc->sconf.host, NULL, NULL, NULL, 0, &ctx->sasl );
|
rc = sasl_client_new( "imap", srvc->sconf.host, NULL, NULL, NULL, 0, &ctx->sasl );
|
||||||
if (rc != SASL_OK) {
|
if (rc != SASL_OK) {
|
||||||
|
if (rc == SASL_NOMECH)
|
||||||
|
goto notsasl;
|
||||||
if (!ctx->sasl)
|
if (!ctx->sasl)
|
||||||
goto saslbail;
|
goto saslbail;
|
||||||
error( "Error: %s\n", sasl_errdetail( ctx->sasl ) );
|
error( "Error: %s\n", sasl_errdetail( ctx->sasl ) );
|
||||||
|
@ -2023,6 +2051,8 @@ imap_open_store_authenticate2( imap_store_t *ctx )
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sasl_client_start( ctx->sasl, saslmechs + 1, &interact, CAP(SASLIR) ? &out : NULL, &out_len, &gotmech );
|
rc = sasl_client_start( ctx->sasl, saslmechs + 1, &interact, CAP(SASLIR) ? &out : NULL, &out_len, &gotmech );
|
||||||
|
if (rc == SASL_NOMECH)
|
||||||
|
goto notsasl;
|
||||||
if (gotmech)
|
if (gotmech)
|
||||||
info( "Authenticating with SASL mechanism %s...\n", gotmech );
|
info( "Authenticating with SASL mechanism %s...\n", gotmech );
|
||||||
/* Technically, we are supposed to loop over sasl_client_start(),
|
/* Technically, we are supposed to loop over sasl_client_start(),
|
||||||
|
@ -2041,6 +2071,16 @@ imap_open_store_authenticate2( imap_store_t *ctx )
|
||||||
imap_exec( ctx, cmd, done_sasl_auth, enc ? "AUTHENTICATE %s %s" : "AUTHENTICATE %s", gotmech, enc );
|
imap_exec( ctx, cmd, done_sasl_auth, enc ? "AUTHENTICATE %s %s" : "AUTHENTICATE %s", gotmech, enc );
|
||||||
free( enc );
|
free( enc );
|
||||||
return;
|
return;
|
||||||
|
notsasl:
|
||||||
|
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"
|
||||||
|
" selected:%s\n available: %s\n", saslmechs, saslavail );
|
||||||
|
goto skipnote;
|
||||||
|
}
|
||||||
|
info( "NOT using available SASL mechanism(s): %s\n", saslavail );
|
||||||
|
sasl_dispose( &ctx->sasl );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (auth_login) {
|
if (auth_login) {
|
||||||
|
@ -2055,6 +2095,12 @@ imap_open_store_authenticate2( imap_store_t *ctx )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
error( "IMAP error: server supports no acceptable authentication mechanism\n" );
|
error( "IMAP error: server supports no acceptable authentication mechanism\n" );
|
||||||
|
#ifdef HAVE_LIBSASL
|
||||||
|
skipnote:
|
||||||
|
#endif
|
||||||
|
if (skipped_login)
|
||||||
|
error( "Note: not using LOGIN because connection is not encrypted;\n"
|
||||||
|
" use 'AuthMechs LOGIN' explicitly to force it.\n" );
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
imap_open_store_bail( ctx, FAIL_FINAL );
|
imap_open_store_bail( ctx, FAIL_FINAL );
|
||||||
|
@ -2129,22 +2175,20 @@ static void
|
||||||
imap_open_store_namespace2( imap_store_t *ctx )
|
imap_open_store_namespace2( imap_store_t *ctx )
|
||||||
{
|
{
|
||||||
imap_store_conf_t *cfg = (imap_store_conf_t *)ctx->gen.conf;
|
imap_store_conf_t *cfg = (imap_store_conf_t *)ctx->gen.conf;
|
||||||
list_t *nsp, *nsp_1st, *nsp_1st_ns, *nsp_1st_dl;
|
list_t *nsp, *nsp_1st;
|
||||||
|
|
||||||
/* XXX for now assume 1st personal namespace */
|
/* XXX for now assume 1st personal namespace */
|
||||||
if (is_list( (nsp = ctx->ns_personal) ) &&
|
if (is_list( (nsp = ctx->ns_personal) ) &&
|
||||||
is_list( (nsp_1st = nsp->child) ) &&
|
is_list( (nsp_1st = nsp->child) ))
|
||||||
is_atom( (nsp_1st_ns = nsp_1st->child) ) &&
|
|
||||||
is_atom( (nsp_1st_dl = nsp_1st_ns->next) ))
|
|
||||||
{
|
{
|
||||||
|
list_t *nsp_1st_ns = nsp_1st->child;
|
||||||
|
list_t *nsp_1st_dl = nsp_1st_ns->next;
|
||||||
if (!ctx->prefix && cfg->use_namespace)
|
if (!ctx->prefix && cfg->use_namespace)
|
||||||
ctx->prefix = nsp_1st_ns->val;
|
ctx->prefix = nsp_1st_ns->val;
|
||||||
if (!ctx->delimiter[0])
|
if (!ctx->delimiter[0] && is_atom( nsp_1st_dl ))
|
||||||
ctx->delimiter[0] = nsp_1st_dl->val[0];
|
ctx->delimiter[0] = nsp_1st_dl->val[0];
|
||||||
imap_open_store_finalize( ctx );
|
|
||||||
} else {
|
|
||||||
imap_open_store_bail( ctx, FAIL_FINAL );
|
|
||||||
}
|
}
|
||||||
|
imap_open_store_finalize( ctx );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2318,7 +2362,7 @@ imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int_array_t ex
|
||||||
imap_submit_load( ctx, buf, 0, sts );
|
imap_submit_load( ctx, buf, 0, sts );
|
||||||
}
|
}
|
||||||
if (maxuid == INT_MAX)
|
if (maxuid == INT_MAX)
|
||||||
maxuid = ctx->gen.uidnext ? ctx->gen.uidnext - 1 : 1000000000;
|
maxuid = ctx->gen.uidnext ? ctx->gen.uidnext - 1 : 0x7fffffff;
|
||||||
if (maxuid >= minuid) {
|
if (maxuid >= minuid) {
|
||||||
if ((ctx->gen.opts & OPEN_FIND) && minuid < newuid) {
|
if ((ctx->gen.opts & OPEN_FIND) && minuid < newuid) {
|
||||||
sprintf( buf, "%d:%d", minuid, newuid - 1 );
|
sprintf( buf, "%d:%d", minuid, newuid - 1 );
|
||||||
|
|
|
@ -522,7 +522,15 @@ map_name( const char *arg, char **result, int reserve, const char *in, const cha
|
||||||
for (ll = 0; ll < inl; ll++)
|
for (ll = 0; ll < inl; ll++)
|
||||||
if (arg[i + ll] != in[ll])
|
if (arg[i + ll] != in[ll])
|
||||||
goto rnexti;
|
goto rnexti;
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42145 */
|
||||||
|
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||||
|
#endif
|
||||||
memcpy( p, out, outl );
|
memcpy( p, out, outl );
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
p += outl;
|
p += outl;
|
||||||
i += inl;
|
i += inl;
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user