rework authentication mechanism configuration
RequireCRAM (another fairly stupid "use if available" option) is now deprecated. instead, the AuthMech option can be used to give a precise list of acceptable authentication mechanisms (which is currently "a bit" short). in particular, this allows *not* using CRAM-MD5 even if it's available.
This commit is contained in:
parent
aba3524d9b
commit
1217193fbb
2
NEWS
2
NEWS
|
@ -6,6 +6,8 @@ The SSL/TLS configuration has been re-designed.
|
||||||
SSL is now explicitly enabled or disabled - "use SSL if available" is gone.
|
SSL is now explicitly enabled or disabled - "use SSL if available" is gone.
|
||||||
Notice: Tunnels are assumed to be secure and thus default to no SSL.
|
Notice: Tunnels are assumed to be secure and thus default to no SSL.
|
||||||
|
|
||||||
|
More flexible configuration of the used authentication mechanism.
|
||||||
|
|
||||||
[1.1.0]
|
[1.1.0]
|
||||||
|
|
||||||
Support for hierarchical mailboxes in Patterns.
|
Support for hierarchical mailboxes in Patterns.
|
||||||
|
|
|
@ -48,9 +48,9 @@ typedef struct imap_server_conf {
|
||||||
char *pass;
|
char *pass;
|
||||||
char *pass_cmd;
|
char *pass_cmd;
|
||||||
int max_in_progress;
|
int max_in_progress;
|
||||||
|
string_list_t *auth_mechs;
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
char ssl_type;
|
char ssl_type;
|
||||||
char require_cram;
|
|
||||||
#endif
|
#endif
|
||||||
} imap_server_conf_t;
|
} imap_server_conf_t;
|
||||||
|
|
||||||
|
@ -100,6 +100,7 @@ typedef struct imap_store {
|
||||||
list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */
|
list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */
|
||||||
message_t **msgapp; /* FETCH results */
|
message_t **msgapp; /* FETCH results */
|
||||||
unsigned caps; /* CAPABILITY results */
|
unsigned caps; /* CAPABILITY results */
|
||||||
|
string_list_t *auth_mechs;
|
||||||
parse_list_state_t parse_list_sts;
|
parse_list_state_t parse_list_sts;
|
||||||
/* command queue */
|
/* command queue */
|
||||||
int nexttag, num_in_progress;
|
int nexttag, num_in_progress;
|
||||||
|
@ -173,7 +174,6 @@ struct imap_cmd_refcounted {
|
||||||
enum CAPABILITY {
|
enum CAPABILITY {
|
||||||
NOLOGIN = 0,
|
NOLOGIN = 0,
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
CRAM,
|
|
||||||
STARTTLS,
|
STARTTLS,
|
||||||
#endif
|
#endif
|
||||||
UIDPLUS,
|
UIDPLUS,
|
||||||
|
@ -185,7 +185,6 @@ enum CAPABILITY {
|
||||||
static const char *cap_list[] = {
|
static const char *cap_list[] = {
|
||||||
"LOGINDISABLED",
|
"LOGINDISABLED",
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
"AUTH=CRAM-MD5",
|
|
||||||
"STARTTLS",
|
"STARTTLS",
|
||||||
#endif
|
#endif
|
||||||
"UIDPLUS",
|
"UIDPLUS",
|
||||||
|
@ -983,11 +982,20 @@ parse_capability( imap_store_t *ctx, char *cmd )
|
||||||
char *arg;
|
char *arg;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
free_string_list( ctx->auth_mechs );
|
||||||
|
ctx->auth_mechs = 0;
|
||||||
ctx->caps = 0x80000000;
|
ctx->caps = 0x80000000;
|
||||||
while ((arg = next_arg( &cmd )))
|
while ((arg = next_arg( &cmd ))) {
|
||||||
|
if (!memcmp( "AUTH=", arg, 5 )) {
|
||||||
|
add_string_list( &ctx->auth_mechs, arg + 5 );
|
||||||
|
} else {
|
||||||
for (i = 0; i < as(cap_list); i++)
|
for (i = 0; i < as(cap_list); i++)
|
||||||
if (!strcmp( cap_list[i], arg ))
|
if (!strcmp( cap_list[i], arg ))
|
||||||
ctx->caps |= 1 << i;
|
ctx->caps |= 1 << i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!CAP(NOLOGIN))
|
||||||
|
add_string_list( &ctx->auth_mechs, "LOGIN" );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1354,6 +1362,7 @@ imap_cancel_store( store_t *gctx )
|
||||||
free_list( ctx->ns_personal );
|
free_list( ctx->ns_personal );
|
||||||
free_list( ctx->ns_other );
|
free_list( ctx->ns_other );
|
||||||
free_list( ctx->ns_shared );
|
free_list( ctx->ns_shared );
|
||||||
|
free_string_list( ctx->auth_mechs );
|
||||||
free( ctx->delimiter );
|
free( ctx->delimiter );
|
||||||
imap_deref( ctx );
|
imap_deref( ctx );
|
||||||
}
|
}
|
||||||
|
@ -1644,7 +1653,12 @@ imap_open_store_authenticate2( 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;
|
||||||
imap_server_conf_t *srvc = cfg->server;
|
imap_server_conf_t *srvc = cfg->server;
|
||||||
|
string_list_t *mech, *cmech;
|
||||||
char *arg;
|
char *arg;
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
int auth_cram = 0;
|
||||||
|
#endif
|
||||||
|
int auth_login = 0;
|
||||||
|
|
||||||
info ("Logging in...\n");
|
info ("Logging in...\n");
|
||||||
if (!srvc->user) {
|
if (!srvc->user) {
|
||||||
|
@ -1697,24 +1711,38 @@ imap_open_store_authenticate2( imap_store_t *ctx )
|
||||||
*/
|
*/
|
||||||
srvc->pass = nfstrdup( arg );
|
srvc->pass = nfstrdup( arg );
|
||||||
}
|
}
|
||||||
|
for (mech = srvc->auth_mechs; mech; mech = mech->next) {
|
||||||
|
int any = !strcmp( mech->string, "*" );
|
||||||
|
for (cmech = ctx->auth_mechs; cmech; cmech = cmech->next) {
|
||||||
|
if (any || !strcasecmp( mech->string, cmech->string )) {
|
||||||
|
if (!strcasecmp( cmech->string, "LOGIN" )) {
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
if (CAP(CRAM)) {
|
if (ctx->conn.ssl || !any)
|
||||||
|
#endif
|
||||||
|
auth_login = 1;
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
} else if (!strcasecmp( cmech->string, "CRAM-MD5" )) {
|
||||||
|
auth_cram = 1;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
error( "IMAP error: authentication mechanism %s is not supported\n", cmech->string );
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
if (auth_cram) {
|
||||||
struct imap_cmd *cmd = new_imap_cmd( sizeof(*cmd) );
|
struct imap_cmd *cmd = new_imap_cmd( sizeof(*cmd) );
|
||||||
|
|
||||||
info( "Authenticating with CRAM-MD5\n" );
|
info( "Authenticating with CRAM-MD5...\n" );
|
||||||
cmd->param.cont = do_cram_auth;
|
cmd->param.cont = do_cram_auth;
|
||||||
imap_exec( ctx, cmd, imap_open_store_authenticate2_p2, "AUTHENTICATE CRAM-MD5" );
|
imap_exec( ctx, cmd, imap_open_store_authenticate2_p2, "AUTHENTICATE CRAM-MD5" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (srvc->require_cram) {
|
|
||||||
error( "IMAP error: CRAM-MD5 authentication is not supported by server\n" );
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (CAP(NOLOGIN)) {
|
if (auth_login) {
|
||||||
error( "Skipping account %s, server forbids LOGIN\n", srvc->name );
|
info( "Logging in...\n" );
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
if (!ctx->conn.ssl)
|
if (!ctx->conn.ssl)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1722,6 +1750,8 @@ imap_open_store_authenticate2( imap_store_t *ctx )
|
||||||
imap_exec( ctx, 0, imap_open_store_authenticate2_p2,
|
imap_exec( ctx, 0, imap_open_store_authenticate2_p2,
|
||||||
"LOGIN \"%\\s\" \"%\\s\"", srvc->user, srvc->pass );
|
"LOGIN \"%\\s\" \"%\\s\"", srvc->user, srvc->pass );
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
error( "IMAP error: server supports no acceptable authentication mechanism\n" );
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
imap_open_store_bail( ctx );
|
imap_open_store_bail( ctx );
|
||||||
|
@ -2240,6 +2270,7 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep )
|
||||||
/* Legacy SSL options */
|
/* Legacy SSL options */
|
||||||
int require_ssl = -1, use_imaps = -1;
|
int require_ssl = -1, use_imaps = -1;
|
||||||
int use_sslv2 = -1, use_sslv3 = -1, use_tlsv1 = -1, use_tlsv11 = -1, use_tlsv12 = -1;
|
int use_sslv2 = -1, use_sslv3 = -1, use_tlsv1 = -1, use_tlsv11 = -1, use_tlsv12 = -1;
|
||||||
|
int require_cram = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!strcasecmp( "IMAPAccount", cfg->cmd )) {
|
if (!strcasecmp( "IMAPAccount", cfg->cmd )) {
|
||||||
|
@ -2356,8 +2387,14 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep )
|
||||||
use_tlsv11 = parse_bool( cfg );
|
use_tlsv11 = parse_bool( cfg );
|
||||||
else if (!strcasecmp( "UseTLSv1.2", cfg->cmd ))
|
else if (!strcasecmp( "UseTLSv1.2", cfg->cmd ))
|
||||||
use_tlsv12 = parse_bool( cfg );
|
use_tlsv12 = parse_bool( cfg );
|
||||||
else if (!strcasecmp( "RequireCRAM", cfg->cmd ))
|
else if (!strcasecmp( "AuthMech", cfg->cmd ) ||
|
||||||
server->require_cram = parse_bool( cfg );
|
!strcasecmp( "AuthMechs", cfg->cmd )) {
|
||||||
|
arg = cfg->val;
|
||||||
|
do
|
||||||
|
add_string_list( &server->auth_mechs, arg );
|
||||||
|
while ((arg = get_arg( cfg, ARG_OPTIONAL, 0 )));
|
||||||
|
} else if (!strcasecmp( "RequireCRAM", cfg->cmd ))
|
||||||
|
require_cram = parse_bool( cfg );
|
||||||
#endif
|
#endif
|
||||||
else if (!strcasecmp( "Tunnel", cfg->cmd ))
|
else if (!strcasecmp( "Tunnel", cfg->cmd ))
|
||||||
server->sconf.tunnel = nfstrdup( cfg->val );
|
server->sconf.tunnel = nfstrdup( cfg->val );
|
||||||
|
@ -2438,6 +2475,20 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep )
|
||||||
server->ssl_type = server->sconf.tunnel ? SSL_None : SSL_STARTTLS;
|
server->ssl_type = server->sconf.tunnel ? SSL_None : SSL_STARTTLS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
if (require_cram >= 0) {
|
||||||
|
if (server->auth_mechs) {
|
||||||
|
error( "%s '%s': The deprecated RequireCRAM option is mutually exlusive with AuthMech.\n", type, name );
|
||||||
|
cfg->err = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
warn( "Notice: %s '%s': RequireCRAM is deprecated. Use AuthMech instead.\n", type, name );
|
||||||
|
if (require_cram)
|
||||||
|
add_string_list(&server->auth_mechs, "CRAM-MD5");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!server->auth_mechs)
|
||||||
|
add_string_list( &server->auth_mechs, "*" );
|
||||||
if (!server->sconf.port)
|
if (!server->sconf.port)
|
||||||
server->sconf.port =
|
server->sconf.port =
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
|
|
16
src/mbsync.1
16
src/mbsync.1
|
@ -274,9 +274,16 @@ socket. This allows you to run an IMAP session over an SSH tunnel, for
|
||||||
example.
|
example.
|
||||||
..
|
..
|
||||||
.TP
|
.TP
|
||||||
\fBRequireCRAM\fR \fIyes\fR|\fIno\fR
|
\fBAuthMechs\fR \fItype\fR ...
|
||||||
If set to \fIyes\fR, \fBmbsync\fR will abort the connection if no CRAM-MD5
|
The list of acceptable authentication mechanisms.
|
||||||
authentication is possible. (Default: \fIno\fR)
|
In addition to the mechanisms listed in the SASL registry (link below),
|
||||||
|
the legacy IMAP \fBLOGIN\fR mechanism is known.
|
||||||
|
The wildcard \fB*\fR represents all mechanisms that are deemed secure
|
||||||
|
enough for the current \fBSSLType\fR setting.
|
||||||
|
The actually used mechanism is the most secure choice from the intersection
|
||||||
|
of this list, the list supplied by the server, and the mechanisms actually
|
||||||
|
supported by \fBmbsync\fR (currently only \fBCRAM-MD5\fR and \fBLOGIN\fR).
|
||||||
|
(Default: \fB*\fR)
|
||||||
..
|
..
|
||||||
.TP
|
.TP
|
||||||
\fBSSLType\fR {\fINone\fR|\fISTARTTLS\fR|\fIIMAPS\fR}
|
\fBSSLType\fR {\fINone\fR|\fISTARTTLS\fR|\fIIMAPS\fR}
|
||||||
|
@ -594,6 +601,9 @@ Directory containing synchronization state files
|
||||||
mdconvert(1), isync(1), mutt(1), maildir(5)
|
mdconvert(1), isync(1), mutt(1), maildir(5)
|
||||||
.P
|
.P
|
||||||
Up to date information on \fBmbsync\fR can be found at http://isync.sf.net/
|
Up to date information on \fBmbsync\fR can be found at http://isync.sf.net/
|
||||||
|
.P
|
||||||
|
SASL mechanisms are listed at
|
||||||
|
http://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml
|
||||||
..
|
..
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
Originally written by Michael R. Elkins,
|
Originally written by Michael R. Elkins,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user