diff --git a/ChangeLog b/ChangeLog
index e71d563..6616bb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,6 @@
0.9.3
+ - Legacy authentication is disabled by default, can be enabled with
+ connection flag XMPP_CONN_FLAG_LEGACY_AUTH
- Session is not established if it is optional
- Fixed a bug causing a reused connection not to cleanup properly
- Improved debug logging in OpenSSL module
diff --git a/src/auth.c b/src/auth.c
index 6872b83..a23504e 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -61,6 +61,7 @@
#endif
static void _auth(xmpp_conn_t * const conn);
+static void _auth_legacy(xmpp_conn_t *conn);
static void _handle_open_sasl(xmpp_conn_t * const conn);
static void _handle_open_tls(xmpp_conn_t * const conn);
@@ -69,11 +70,6 @@ static int _handle_component_hs_response(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza,
void * const userdata);
-static int _handle_missing_legacy(xmpp_conn_t * const conn,
- void * const userdata);
-static int _handle_legacy(xmpp_conn_t * const conn,
- xmpp_stanza_t * const stanza,
- void * const userdata);
static int _handle_features_sasl(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza,
void * const userdata);
@@ -557,9 +553,11 @@ static xmpp_stanza_t *_make_sasl_auth(xmpp_conn_t * const conn,
*/
static void _auth(xmpp_conn_t * const conn)
{
- xmpp_stanza_t *auth, *authdata, *query, *child, *iq;
- char *str, *authid;
+ xmpp_stanza_t *auth;
+ xmpp_stanza_t *authdata;
+ char *authid;
char *scram_init;
+ char *str;
int anonjid;
/* if there is no node in conn->jid, we assume anonymous connect */
@@ -726,105 +724,12 @@ static void _auth(xmpp_conn_t * const conn)
/* SASL PLAIN was tried */
conn->sasl_support &= ~SASL_MASK_PLAIN;
- } else if (conn->type == XMPP_CLIENT) {
- /* legacy client authentication */
-
- iq = xmpp_iq_new(conn->ctx, "set", "_xmpp_auth1");
- if (!iq) {
- disconnect_mem_error(conn);
- return;
- }
-
- query = xmpp_stanza_new(conn->ctx);
- if (!query) {
- xmpp_stanza_release(iq);
- disconnect_mem_error(conn);
- return;
- }
- xmpp_stanza_set_name(query, "query");
- xmpp_stanza_set_ns(query, XMPP_NS_AUTH);
- xmpp_stanza_add_child(iq, query);
- xmpp_stanza_release(query);
-
- child = xmpp_stanza_new(conn->ctx);
- if (!child) {
- xmpp_stanza_release(iq);
- disconnect_mem_error(conn);
- return;
- }
- xmpp_stanza_set_name(child, "username");
- xmpp_stanza_add_child(query, child);
- xmpp_stanza_release(child);
-
- authdata = xmpp_stanza_new(conn->ctx);
- if (!authdata) {
- xmpp_stanza_release(iq);
- disconnect_mem_error(conn);
- return;
- }
- str = xmpp_jid_node(conn->ctx, conn->jid);
- xmpp_stanza_set_text(authdata, str);
- xmpp_free(conn->ctx, str);
- xmpp_stanza_add_child(child, authdata);
- xmpp_stanza_release(authdata);
-
- child = xmpp_stanza_new(conn->ctx);
- if (!child) {
- xmpp_stanza_release(iq);
- disconnect_mem_error(conn);
- return;
- }
- xmpp_stanza_set_name(child, "password");
- xmpp_stanza_add_child(query, child);
- xmpp_stanza_release(child);
-
- authdata = xmpp_stanza_new(conn->ctx);
- if (!authdata) {
- xmpp_stanza_release(iq);
- disconnect_mem_error(conn);
- return;
- }
- xmpp_stanza_set_text(authdata, conn->pass);
- xmpp_stanza_add_child(child, authdata);
- xmpp_stanza_release(authdata);
-
- child = xmpp_stanza_new(conn->ctx);
- if (!child) {
- xmpp_stanza_release(iq);
- disconnect_mem_error(conn);
- return;
- }
- xmpp_stanza_set_name(child, "resource");
- xmpp_stanza_add_child(query, child);
- xmpp_stanza_release(child);
-
- authdata = xmpp_stanza_new(conn->ctx);
- if (!authdata) {
- xmpp_stanza_release(iq);
- disconnect_mem_error(conn);
- return;
- }
- str = xmpp_jid_resource(conn->ctx, conn->jid);
- if (str) {
- xmpp_stanza_set_text(authdata, str);
- xmpp_free(conn->ctx, str);
- } else {
- xmpp_stanza_release(authdata);
- xmpp_stanza_release(iq);
- xmpp_error(conn->ctx, "auth",
- "Cannot authenticate without resource");
- xmpp_disconnect(conn);
- return;
- }
- xmpp_stanza_add_child(child, authdata);
- xmpp_stanza_release(authdata);
-
- handler_add_id(conn, _handle_legacy, "_xmpp_auth1", NULL);
- handler_add_timed(conn, _handle_missing_legacy,
- LEGACY_TIMEOUT, NULL);
-
- xmpp_send(conn, iq);
- xmpp_stanza_release(iq);
+ } else if (conn->type == XMPP_CLIENT && conn->auth_legacy_enabled) {
+ /* legacy client authentication */
+ _auth_legacy(conn);
+ } else {
+ xmpp_error(conn->ctx, "auth", "Cannot authenticate with known methods");
+ xmpp_disconnect(conn);
}
}
@@ -1105,6 +1010,15 @@ static int _handle_missing_session(xmpp_conn_t * const conn,
return 0;
}
+static int _handle_missing_legacy(xmpp_conn_t * const conn,
+ void * const userdata)
+{
+ xmpp_error(conn->ctx, "xmpp", "Server did not reply to legacy "\
+ "authentication request.");
+ xmpp_disconnect(conn);
+ return 0;
+}
+
static int _handle_legacy(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza,
void * const userdata)
@@ -1141,13 +1055,97 @@ static int _handle_legacy(xmpp_conn_t * const conn,
return 0;
}
-static int _handle_missing_legacy(xmpp_conn_t * const conn,
- void * const userdata)
+static void _auth_legacy(xmpp_conn_t *conn)
{
- xmpp_error(conn->ctx, "xmpp", "Server did not reply to legacy "\
- "authentication request.");
- xmpp_disconnect(conn);
- return 0;
+ xmpp_stanza_t *iq;
+ xmpp_stanza_t *authdata;
+ xmpp_stanza_t *query;
+ xmpp_stanza_t *child;
+ char *str;
+
+ xmpp_debug(conn->ctx, "auth", "Legacy authentication request");
+
+ iq = xmpp_iq_new(conn->ctx, "set", "_xmpp_auth1");
+ if (!iq)
+ goto err;
+
+ query = xmpp_stanza_new(conn->ctx);
+ if (!query)
+ goto err_free;
+ xmpp_stanza_set_name(query, "query");
+ xmpp_stanza_set_ns(query, XMPP_NS_AUTH);
+ xmpp_stanza_add_child(iq, query);
+ xmpp_stanza_release(query);
+
+ child = xmpp_stanza_new(conn->ctx);
+ if (!child)
+ goto err_free;
+ xmpp_stanza_set_name(child, "username");
+ xmpp_stanza_add_child(query, child);
+ xmpp_stanza_release(child);
+
+ authdata = xmpp_stanza_new(conn->ctx);
+ if (!authdata)
+ goto err_free;
+ str = xmpp_jid_node(conn->ctx, conn->jid);
+ if (!str) {
+ xmpp_stanza_release(authdata);
+ goto err_free;
+ }
+ xmpp_stanza_set_text(authdata, str);
+ xmpp_free(conn->ctx, str);
+ xmpp_stanza_add_child(child, authdata);
+ xmpp_stanza_release(authdata);
+
+ child = xmpp_stanza_new(conn->ctx);
+ if (!child)
+ goto err_free;
+ xmpp_stanza_set_name(child, "password");
+ xmpp_stanza_add_child(query, child);
+ xmpp_stanza_release(child);
+
+ authdata = xmpp_stanza_new(conn->ctx);
+ if (!authdata)
+ goto err_free;
+ xmpp_stanza_set_text(authdata, conn->pass);
+ xmpp_stanza_add_child(child, authdata);
+ xmpp_stanza_release(authdata);
+
+ child = xmpp_stanza_new(conn->ctx);
+ if (!child)
+ goto err_free;
+ xmpp_stanza_set_name(child, "resource");
+ xmpp_stanza_add_child(query, child);
+ xmpp_stanza_release(child);
+
+ authdata = xmpp_stanza_new(conn->ctx);
+ if (!authdata)
+ goto err_free;
+ str = xmpp_jid_resource(conn->ctx, conn->jid);
+ if (str) {
+ xmpp_stanza_set_text(authdata, str);
+ xmpp_free(conn->ctx, str);
+ } else {
+ xmpp_stanza_release(authdata);
+ xmpp_stanza_release(iq);
+ xmpp_error(conn->ctx, "auth", "Cannot authenticate without resource");
+ xmpp_disconnect(conn);
+ return;
+ }
+ xmpp_stanza_add_child(child, authdata);
+ xmpp_stanza_release(authdata);
+
+ handler_add_id(conn, _handle_legacy, "_xmpp_auth1", NULL);
+ handler_add_timed(conn, _handle_missing_legacy, LEGACY_TIMEOUT, NULL);
+
+ xmpp_send(conn, iq);
+ xmpp_stanza_release(iq);
+ return;
+
+err_free:
+ xmpp_stanza_release(iq);
+err:
+ disconnect_mem_error(conn);
}
void auth_handle_component_open(xmpp_conn_t * const conn)
diff --git a/src/common.h b/src/common.h
index f1356b0..e53e4ff 100644
--- a/src/common.h
+++ b/src/common.h
@@ -172,6 +172,7 @@ struct _xmpp_conn_t {
int tls_failed; /* set when tls fails, so we don't try again */
int sasl_support; /* if true, field is a bitfield of supported
mechanisms */
+ int auth_legacy_enabled;
int secured; /* set when stream is secured with TLS */
/* if server returns or we must do them */
diff --git a/src/conn.c b/src/conn.c
index 91cd9ab..316552c 100644
--- a/src/conn.c
+++ b/src/conn.c
@@ -140,6 +140,7 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx)
conn->tls_trust = 0;
conn->tls_failed = 0;
conn->sasl_support = 0;
+ conn->auth_legacy_enabled = 0;
conn->secured = 0;
conn->bind_required = 0;
@@ -921,7 +922,8 @@ long xmpp_conn_get_flags(const xmpp_conn_t * const conn)
flags = XMPP_CONN_FLAG_DISABLE_TLS * conn->tls_disabled |
XMPP_CONN_FLAG_MANDATORY_TLS * conn->tls_mandatory |
XMPP_CONN_FLAG_LEGACY_SSL * conn->tls_legacy_ssl |
- XMPP_CONN_FLAG_TRUST_TLS * conn->tls_trust;
+ XMPP_CONN_FLAG_TRUST_TLS * conn->tls_trust |
+ XMPP_CONN_FLAG_LEGACY_AUTH * conn->auth_legacy_enabled;;
return flags;
}
@@ -939,6 +941,7 @@ long xmpp_conn_get_flags(const xmpp_conn_t * const conn)
* - XMPP_CONN_FLAG_MANDATORY_TLS
* - XMPP_CONN_FLAG_LEGACY_SSL
* - XMPP_CONN_FLAG_TRUST_TLS
+ * - XMPP_CONN_FLAG_LEGACY_AUTH
*
* @param conn a Strophe connection object
* @param flags ORed connection flags
@@ -965,6 +968,7 @@ int xmpp_conn_set_flags(xmpp_conn_t * const conn, long flags)
conn->tls_mandatory = (flags & XMPP_CONN_FLAG_MANDATORY_TLS) ? 1 : 0;
conn->tls_legacy_ssl = (flags & XMPP_CONN_FLAG_LEGACY_SSL) ? 1 : 0;
conn->tls_trust = (flags & XMPP_CONN_FLAG_TRUST_TLS) ? 1 : 0;
+ conn->auth_legacy_enabled = (flags & XMPP_CONN_FLAG_LEGACY_AUTH) ? 1 : 0;
return 0;
}
diff --git a/strophe.h b/strophe.h
index 5a18f1a..d9f048f 100644
--- a/strophe.h
+++ b/strophe.h
@@ -169,6 +169,10 @@ typedef struct _xmpp_stanza_t xmpp_stanza_t;
* Trust server's certificate even if it is invalid.
*/
#define XMPP_CONN_FLAG_TRUST_TLS (1UL << 3)
+/** @def XMPP_CONN_FLAG_LEGACY_AUTH
+ * Enable legacy authentication support.
+ */
+#define XMPP_CONN_FLAG_LEGACY_AUTH (1UL << 4)
/* connect callback */
typedef enum {