[balsa] SMTP, POP: fall back to auth w/ password
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa] SMTP, POP: fall back to auth w/ password
- Date: Wed, 19 Dec 2018 00:38:37 +0000 (UTC)
commit a0065aa672da97a21d91cb7e0f4d7e0720edac7b
Author: Albrecht Dreß <albrecht dress arcor de>
Date: Tue Dec 18 19:23:10 2018 -0500
SMTP, POP: fall back to auth w/ password
SMTP, POP: fall back to auth w/ password if GSS failed
* libnetclient/net-client-pop.c, libnetclient/net-client-smtp.c:
retry auth with password if GSS auth failed; small performance
improvement checking the various auth methods
* libnetclient/net-client-utils.c: print more (internal) debug
info about failed GSS operations, fix nit-picks
Signed-off-by: Peter Bloomfield <PeterBloomfield bellsouth net>
ChangeLog | 10 ++++++++++
libnetclient/net-client-pop.c | 28 ++++++++++++++++++++++------
libnetclient/net-client-smtp.c | 24 ++++++++++++++++++++----
libnetclient/net-client-utils.c | 8 ++++++--
4 files changed, 58 insertions(+), 12 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6bf1134bb..4f08ef2b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2018-12-18 Albrecht Dreß <albrecht dress arcor de>
+
+ SMTP, POP: fall back to auth w/ password if GSS failed
+
+ * libnetclient/net-client-pop.c, libnetclient/net-client-smtp.c:
+ retry auth with password if GSS auth failed; small performance
+ improvement checking the various auth methods
+ * libnetclient/net-client-utils.c: print more (internal) debug
+ info about failed GSS operations, fix nit-picks
+
2018-12-14 Peter Bloomfield <pbloomfield bellsouth net>
Stop using GSlice; it may go away
diff --git a/libnetclient/net-client-pop.c b/libnetclient/net-client-pop.c
index 3a757c0d0..5967fdbff 100644
--- a/libnetclient/net-client-pop.c
+++ b/libnetclient/net-client-pop.c
@@ -171,12 +171,26 @@ net_client_pop_connect(NetClientPop *client, gchar **greeting, GError **error)
auth_data = NULL;
need_pwd = (auth_supported & NET_CLIENT_POP_AUTH_NO_PWD) == 0U;
- g_debug("emit 'auth' signal for client %p", client);
+ g_debug("emit 'auth' signal for client %p, need pwd %d", client, need_pwd);
g_signal_emit_by_name(client, "auth", need_pwd, &auth_data);
if ((auth_data != NULL) && (auth_data[0] != NULL)) {
result = net_client_pop_auth(client, auth_data[0], auth_data[1], auth_supported,
error);
net_client_free_authstr(auth_data[0]);
net_client_free_authstr(auth_data[1]);
+
+ /* if passwordless authentication failed, try again with password */
+ if (!result && !need_pwd) {
+ g_debug("passwordless authentication failed, retry w/ password: emit 'auth'
signal for client %p", client);
+ g_clear_error(error);
+ g_free(auth_data);
+ g_signal_emit_by_name(client, "auth", TRUE, &auth_data);
+ if ((auth_data != NULL) && (auth_data[0] != NULL)) {
+ result = net_client_pop_auth(client, auth_data[0], auth_data[1],
+ auth_supported & ~NET_CLIENT_POP_AUTH_NO_PWD, error);
+ net_client_free_authstr(auth_data[0]);
+ net_client_free_authstr(auth_data[1]);
+ }
+ }
}
g_free(auth_data);
}
@@ -482,7 +496,10 @@ net_client_pop_auth(NetClientPop *client, const gchar *user, const gchar *passwd
auth_mask = client->priv->auth_allowed[1] & auth_supported;
}
- if (((auth_mask & NET_CLIENT_POP_AUTH_NO_PWD) == 0U) && (passwd == NULL)) {
+ if (auth_mask == 0U) {
+ g_set_error(error, NET_CLIENT_POP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_POP_NO_AUTH,
+ _("no suitable authentication mechanism"));
+ } else if (((auth_mask & NET_CLIENT_POP_AUTH_NO_PWD) == 0U) && (passwd == NULL)) {
g_set_error(error, NET_CLIENT_POP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_POP_NO_AUTH,
_("password required"));
} else {
/* first try authentication methods w/o password, then safe ones, and finally the plain-text
methods */
@@ -501,14 +518,13 @@ net_client_pop_auth(NetClientPop *client, const gchar *user, const gchar *passwd
} else if ((auth_mask & NET_CLIENT_POP_AUTH_LOGIN) != 0U) {
result = net_client_pop_auth_login(client, user, passwd, error);
} else {
- g_set_error(error, NET_CLIENT_POP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_POP_NO_AUTH,
- _("no suitable authentication mechanism"));
+ g_assert_not_reached();
}
/* POP3 does not define a mechanism to indicate that the authentication failed due to a too
weak mechanism or wrong
* credentials, so we treat all server -ERR responses as authentication failures */
- if (!result && (*error != NULL) && ((*error)->code == NET_CLIENT_ERROR_POP_SERVER_ERR)) {
- (*error)->code = NET_CLIENT_ERROR_POP_AUTHFAIL;
+ if (!result && (*error != NULL) && ((*error)->code == (gint)
NET_CLIENT_ERROR_POP_SERVER_ERR)) {
+ (*error)->code = (gint) NET_CLIENT_ERROR_POP_AUTHFAIL;
}
}
diff --git a/libnetclient/net-client-smtp.c b/libnetclient/net-client-smtp.c
index bc7597031..63c59fa3c 100644
--- a/libnetclient/net-client-smtp.c
+++ b/libnetclient/net-client-smtp.c
@@ -157,12 +157,26 @@ net_client_smtp_connect(NetClientSmtp *client, gchar **greeting, GError **error)
auth_data = NULL;
need_pwd = (auth_supported & NET_CLIENT_SMTP_AUTH_NO_PWD) == 0U;
- g_debug("emit 'auth' signal for client %p", client);
+ g_debug("emit 'auth' signal for client %p, need pwd %d", client, need_pwd);
g_signal_emit_by_name(client, "auth", need_pwd, &auth_data);
if ((auth_data != NULL) && (auth_data[0] != NULL)) {
result = net_client_smtp_auth(client, auth_data[0], auth_data[1], auth_supported,
error);
net_client_free_authstr(auth_data[0]);
net_client_free_authstr(auth_data[1]);
+
+ /* if passwordless authentication failed, try again with password */
+ if (!result && !need_pwd) {
+ g_debug("passwordless authentication failed, retry w/ password: emit 'auth'
signal for client %p", client);
+ g_clear_error(error);
+ g_free(auth_data);
+ g_signal_emit_by_name(client, "auth", TRUE, &auth_data);
+ if ((auth_data != NULL) && (auth_data[0] != NULL)) {
+ result = net_client_smtp_auth(client, auth_data[0], auth_data[1],
+ auth_supported & ~NET_CLIENT_SMTP_AUTH_NO_PWD, error);
+ net_client_free_authstr(auth_data[0]);
+ net_client_free_authstr(auth_data[1]);
+ }
+ }
}
g_free(auth_data);
}
@@ -391,7 +405,10 @@ net_client_smtp_auth(NetClientSmtp *client, const gchar *user, const gchar *pass
auth_mask = client->priv->auth_allowed[1] & auth_supported;
}
- if (((auth_mask & NET_CLIENT_SMTP_AUTH_NO_PWD) == 0U) && (passwd == NULL)) {
+ if (auth_mask == 0U) {
+ g_set_error(error, NET_CLIENT_SMTP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_SMTP_NO_AUTH,
+ _("no suitable authentication mechanism"));
+ } else if (((auth_mask & NET_CLIENT_SMTP_AUTH_NO_PWD) == 0U) && (passwd == NULL)) {
g_set_error(error, NET_CLIENT_SMTP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_SMTP_NO_AUTH,
_("password required"));
} else {
/* first try authentication methods w/o password, then safe ones, and finally the plain-text
methods */
@@ -406,8 +423,7 @@ net_client_smtp_auth(NetClientSmtp *client, const gchar *user, const gchar *pass
} else if ((auth_mask & NET_CLIENT_SMTP_AUTH_LOGIN) != 0U) {
result = net_client_smtp_auth_login(client, user, passwd, error);
} else {
- g_set_error(error, NET_CLIENT_SMTP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_SMTP_NO_AUTH,
- _("no suitable authentication mechanism"));
+ g_assert_not_reached();
}
}
diff --git a/libnetclient/net-client-utils.c b/libnetclient/net-client-utils.c
index 83c9641ad..141dc70bc 100644
--- a/libnetclient/net-client-utils.c
+++ b/libnetclient/net-client-utils.c
@@ -70,7 +70,7 @@ net_client_cram_calc(const gchar *base64_challenge, GChecksumType chksum_type, c
const gchar *
net_client_chksum_to_str(GChecksumType chksum_type)
{
- /*lint -e{904} -e{9077} -e{9090} (MISRA C:2012 Rules 15.5, 16.1, 16.3) */
+ /*lint -e{904} -e{9077} -e{9090} -e{788} (MISRA C:2012 Rules 15.5, 16.1, 16.3) */
switch (chksum_type) {
case G_CHECKSUM_MD5:
return "MD5";
@@ -118,7 +118,7 @@ net_client_free_authstr(gchar *str)
guint n;
for (n = 0; str[n] != '\0'; n++) {
- str[n] = g_random_int_range(32, 128);
+ str[n] = (gchar) g_random_int_range(32, 128);
}
g_free(str);
}
@@ -151,6 +151,7 @@ net_client_gss_ctx_new(const gchar *service, const gchar *host, const gchar *use
if (GSS_ERROR(maj_stat) != 0U) {
gchar *gss_err = gss_error_string(maj_stat, min_stat);
+ g_debug("gss_import_name: %x:%x: %s", maj_stat, min_stat, gss_err);
g_set_error(error, NET_CLIENT_ERROR_QUARK, (gint) NET_CLIENT_ERROR_GSSAPI, _("importing GSS service
name %s failed: %s"),
service_str, gss_err);
g_free(gss_err);
@@ -194,6 +195,7 @@ net_client_gss_auth_step(NetClientGssCtx *gss_ctx, const gchar *in_token, gchar
if ((maj_stat != GSS_S_COMPLETE) && (maj_stat != GSS_S_CONTINUE_NEEDED)) {
gchar *gss_err = gss_error_string(maj_stat, min_stat);
+ g_debug("gss_init_sec_context: %x:%x: %s", maj_stat, min_stat, gss_err);
g_set_error(error, NET_CLIENT_ERROR_QUARK, (gint) NET_CLIENT_ERROR_GSSAPI, _("cannot initialize GSS
security context: %s"),
gss_err);
g_free(gss_err);
@@ -233,6 +235,7 @@ net_client_gss_auth_finish(const NetClientGssCtx *gss_ctx, const gchar *in_token
if (maj_stat != GSS_S_COMPLETE) {
gchar *gss_err = gss_error_string(maj_stat, min_stat);
+ g_debug("gss_unwrap: %x:%x: %s", maj_stat, min_stat, gss_err);
g_set_error(error, NET_CLIENT_ERROR_QUARK, (gint) NET_CLIENT_ERROR_GSSAPI, _("malformed GSS security
token: %s"), gss_err);
g_free(gss_err);
} else {
@@ -258,6 +261,7 @@ net_client_gss_auth_finish(const NetClientGssCtx *gss_ctx, const gchar *in_token
if (maj_stat != GSS_S_COMPLETE) {
gchar *gss_err = gss_error_string(maj_stat, min_stat);
+ g_debug("gss_wrap: %x:%x: %s", maj_stat, min_stat, gss_err);
g_set_error(error, NET_CLIENT_ERROR_QUARK, (gint) NET_CLIENT_ERROR_GSSAPI,
_("cannot create GSS login request: %s"),
gss_err);
g_free(gss_err);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]