[balsa/oauth2-support] libnetclient improvements for OAuth2 preparation
- From: Albrecht Dreß <albrecht src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa/oauth2-support] libnetclient improvements for OAuth2 preparation
- Date: Wed, 9 Sep 2020 17:51:36 +0000 (UTC)
commit 79e49ab4e38e748ebd971fd505e8311faee031da
Author: Albrecht Dreß <albrecht dress arcor de>
Date: Wed Sep 9 19:42:25 2020 +0200
libnetclient improvements for OAuth2 preparation
- in libnetclient:
- net-client.h: rename ANONYMOUS auth method to NONE_ANON, update docs
- net-client-pop.[ch]: rework auth code, add ANONYMOUS auth
- net-client-smtp.[ch]: rework auth code
- net-client-utils.[ch]: add helper for ANONYMOUS auth token
calculation
- in libbalsa/imap:
- auth-cram.c, auth-gssapi.c, imap-auth.c, imap-handle.c: use new auth
signal signature and auth method naming
- imap-auth.c: improve ANONYMOUS auth
- fix meson error (thanks @peterb)
- in libbalsa:
- server-config.c: add ANONYMOUS auth for POP3 and IMAP, use new auth
method naming, add log domain
- server.[ch]: implement new auth signal handler, add log domain
- smtp-server.c: add log domain
Signed-off-by: Albrecht Dreß <albrecht dress arcor de>
libbalsa/imap/auth-cram.c | 2 +-
libbalsa/imap/auth-gssapi.c | 2 +-
libbalsa/imap/imap-auth.c | 24 ++-----
libbalsa/imap/imap-handle.c | 2 +-
libbalsa/imap/imap_tst.c | 2 +-
libbalsa/imap/meson.build | 2 +-
libbalsa/server-config.c | 16 +++--
libbalsa/server.c | 40 +++++++----
libbalsa/server.h | 6 +-
libbalsa/smtp-server.c | 7 ++
libnetclient/net-client-pop.c | 150 ++++++++++++++++++++++++++--------------
libnetclient/net-client-pop.h | 15 ++--
libnetclient/net-client-smtp.c | 86 +++++++++++++----------
libnetclient/net-client-smtp.h | 4 +-
libnetclient/net-client-utils.c | 19 +++++
libnetclient/net-client-utils.h | 17 ++++-
libnetclient/net-client.h | 13 ++--
17 files changed, 259 insertions(+), 148 deletions(-)
---
diff --git a/libbalsa/imap/auth-cram.c b/libbalsa/imap/auth-cram.c
index 6b11f72a2..18b9a18d3 100644
--- a/libbalsa/imap/auth-cram.c
+++ b/libbalsa/imap/auth-cram.c
@@ -42,7 +42,7 @@ imap_auth_cram(ImapMboxHandle* handle)
if (!imap_mbox_handle_can_do(handle, IMCAP_ACRAM_MD5))
return IMAP_AUTH_UNAVAIL;
- g_signal_emit_by_name(handle->sio, "auth", TRUE, &auth_data);
+ g_signal_emit_by_name(handle->sio, "auth", NET_CLIENT_AUTH_USER_PASS, &auth_data);
if((auth_data == NULL) || (auth_data[0] == NULL) || (auth_data[1] == NULL)) {
imap_mbox_handle_set_msg(handle, _("Authentication cancelled"));
g_strfreev(auth_data);
diff --git a/libbalsa/imap/auth-gssapi.c b/libbalsa/imap/auth-gssapi.c
index e5bcd6973..0a6323f9c 100644
--- a/libbalsa/imap/auth-gssapi.c
+++ b/libbalsa/imap/auth-gssapi.c
@@ -125,7 +125,7 @@ imap_auth_gssapi(ImapMboxHandle* handle)
return IMAP_AUTH_UNAVAIL;
}
- g_signal_emit_by_name(handle->sio, "auth", FALSE, &auth_data);
+ g_signal_emit_by_name(handle->sio, "auth", NET_CLIENT_AUTH_KERBEROS, &auth_data);
if((auth_data == NULL) || (auth_data[0] == NULL)) {
imap_mbox_handle_set_msg(handle, _("User name required, authentication cancelled"));
g_strfreev(auth_data);
diff --git a/libbalsa/imap/imap-auth.c b/libbalsa/imap/imap-auth.c
index 94258a5d4..b3091f9a2 100644
--- a/libbalsa/imap/imap-auth.c
+++ b/libbalsa/imap/imap-auth.c
@@ -64,7 +64,7 @@ imap_authenticate(ImapMboxHandle* handle)
r = imap_auth_gssapi(handle);
}
- if ((r != IMAP_SUCCESS) && (handle->auth_mode & NET_CLIENT_AUTH_ANONYMOUS) != 0U) {
+ if ((r != IMAP_SUCCESS) && (handle->auth_mode & NET_CLIENT_AUTH_NONE_ANON) != 0U) {
r = imap_auth_anonymous(handle);
}
@@ -94,7 +94,7 @@ imap_auth_login(ImapMboxHandle* handle)
if (imap_mbox_handle_can_do(handle, IMCAP_LOGINDISABLED))
return IMAP_AUTH_UNAVAIL;
- g_signal_emit_by_name(handle->sio, "auth", TRUE, &auth_data);
+ g_signal_emit_by_name(handle->sio, "auth", NET_CLIENT_AUTH_USER_PASS, &auth_data);
if((auth_data == NULL) || (auth_data[0] == NULL) || (auth_data[1] == NULL)) {
imap_mbox_handle_set_msg(handle, _("Authentication cancelled"));
g_strfreev(auth_data);
@@ -184,7 +184,7 @@ getmsg_plain(ImapMboxHandle *h, char **retmsg, int *retmsglen)
gchar **auth_data;
gboolean result;
- g_signal_emit_by_name(h->sio, "auth", TRUE, &auth_data);
+ g_signal_emit_by_name(h->sio, "auth", NET_CLIENT_AUTH_USER_PASS, &auth_data);
if ((auth_data == NULL) || (auth_data[0] == NULL) || (auth_data[1] == NULL)) {
result = FALSE;
} else {
@@ -209,24 +209,14 @@ imap_auth_plain(ImapMboxHandle* handle)
/* =================================================================== */
-/* SASL ANONYMOUS RFC-2245 */
+/* SASL ANONYMOUS RFC-4505 */
/* =================================================================== */
static gboolean
getmsg_anonymous(ImapMboxHandle *h, char **retmsg, int *retmsglen)
{
- gchar **auth_data;
- gboolean result;
-
- g_signal_emit_by_name(h->sio, "auth", FALSE, &auth_data);
- if((auth_data == NULL) || (auth_data[0] == NULL)) {
- result = FALSE;
- } else {
- *retmsg = g_base64_encode((const guchar *) auth_data[0], strlen(auth_data[0]));
- *retmsglen = strlen(*retmsg);
- result = TRUE;
- }
- g_strfreev(auth_data);
- return result;
+ *retmsg = net_client_auth_anonymous_token();
+ *retmsglen = strlen(*retmsg);
+ return TRUE;
}
static ImapResult
diff --git a/libbalsa/imap/imap-handle.c b/libbalsa/imap/imap-handle.c
index 1ae777482..b8e5643aa 100644
--- a/libbalsa/imap/imap-handle.c
+++ b/libbalsa/imap/imap-handle.c
@@ -4480,7 +4480,7 @@ imap_server_probe(const gchar *host, guint timeout_secs, NetClientProbeResult *r
result->auth_mode = 0U;
if (imap_mbox_handle_can_do(handle, IMCAP_AANONYMOUS) != 0) {
- result->auth_mode |= NET_CLIENT_AUTH_ANONYMOUS;
+ result->auth_mode |= NET_CLIENT_AUTH_NONE_ANON;
}
if ((imap_mbox_handle_can_do(handle, IMCAP_ACRAM_MD5) != 0) ||
(imap_mbox_handle_can_do(handle, IMCAP_APLAIN) != 0)) {
diff --git a/libbalsa/imap/imap_tst.c b/libbalsa/imap/imap_tst.c
index 7174f066f..01997f031 100644
--- a/libbalsa/imap/imap_tst.c
+++ b/libbalsa/imap/imap_tst.c
@@ -124,7 +124,7 @@ get_handle(const char *host)
imap_handle_set_tls_mode(h, TestContext.tls_mode);
if(TestContext.anonymous)
- imap_handle_set_auth_mode(h, NET_CLIENT_AUTH_ANONYMOUS);
+ imap_handle_set_auth_mode(h, NET_CLIENT_AUTH_NONE_ANON);
if(TestContext.compress)
imap_handle_set_option(h, IMAP_OPT_COMPRESS, TRUE);
diff --git a/libbalsa/imap/meson.build b/libbalsa/imap/meson.build
index 34918b947..ed1e977d0 100644
--- a/libbalsa/imap/meson.build
+++ b/libbalsa/imap/meson.build
@@ -37,5 +37,5 @@ imap_tst_sources = 'imap_tst.c'
imap_tst = executable('imap_tst', imap_tst_sources,
link_with : [libimap_a, libnetclient_a],
dependencies : balsa_deps,
- include_directories : libnetclient_include,
+ include_directories : [top_include, libnetclient_include],
install : false)
diff --git a/libbalsa/server-config.c b/libbalsa/server-config.c
index 1bf2f3659..5ac74dc97 100644
--- a/libbalsa/server-config.c
+++ b/libbalsa/server-config.c
@@ -30,6 +30,12 @@
#include "server-config.h"
+#ifdef G_LOG_DOMAIN
+# undef G_LOG_DOMAIN
+#endif
+#define G_LOG_DOMAIN "libbalsa-server"
+
+
struct _LibBalsaServerCfg {
GtkNotebook parent;
@@ -416,7 +422,9 @@ server_cfg_auth_widget(LibBalsaServer *server)
gchar id_buf[8];
protocol = libbalsa_server_get_protocol(server);
- if ((strcmp(protocol, "smtp") == 0) || (strcmp(protocol, "imap") == 0)) {
+ if ((strcmp(protocol, "pop3") == 0) || (strcmp(protocol, "imap") == 0)) {
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo_box), "1", _("anonymous access")); /*
RFC 4505 */
+ } else {
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo_box), "1", _("none required"));
}
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo_box), "2", _("user name and pass phrase"));
@@ -455,12 +463,12 @@ on_server_cfg_changed(GtkWidget *widget, LibBalsaServerCfg *server_cfg)
} else {
auth_mode = 0;
}
- gtk_widget_set_sensitive(server_cfg->username, auth_mode != NET_CLIENT_AUTH_ANONYMOUS);
+ gtk_widget_set_sensitive(server_cfg->username, auth_mode != NET_CLIENT_AUTH_NONE_ANON);
gtk_widget_set_sensitive(server_cfg->password, auth_mode == NET_CLIENT_AUTH_USER_PASS);
gtk_widget_set_sensitive(server_cfg->remember_pass, auth_mode == NET_CLIENT_AUTH_USER_PASS);
/* invalid configuration if authentication is required, but no user name given */
- if ((auth_mode != NET_CLIENT_AUTH_ANONYMOUS) && (*gtk_entry_get_text(GTK_ENTRY(server_cfg->username))
== '\0')) {
+ if ((auth_mode != NET_CLIENT_AUTH_NONE_ANON) && (*gtk_entry_get_text(GTK_ENTRY(server_cfg->username))
== '\0')) {
server_cfg->cfg_valid = FALSE;
}
@@ -528,7 +536,7 @@ on_server_probe(GtkWidget *widget, LibBalsaServerCfg *server_cfg)
probe_res.auth_mode = NET_CLIENT_AUTH_USER_PASS;
} else {
auth_str = _("none");
- probe_res.auth_mode = NET_CLIENT_AUTH_ANONYMOUS;
+ probe_res.auth_mode = NET_CLIENT_AUTH_NONE_ANON;
}
msgdlg = gtk_message_dialog_new(NULL,
GTK_DIALOG_DESTROY_WITH_PARENT | libbalsa_dialog_flags(),
diff --git a/libbalsa/server.c b/libbalsa/server.c
index c49cd2d0d..f1ffe6bd8 100644
--- a/libbalsa/server.c
+++ b/libbalsa/server.c
@@ -36,6 +36,13 @@
#include "net-client-utils.h"
#include <glib/gi18n.h>
+
+#ifdef G_LOG_DOMAIN
+# undef G_LOG_DOMAIN
+#endif
+#define G_LOG_DOMAIN "libbalsa-server"
+
+
#if defined(HAVE_LIBSECRET)
static const SecretSchema server_schema = {
"org.gnome.Balsa.NetworkPassword", SECRET_SCHEMA_NONE,
@@ -448,7 +455,7 @@ libbalsa_server_load_config(LibBalsaServer * server)
priv->auth_mode = libbalsa_conf_get_int("AuthMode=2"); /* default NET_CLIENT_AUTH_USER_PASS */
if (libbalsa_conf_has_key("Anonymous")) {
if (libbalsa_conf_get_bool("Anonymous")) {
- priv->auth_mode = NET_CLIENT_AUTH_ANONYMOUS;
+ priv->auth_mode = NET_CLIENT_AUTH_NONE_ANON;
}
libbalsa_conf_clean_key("Anonymous");
}
@@ -553,25 +560,32 @@ libbalsa_server_connect_signals(LibBalsaServer * server, GCallback cb,
gchar **
-libbalsa_server_get_auth(NetClient *client,
- gboolean need_passwd,
- gpointer user_data)
+libbalsa_server_get_auth(NetClient *client,
+ NetClientAuthMode mode,
+ gpointer user_data)
{
LibBalsaServer *server = LIBBALSA_SERVER(user_data);
LibBalsaServerPrivate *priv = libbalsa_server_get_instance_private(server);
gchar **result = NULL;
- g_debug("%s: %p %p: encrypted = %d", __func__, client, user_data,
- net_client_is_encrypted(client));
- if (priv->auth_mode != NET_CLIENT_AUTH_ANONYMOUS) {
+ g_debug("%s: %p %d %p: encrypted = %d", __func__, client, mode, user_data,
net_client_is_encrypted(client));
+ if (priv->auth_mode != NET_CLIENT_AUTH_NONE_ANON) {
result = g_new0(gchar *, 3U);
result[0] = g_strdup(priv->user);
- if (need_passwd) {
- if ((priv->passwd != NULL) && (priv->passwd[0] != '\0')) {
- result[1] = g_strdup(priv->passwd);
- } else {
- result[1] = lbs_get_password(server, NULL);
- }
+ switch (mode) {
+ case NET_CLIENT_AUTH_USER_PASS:
+ if ((priv->passwd != NULL) && (priv->passwd[0] != '\0')) {
+ result[1] = g_strdup(priv->passwd);
+ } else {
+ result[1] = lbs_get_password(server, NULL);
+ }
+ break;
+ case NET_CLIENT_AUTH_KERBEROS:
+ break; /* only user name required */
+ case NET_CLIENT_AUTH_OAUTH2:
+ break; // FIXME!! get the OAuth2 token in result[1]
+ default:
+ g_assert_not_reached();
}
}
return result;
diff --git a/libbalsa/server.h b/libbalsa/server.h
index 34584ef31..5dc4cc5c5 100644
--- a/libbalsa/server.h
+++ b/libbalsa/server.h
@@ -64,9 +64,9 @@ void libbalsa_server_save_config(LibBalsaServer * server);
/* NetClient related signal handlers */
-gchar **libbalsa_server_get_auth(NetClient *client,
- gboolean need_passwd,
- gpointer user_data);
+gchar **libbalsa_server_get_auth(NetClient *client,
+ NetClientAuthMode mode,
+ gpointer user_data);
gboolean libbalsa_server_check_cert(NetClient *client,
GTlsCertificate *peer_cert,
GTlsCertificateFlags errors,
diff --git a/libbalsa/smtp-server.c b/libbalsa/smtp-server.c
index a0ca8dd7c..22e3ec695 100644
--- a/libbalsa/smtp-server.c
+++ b/libbalsa/smtp-server.c
@@ -35,6 +35,13 @@
# include "macosx-helpers.h"
#endif
+
+#ifdef G_LOG_DOMAIN
+# undef G_LOG_DOMAIN
+#endif
+#define G_LOG_DOMAIN "libbalsa-server"
+
+
struct _LibBalsaSmtpServer {
LibBalsaServer server;
diff --git a/libnetclient/net-client-pop.c b/libnetclient/net-client-pop.c
index 2f6456948..883e8bee9 100644
--- a/libnetclient/net-client-pop.c
+++ b/libnetclient/net-client-pop.c
@@ -39,21 +39,24 @@ struct _NetClientPop {
* @{
*/
/** RFC 1939 "USER" and "PASS" authentication method. */
-#define NET_CLIENT_POP_AUTH_USER_PASS 0x01U
+#define NET_CLIENT_POP_AUTH_USER_PASS 0x001U
/** RFC 1939 "APOP" authentication method. */
-#define NET_CLIENT_POP_AUTH_APOP 0x02U
+#define NET_CLIENT_POP_AUTH_APOP 0x002U
/** RFC 5034 SASL "LOGIN" authentication method. */
-#define NET_CLIENT_POP_AUTH_LOGIN 0x04U
+#define NET_CLIENT_POP_AUTH_LOGIN 0x004U
/** RFC 5034 SASL "PLAIN" authentication method. */
-#define NET_CLIENT_POP_AUTH_PLAIN 0x08U
+#define NET_CLIENT_POP_AUTH_PLAIN 0x008U
/** RFC 5034 SASL "CRAM-MD5" authentication method. */
-#define NET_CLIENT_POP_AUTH_CRAM_MD5 0x10U
+#define NET_CLIENT_POP_AUTH_CRAM_MD5 0x010U
/** RFC 5034 SASL "CRAM-SHA1" authentication method. */
-#define NET_CLIENT_POP_AUTH_CRAM_SHA1 0x20U
+#define NET_CLIENT_POP_AUTH_CRAM_SHA1 0x020U
/** RFC 4752 "GSSAPI" authentication method. */
-#define NET_CLIENT_POP_AUTH_GSSAPI 0x40U
+#define NET_CLIENT_POP_AUTH_GSSAPI 0x040U
/** RFC 6749 "XOAUTH2" authentication method. */
-#define NET_CLIENT_POP_AUTH_OAUTH2 0x80U
+#define NET_CLIENT_POP_AUTH_OAUTH2 0x080U
+/** RFC 4505 "ANONYMOUS" authentication method. */
+#define NET_CLIENT_POP_AUTH_ANONYMOUS 0x100U
+
/** Mask of all authentication methods requiring user name and password. */
#define NET_CLIENT_POP_AUTH_PASSWORD \
@@ -62,9 +65,7 @@ struct _NetClientPop {
/** Mask of all authentication methods. */
#define NET_CLIENT_POP_AUTH_ALL \
- (NET_CLIENT_POP_AUTH_PASSWORD + NET_CLIENT_POP_AUTH_GSSAPI + NET_CLIENT_POP_AUTH_OAUTH2)
-/** Mask of all authentication methods which do not require a password (Note: OAuth2 requires the
authentication token). */
-#define NET_CLIENT_POP_AUTH_NO_PWD NET_CLIENT_POP_AUTH_GSSAPI
+ (NET_CLIENT_POP_AUTH_PASSWORD + NET_CLIENT_POP_AUTH_GSSAPI + NET_CLIENT_POP_AUTH_OAUTH2 +
NET_CLIENT_POP_AUTH_ANONYMOUS)
/** @} */
@@ -95,10 +96,10 @@ static gboolean net_client_pop_starttls(NetClientPop *client, GError **error);
static gboolean net_client_pop_execute(NetClientPop *client, const gchar *request_fmt, gchar **last_reply,
GError **error, ...)
G_GNUC_PRINTF(2, 5);
static gboolean net_client_pop_execute_sasl(NetClientPop *client, const gchar *request_fmt, gchar
**challenge, GError **error, ...);
-static gboolean net_client_pop_auth(NetClientPop *client, const gchar *user, const gchar *passwd, guint
auth_supported,
- GError **error);
+static gboolean net_client_pop_auth(NetClientPop *client, guint auth_supported, GError **error);
static gboolean net_client_pop_auth_plain(NetClientPop *client, const gchar* user, const gchar* passwd,
GError** error);
static gboolean net_client_pop_auth_login(NetClientPop *client, const gchar *user, const gchar *passwd,
GError **error);
+static gboolean net_client_pop_auth_anonymous(NetClientPop *client, GError **error);
static gboolean net_client_pop_auth_user_pass(NetClientPop *client, const gchar* user, const gchar* passwd,
GError** error);
static gboolean net_client_pop_auth_apop(NetClientPop *client, const gchar* user, const gchar* passwd,
GError** error);
static gboolean net_client_pop_auth_cram(NetClientPop *client, GChecksumType chksum_type, const gchar *user,
const gchar *passwd,
@@ -237,6 +238,9 @@ net_client_pop_set_auth_mode(NetClientPop *client, NetClientAuthMode auth_mode,
g_return_val_if_fail(NET_IS_CLIENT_POP(client), FALSE);
client->auth_enabled = 0U;
+ if ((auth_mode & NET_CLIENT_AUTH_NONE_ANON) != 0U) {
+ client->auth_enabled |= NET_CLIENT_POP_AUTH_ANONYMOUS;
+ }
if ((auth_mode & NET_CLIENT_AUTH_USER_PASS) != 0U) {
client->auth_enabled |= NET_CLIENT_POP_AUTH_PASSWORD;
if (disable_apop) {
@@ -319,19 +323,7 @@ net_client_pop_connect(NetClientPop *client, gchar **greeting, GError **error)
/* authenticate if we were successful so far */
if (result) {
- gchar **auth_data;
- gboolean need_pwd;
-
- auth_data = NULL;
- need_pwd = (auth_supported & NET_CLIENT_POP_AUTH_NO_PWD) == 0U;
- 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]);
- }
- g_free(auth_data);
+ result = net_client_pop_auth(client, auth_supported, error);
}
return result;
@@ -626,46 +618,78 @@ net_client_pop_starttls(NetClientPop *client, GError **error)
static gboolean
-net_client_pop_auth(NetClientPop *client, const gchar *user, const gchar *passwd, guint auth_supported,
GError **error)
+net_client_pop_auth(NetClientPop *client, guint auth_supported, GError **error)
{
gboolean result = FALSE;
guint auth_mask;
+ gchar **auth_data = NULL;
/* calculate the possible authentication methods */
auth_mask = client->auth_enabled & auth_supported;
+ /* try, in this order, enabled modes: anonymous; GSSAPI/Kerberos; OAuth2; user name and password */
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 if ((auth_mask & NET_CLIENT_POP_AUTH_ANONYMOUS) != 0U) {
+ /* Anonymous authentication - nothing required */
+ result = net_client_pop_auth_anonymous(client, error);
+ } else if ((auth_mask & NET_CLIENT_POP_AUTH_GSSAPI) != 0U) {
+ /* GSSAPI aka Kerberos authentication - user name required */
+ g_signal_emit_by_name(client, "auth", NET_CLIENT_AUTH_KERBEROS, &auth_data);
+ if ((auth_data == NULL) || (auth_data[0] == NULL)) {
+ g_set_error(error, NET_CLIENT_POP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_POP_NO_AUTH,
_("user name required"));
+ } else {
+ result = net_client_pop_auth_gssapi(client, auth_data[0], error);
+ }
+ } else if ((auth_mask & NET_CLIENT_POP_AUTH_OAUTH2) != 0U) {
+ /* OAuth2 authentication - user name and access token required */
+ g_signal_emit_by_name(client, "auth", NET_CLIENT_AUTH_OAUTH2, &auth_data);
+ if ((auth_data == NULL) || (auth_data[0] == NULL) || (auth_data[1] == NULL)) {
+ g_set_error(error, NET_CLIENT_POP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_POP_NO_AUTH,
+ _("user name and access token required"));
+ } else {
+ result = net_client_pop_auth_oauth2(client, auth_data[0], auth_data[1], error);
+ }
} else {
- /* first try authentication methods w/o password, then safe ones, and finally the plain-text
methods */
- if ((auth_mask & NET_CLIENT_POP_AUTH_OAUTH2) != 0U) {
- result = net_client_pop_auth_oauth2(client, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_POP_AUTH_GSSAPI) != 0U) {
- result = net_client_pop_auth_gssapi(client, user, error);
- } else if ((auth_mask & NET_CLIENT_POP_AUTH_CRAM_SHA1) != 0U) {
- result = net_client_pop_auth_cram(client, G_CHECKSUM_SHA1, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_POP_AUTH_CRAM_MD5) != 0U) {
- result = net_client_pop_auth_cram(client, G_CHECKSUM_MD5, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_POP_AUTH_APOP) != 0U) {
- result = net_client_pop_auth_apop(client, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_POP_AUTH_PLAIN) != 0U) {
- result = net_client_pop_auth_plain(client, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_POP_AUTH_USER_PASS) != 0U) {
- result = net_client_pop_auth_user_pass(client, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_POP_AUTH_LOGIN) != 0U) {
- result = net_client_pop_auth_login(client, user, passwd, error);
+ /* user name and password authentication methods */
+ g_signal_emit_by_name(client, "auth", NET_CLIENT_AUTH_USER_PASS, &auth_data);
+ if ((auth_data == NULL) || (auth_data[0] == NULL) || (auth_data[1] == NULL)) {
+ g_set_error(error, NET_CLIENT_POP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_POP_NO_AUTH,
+ _("user name and password required"));
} else {
- g_assert_not_reached();
+ /* first check for safe (hashed) authentication methods, used plain-text ones if they
are not supported */
+ if ((auth_mask & NET_CLIENT_POP_AUTH_CRAM_SHA1) != 0U) {
+ result = net_client_pop_auth_cram(client, G_CHECKSUM_SHA1, auth_data[0],
auth_data[1], error);
+ } else if ((auth_mask & NET_CLIENT_POP_AUTH_CRAM_MD5) != 0U) {
+ result = net_client_pop_auth_cram(client, G_CHECKSUM_MD5, auth_data[0],
auth_data[1], error);
+ } else if ((auth_mask & NET_CLIENT_POP_AUTH_APOP) != 0U) {
+ result = net_client_pop_auth_apop(client, auth_data[0], auth_data[1], error);
+ } else if ((auth_mask & NET_CLIENT_POP_AUTH_PLAIN) != 0U) {
+ result = net_client_pop_auth_plain(client, auth_data[0], auth_data[1], error);
+ } else if ((auth_mask & NET_CLIENT_POP_AUTH_LOGIN) != 0U) {
+ result = net_client_pop_auth_login(client, auth_data[0], auth_data[1], error);
+ } else if ((auth_mask & NET_CLIENT_POP_AUTH_USER_PASS) != 0U) {
+ result = net_client_pop_auth_user_pass(client, auth_data[0], auth_data[1],
error);
+ } else {
+ 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 == (gint)
NET_CLIENT_ERROR_POP_SERVER_ERR)) {
- (*error)->code = (gint) NET_CLIENT_ERROR_POP_AUTHFAIL;
+ /* 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 != NULL) && ((*error)->code == (gint)
NET_CLIENT_ERROR_POP_SERVER_ERR)) {
+ (*error)->code = (gint) NET_CLIENT_ERROR_POP_AUTHFAIL;
+ }
+
+ /* clean up any auth data */
+ if (auth_data != NULL) {
+ if (auth_data[0] != NULL) {
+ net_client_free_authstr(auth_data[0]);
+ net_client_free_authstr(auth_data[1]);
}
+ free(auth_data);
}
return result;
@@ -716,6 +740,24 @@ net_client_pop_auth_login(NetClientPop *client, const gchar *user, const gchar *
}
+static gboolean
+net_client_pop_auth_anonymous(NetClientPop *client, GError **error)
+{
+ gboolean result;
+
+ result = net_client_pop_execute_sasl(client, "AUTH ANONYMOUS", NULL, error);
+ if (result) {
+ gchar *base64_buf;
+
+ base64_buf = net_client_auth_anonymous_token();
+ result = net_client_pop_execute(client, "%s", NULL, error, base64_buf);
+ net_client_free_authstr(base64_buf);
+ }
+
+ return result;
+}
+
+
static gboolean
net_client_pop_auth_user_pass(NetClientPop *client, const gchar *user, const gchar *passwd, GError **error)
{
@@ -856,7 +898,7 @@ net_client_pop_auth_oauth2(NetClientPop *client, const gchar *user, const gchar
static gboolean
net_client_pop_auth_oauth2(NetClientPop G_GNUC_UNUSED *client, const gchar G_GNUC_UNUSED *user,
- const gcharG_GNUC_UNUSED *access_token, GError G_GNUC_UNUSED **error)
+ const gchar G_GNUC_UNUSED *access_token, GError G_GNUC_UNUSED **error)
{
g_assert_not_reached(); /* this should never happen! */
return FALSE; /* never reached, make gcc happy */
@@ -932,6 +974,8 @@ net_client_pop_get_capa(NetClientPop *client, guint *auth_supported)
*auth_supported |= NET_CLIENT_POP_AUTH_CRAM_MD5;
} else if (strcmp(auth[n], "CRAM-SHA1") == 0) {
*auth_supported |= NET_CLIENT_POP_AUTH_CRAM_SHA1;
+ } else if (strcmp(auth[n], "ANONYMOUS") == 0) {
+ *auth_supported |= NET_CLIENT_POP_AUTH_ANONYMOUS;
#if defined(HAVE_GSSAPI)
} else if (strcmp(auth[n], "GSSAPI") == 0) {
*auth_supported |= NET_CLIENT_POP_AUTH_GSSAPI;
@@ -941,7 +985,7 @@ net_client_pop_get_capa(NetClientPop *client, guint *auth_supported)
*auth_supported |= NET_CLIENT_POP_AUTH_OAUTH2;
#endif
} else {
- /* other auth methods are ignored for the time being */
+ /* other auth methods are ignored for the time being (see
MISRA C:2012, Rule 15.7) */
}
}
g_strfreev(auth);
diff --git a/libnetclient/net-client-pop.h b/libnetclient/net-client-pop.h
index 58faeff60..8b94c9ed3 100644
--- a/libnetclient/net-client-pop.h
+++ b/libnetclient/net-client-pop.h
@@ -138,9 +138,9 @@ gboolean net_client_pop_set_auth_mode(NetClientPop *client, NetClientAuthMode au
* information. Simply ignore the signal for an unauthenticated connection.
*
* The function will try only @em one authentication method which is both supported by the server and
enabled by calling
- * net_client_pop_set_auth_mode(). The default is to try all methods, from highest to lowest, OAuth2 (if
configured), GSSAPI (if
- * configured), CRAM-SHA1, CRAM-MD5, APOP, PLAIN, USER/PASS or LOGIN. It is up to the caller to ensure
encryption or a connection
- * to @c localhost if one of the plain text methods shall be used.
+ * net_client_pop_set_auth_mode(). The precedence is: ANONYMOUS, GSSAPI (Kerberos), OAuth2, user name and
password. For the
+ * latter, the order is CRAM-SHA1, CRAM-MD5, APOP, PLAIN, LOGIN or USER/PASS. It is up to the caller to
ensure encryption or a
+ * connection to @c localhost if one of the plain text methods shall be used.
*
* In order to shut down a successfully established connection, just call <tt>g_object_unref()</tt> on the
POP network client
* object.
@@ -227,10 +227,11 @@ void net_client_pop_msg_info_free(NetClientPopMessageInfo *info);
* - the <i>STAT</i>, <i>LIST</i>, <i>RETR</i> and <i>DELE</i> commands as defined in RFC 1939;
* - support for <i>PIPELINING</i> and <i>UIDL</i> as defined by <a
href="https://tools.ietf.org/html/rfc2449">RFC 2449</a>;
* - <i>STLS</i> encryption as defined by <a href="https://tools.ietf.org/html/rfc2595">RFC 2595</a>;
- * - authentication using <i>APOP</i>, <i>USER/PASS</i> (both RFC 1939) or the SASL methods <i>PLAIN</i>,
<i>LOGIN</i>,
- * <i>CRAM-MD5</i>, <i>CRAM-SHA1</i> or <i>GSSAPI</i> (see <a
href="https://tools.ietf.org/html/rfc4752">RFC 4752</a> and
- * <a href="https://tools.ietf.org/html/rfc5034">RFC 5034</a>), depending upon the capabilities reported
by the server. Note the
- * <i>GSSAPI</i> is available only if configured with gssapi support.
+ * - authentication using <i>APOP</i>, <i>USER/PASS</i> (both RFC 1939) or the SASL methods
<i>ANONYMOUS</i>, <i>PLAIN</i>,
+ * <i>LOGIN</i>, <i>CRAM-MD5</i>, <i>CRAM-SHA1</i>, <i>GSSAPI</i> (see <a
href="https://tools.ietf.org/html/rfc4752">RFC
+ * 4752</a> and <a href="https://tools.ietf.org/html/rfc5034">RFC 5034</a>) or <i>XOAUTH2</i> (<a
+ * href="https://tools.ietf.org/html/rfc6749">RFC 6749</a>) depending upon the capabilities reported by
the server. Note that
+ * <i>GSSAPI</i> and <i>XOAUTH2</i> are available only if configured with the respective support.
*/
diff --git a/libnetclient/net-client-smtp.c b/libnetclient/net-client-smtp.c
index be0d41332..925803749 100644
--- a/libnetclient/net-client-smtp.c
+++ b/libnetclient/net-client-smtp.c
@@ -71,8 +71,6 @@ typedef struct {
/** Mask of all authentication methods. */
#define NET_CLIENT_SMTP_AUTH_ALL \
(NET_CLIENT_SMTP_AUTH_NONE | NET_CLIENT_SMTP_AUTH_PASSWORD | NET_CLIENT_SMTP_AUTH_GSSAPI |
NET_CLIENT_SMTP_AUTH_OAUTH2)
-/** Mask of all authentication methods which do not require a password (Note: OAuth2 requires the
authentication token). */
-#define NET_CLIENT_SMTP_AUTH_NO_PWD NET_CLIENT_SMTP_AUTH_GSSAPI
/** @} */
@@ -91,8 +89,7 @@ static gboolean net_client_smtp_ehlo(NetClientSmtp *client, guint *auth_supporte
static gboolean net_client_smtp_starttls(NetClientSmtp *client, GError **error);
static gboolean net_client_smtp_execute(NetClientSmtp *client, const gchar *request_fmt, gchar **last_reply,
GError **error, ...)
G_GNUC_PRINTF(2, 5);
-static gboolean net_client_smtp_auth(NetClientSmtp *client, const gchar *user, const gchar *passwd, guint
auth_supported,
- GError **error);
+static gboolean net_client_smtp_auth(NetClientSmtp *client, guint auth_supported, GError **error);
static gboolean net_client_smtp_auth_plain(NetClientSmtp *client, const gchar *user, const gchar *passwd,
GError **error);
static gboolean net_client_smtp_auth_login(NetClientSmtp *client, const gchar *user, const gchar *passwd,
GError **error);
static gboolean net_client_smtp_auth_cram(NetClientSmtp *client, GChecksumType chksum_type, const gchar
*user, const gchar *passwd,
@@ -133,7 +130,7 @@ net_client_smtp_set_auth_mode(NetClientSmtp *client, NetClientAuthMode auth_mode
g_return_val_if_fail(NET_IS_CLIENT_SMTP(client), FALSE);
client->auth_enabled = 0U;
- if ((auth_mode & NET_CLIENT_AUTH_ANONYMOUS) != 0U) {
+ if ((auth_mode & NET_CLIENT_AUTH_NONE_ANON) != 0U) {
client->auth_enabled |= NET_CLIENT_SMTP_AUTH_NONE;
}
if ((auth_mode & NET_CLIENT_AUTH_USER_PASS) != 0U) {
@@ -300,20 +297,8 @@ net_client_smtp_connect(NetClientSmtp *client, gchar **greeting, GError **error)
}
/* authenticate if we were successful so far, unless anonymous access is configured */
- if (result && (client->auth_enabled != NET_CLIENT_SMTP_AUTH_NONE)) {
- gchar **auth_data;
- gboolean need_pwd;
-
- auth_data = NULL;
- need_pwd = (auth_supported & NET_CLIENT_SMTP_AUTH_NO_PWD) == 0U;
- 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]);
- }
- g_free(auth_data);
+ if (result && ((client->auth_enabled & NET_CLIENT_SMTP_AUTH_NONE) == 0U)) {
+ result = net_client_smtp_auth(client, auth_supported, error);
}
return result;
@@ -526,36 +511,65 @@ net_client_smtp_starttls(NetClientSmtp *client, GError **error)
static gboolean
-net_client_smtp_auth(NetClientSmtp *client, const gchar *user, const gchar *passwd, guint auth_supported,
GError **error)
+net_client_smtp_auth(NetClientSmtp *client, guint auth_supported, GError **error)
{
gboolean result = FALSE;
guint auth_mask;
+ gchar **auth_data = NULL;
/* calculate the possible authentication methods */
auth_mask = client->auth_enabled & auth_supported;
+ /* try, in this order, enabled modes: GSSAPI/Kerberos; OAuth2; user name and password */
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 if ((auth_mask & NET_CLIENT_SMTP_AUTH_GSSAPI) != 0U) {
+ /* GSSAPI aka Kerberos authentication - user name required */
+ g_signal_emit_by_name(client, "auth", NET_CLIENT_AUTH_KERBEROS, &auth_data);
+ if ((auth_data == NULL) || (auth_data[0] == NULL)) {
+ g_set_error(error, NET_CLIENT_SMTP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_SMTP_NO_AUTH,
_("user name required"));
+ } else {
+ result = net_client_smtp_auth_gssapi(client, auth_data[0], error);
+ }
+ } else if ((auth_mask & NET_CLIENT_SMTP_AUTH_OAUTH2) != 0U) {
+ /* OAuth2 authentication - user name and access token required */
+ g_signal_emit_by_name(client, "auth", NET_CLIENT_AUTH_OAUTH2, &auth_data);
+ if ((auth_data == NULL) || (auth_data[0] == NULL) || (auth_data[1] == NULL)) {
+ g_set_error(error, NET_CLIENT_SMTP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_SMTP_NO_AUTH,
+ _("user name and access token required"));
+ } else {
+ result = net_client_smtp_auth_oauth2(client, auth_data[0], auth_data[1], error);
+ }
} else {
- /* first try authentication methods w/o password, then safe ones, and finally the plain-text
methods */
- if ((auth_mask & NET_CLIENT_SMTP_AUTH_OAUTH2) != 0U) {
- result = net_client_smtp_auth_oauth2(client, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_SMTP_AUTH_GSSAPI) != 0U) {
- result = net_client_smtp_auth_gssapi(client, user, error);
- } else if ((auth_mask & NET_CLIENT_SMTP_AUTH_CRAM_SHA1) != 0U) {
- result = net_client_smtp_auth_cram(client, G_CHECKSUM_SHA1, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_SMTP_AUTH_CRAM_MD5) != 0U) {
- result = net_client_smtp_auth_cram(client, G_CHECKSUM_MD5, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_SMTP_AUTH_PLAIN) != 0U) {
- result = net_client_smtp_auth_plain(client, user, passwd, error);
- } else if ((auth_mask & NET_CLIENT_SMTP_AUTH_LOGIN) != 0U) {
- result = net_client_smtp_auth_login(client, user, passwd, error);
+ /* user name and password authentication methods */
+ g_signal_emit_by_name(client, "auth", NET_CLIENT_AUTH_USER_PASS, &auth_data);
+ if ((auth_data == NULL) || (auth_data[0] == NULL) || (auth_data[1] == NULL)) {
+ g_set_error(error, NET_CLIENT_SMTP_ERROR_QUARK, (gint) NET_CLIENT_ERROR_SMTP_NO_AUTH,
+ _("user name and password required"));
} else {
- g_assert_not_reached();
+ /* first check for safe (hashed) authentication methods, used plain-text ones if they
are not supported */
+ if ((auth_mask & NET_CLIENT_SMTP_AUTH_CRAM_SHA1) != 0U) {
+ result = net_client_smtp_auth_cram(client, G_CHECKSUM_SHA1, auth_data[0],
auth_data[1], error);
+ } else if ((auth_mask & NET_CLIENT_SMTP_AUTH_CRAM_MD5) != 0U) {
+ result = net_client_smtp_auth_cram(client, G_CHECKSUM_MD5, auth_data[0],
auth_data[1], error);
+ } else if ((auth_mask & NET_CLIENT_SMTP_AUTH_PLAIN) != 0U) {
+ result = net_client_smtp_auth_plain(client, auth_data[0], auth_data[1],
error);
+ } else if ((auth_mask & NET_CLIENT_SMTP_AUTH_LOGIN) != 0U) {
+ result = net_client_smtp_auth_login(client, auth_data[0], auth_data[1],
error);
+ } else {
+ g_assert_not_reached();
+ }
+ }
+ }
+
+ /* clean up any auth data */
+ if (auth_data != NULL) {
+ if (auth_data[0] != NULL) {
+ net_client_free_authstr(auth_data[0]);
+ net_client_free_authstr(auth_data[1]);
}
+ free(auth_data);
}
return result;
diff --git a/libnetclient/net-client-smtp.h b/libnetclient/net-client-smtp.h
index c26d61c1a..373eb8916 100644
--- a/libnetclient/net-client-smtp.h
+++ b/libnetclient/net-client-smtp.h
@@ -125,8 +125,8 @@ gboolean net_client_smtp_set_auth_mode(NetClientSmtp *client, NetClientAuthMode
* information unless anonymous access has been configured by calling net_client_smtp_set_auth_mode().
*
* The function will try only @em one authentication method which is both supported by the server and
enabled by calling
- * net_client_smtp_set_auth_mode(). The default is to try all methods, from highest to lowest, OAuth2 (if
configured), GSSAPI (if
- * configured), CRAM-SHA1, CRAM-MD5, PLAIN, LOGIN or anonymous. It is up to the caller to ensure encryption
or a connection to
+ * net_client_smtp_set_auth_mode(). The precedence is: no authentication, GSSAPI (Kerberos), OAuth2, user
name and password. For
+ * the latter, the order is CRAM-SHA1, CRAM-MD5, PLAIN, or LOGIN. It is up to the caller to ensure
encryption or a connection to
* @c localhost if one of the plain text methods shall be used.
*
* In order to shut down a successfully established connection, just call <tt>g_object_unref()</tt> on the
SMTP network client
diff --git a/libnetclient/net-client-utils.c b/libnetclient/net-client-utils.c
index 04b8c422a..0781956f0 100644
--- a/libnetclient/net-client-utils.c
+++ b/libnetclient/net-client-utils.c
@@ -129,6 +129,25 @@ net_client_auth_plain_calc(const gchar *user, const gchar *passwd)
}
+gchar *
+net_client_auth_anonymous_token(void)
+{
+ gchar *buffer;
+ GChecksum *hash;
+ const gchar *hash_str;
+
+ buffer = g_strdup_printf("%s@%s:%ld", g_get_user_name(), g_get_host_name(), (long) time(NULL));
+ hash = g_checksum_new(G_CHECKSUM_SHA256);
+ g_checksum_update(hash, (const guchar *) buffer, strlen(buffer));
+ g_free(buffer);
+
+ hash_str = g_checksum_get_string(hash);
+ buffer = g_base64_encode((const guchar *) hash_str, strlen(hash_str));
+ g_checksum_free(hash);
+ return buffer;
+}
+
+
void
net_client_free_authstr(gchar *str)
{
diff --git a/libnetclient/net-client-utils.h b/libnetclient/net-client-utils.h
index b521d4c62..4ca69f461 100644
--- a/libnetclient/net-client-utils.h
+++ b/libnetclient/net-client-utils.h
@@ -83,7 +83,7 @@ const gchar *net_client_chksum_to_str(GChecksumType chksum_type);
* @param passwd password
* @return a newly allocated string containing the base64-encoded authentication
*
- * This helper function calculates the the base64-encoded SASL AUTH PLAIN authentication string from the
user name and the password
+ * This helper function calculates the base64-encoded SASL AUTH PLAIN authentication string from the user
name and the password
* according to <a href="https://tools.ietf.org/html/rfc4616">RFC 4616</a>. The caller shall free the
returned string when it is
* not needed any more.
*/
@@ -101,6 +101,21 @@ gchar *net_client_auth_plain_calc(const gchar *user, const gchar *passwd)
void net_client_free_authstr(gchar *str);
+/** @brief Create a token for anonymous authentication
+ *
+ * @return a newly allocated string containing the base64-encoded authentication
+ *
+ * This helper function calculates a base64-encoded SASL AUTH ANONYMOUS authentication token which is used
as trace information by
+ * the server. As recommended by RFC 4505, the token does not contain personal data. The returned value is
the encoded SHA256 hex
+ * hash of the string <c>user-name@host-name:time<c> (time is the creation time stamp as returned by
time()). This token will be
+ * unique, but makes it impossible for the server to extract user and host. However, the client @em may
store to token if linking
+ * server to client operations is required, e.g. for debugging purposes.
+ *
+ * The caller shall free the returned string when it is not needed any more.
+ */
+gchar *net_client_auth_anonymous_token(void);
+
+
#if defined(HAVE_GSSAPI)
/** @brief Create a GSSAPI authentication context
diff --git a/libnetclient/net-client.h b/libnetclient/net-client.h
index ab6102264..68392aaa8 100644
--- a/libnetclient/net-client.h
+++ b/libnetclient/net-client.h
@@ -52,7 +52,7 @@ enum _NetClientCryptMode {
/** @brief Authentication mode */
enum _NetClientAuthMode {
- NET_CLIENT_AUTH_ANONYMOUS = 1, /**< No authentication required (e.g. local service,
user cert authentication). */
+ NET_CLIENT_AUTH_NONE_ANON = 1, /**< No authentication (SMTP); anonymous
authentication (RFC 4505 for POP3, IMAP). */
NET_CLIENT_AUTH_USER_PASS = 2, /**< Authenticate with user name and password. */
NET_CLIENT_AUTH_KERBEROS = 4, /**< Authenticate with user name and Kerberos ticket.
*/
NET_CLIENT_AUTH_OAUTH2 = 8 /**< OAuth2 authentication (RFC 6749). */
@@ -343,12 +343,11 @@ gboolean net_client_can_read(NetClient *client);
* @endcode The server certificate is not trusted. The received certificate and the errors which occurred
during the check are
* passed to the signal handler. The handler shall return TRUE to accept the certificate, or FALSE to
reject it.
* - @anchor auth auth
- * @code gchar **get_auth(NetClient *client, gboolean need_passwd, gpointer user_data) @endcode
Authentication is required by the
- * remote server. The signal handler shall return a NULL-terminated array of strings, containing the user
name in the first and
- * the password in the second element. If the parameter @em need_passwd is FALSE, no password is required
(e.g. for kerberos
- * ticket-based or for OAuth2 authentication). In this case, the password element must be present in the
reply, but it is ignored
- * an may be NULL. The strings are wiped and freed when they are not needed any more. Return NULL if no
authentication is
- * required.
+ * @code gchar **get_auth(NetClient *client, NetClientAuthMode mode, gpointer user_data) @endcode
Authentication is required by
+ * the remote server. The signal handler shall return a NULL-terminated array of strings, containing the
user name in the first
+ * and the password (mode @ref NET_CLIENT_AUTH_USER_PASS) or the OAuth2 access token (@ref
NET_CLIENT_AUTH_OAUTH2) in the second
+ * element. For @ref NET_CLIENT_AUTH_KERBEROS, no password is required. In this case, the second element
must be present in the
+ * reply, but it is ignored and should be NULL. The strings are wiped and freed when they are not needed
any more.
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]