Check for name element when reading mechanisms
Fixes an issue where the server sends whitespace between elements, a segfault would occur when performing a strcmp on the name.
This commit is contained in:
70
src/auth.c
70
src/auth.c
@@ -1,7 +1,7 @@
|
||||
/* auth.c
|
||||
** strophe XMPP client library -- auth functions and handlers
|
||||
**
|
||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||
**
|
||||
** This software is provided AS-IS with no warranty, either express or
|
||||
** implied.
|
||||
@@ -9,7 +9,7 @@
|
||||
** This program is dual licensed under the MIT and GPLv3 licenses.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
/** @file
|
||||
* Authentication function and handlers.
|
||||
*/
|
||||
|
||||
@@ -116,7 +116,7 @@ static int _handle_error(xmpp_conn_t * const conn,
|
||||
/* free old stream error if it's still there */
|
||||
if (conn->stream_error) {
|
||||
xmpp_stanza_release(conn->stream_error->stanza);
|
||||
if (conn->stream_error->text)
|
||||
if (conn->stream_error->text)
|
||||
xmpp_free(conn->ctx, conn->stream_error->text);
|
||||
xmpp_free(conn->ctx, conn->stream_error);
|
||||
}
|
||||
@@ -237,9 +237,9 @@ static int _handle_features(xmpp_conn_t * const conn,
|
||||
/* check for SASL */
|
||||
child = xmpp_stanza_get_child_by_name(stanza, "mechanisms");
|
||||
if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_SASL) == 0)) {
|
||||
for (mech = xmpp_stanza_get_children(child); mech;
|
||||
for (mech = xmpp_stanza_get_children(child); mech;
|
||||
mech = xmpp_stanza_get_next(mech)) {
|
||||
if (strcmp(xmpp_stanza_get_name(mech), "mechanism") == 0) {
|
||||
if (xmpp_stanza_get_name(mech) && strcmp(xmpp_stanza_get_name(mech), "mechanism") == 0) {
|
||||
text = xmpp_stanza_get_text(mech);
|
||||
if (strcasecmp(text, "PLAIN") == 0)
|
||||
conn->sasl_support |= SASL_MASK_PLAIN;
|
||||
@@ -256,7 +256,7 @@ static int _handle_features(xmpp_conn_t * const conn,
|
||||
}
|
||||
|
||||
_auth(conn);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ static int _handle_proceedtls_default(xmpp_conn_t * const conn,
|
||||
{
|
||||
char *name;
|
||||
name = xmpp_stanza_get_name(stanza);
|
||||
xmpp_debug(conn->ctx, "xmpp",
|
||||
xmpp_debug(conn->ctx, "xmpp",
|
||||
"handle proceedtls called for %s", name);
|
||||
|
||||
if (strcmp(name, "proceed") == 0) {
|
||||
@@ -295,7 +295,7 @@ static int _handle_proceedtls_default(xmpp_conn_t * const conn,
|
||||
tls_free(conn->tls);
|
||||
conn->tls = NULL;
|
||||
conn->tls_failed = 1;
|
||||
|
||||
|
||||
/* failed tls spoils the connection, so disconnect */
|
||||
xmpp_disconnect(conn);
|
||||
}
|
||||
@@ -321,14 +321,14 @@ static int _handle_sasl_result(xmpp_conn_t * const conn,
|
||||
|
||||
/* the server should send a <success> or <failure> stanza */
|
||||
if (strcmp(name, "failure") == 0) {
|
||||
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth failed",
|
||||
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth failed",
|
||||
(char *)userdata);
|
||||
|
||||
|
||||
/* fall back to next auth method */
|
||||
_auth(conn);
|
||||
} else if (strcmp(name, "success") == 0) {
|
||||
/* SASL PLAIN auth successful, we need to restart the stream */
|
||||
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth successful",
|
||||
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth successful",
|
||||
(char *)userdata);
|
||||
|
||||
/* reset parser */
|
||||
@@ -373,10 +373,10 @@ static int _handle_digestmd5_challenge(xmpp_conn_t * const conn,
|
||||
if (!auth) {
|
||||
disconnect_mem_error(conn);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
xmpp_stanza_set_name(auth, "response");
|
||||
xmpp_stanza_set_ns(auth, XMPP_NS_SASL);
|
||||
|
||||
|
||||
authdata = xmpp_stanza_new(conn->ctx);
|
||||
if (!authdata) {
|
||||
disconnect_mem_error(conn);
|
||||
@@ -389,7 +389,7 @@ static int _handle_digestmd5_challenge(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_add_child(auth, authdata);
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
handler_add(conn, _handle_digestmd5_rspauth,
|
||||
handler_add(conn, _handle_digestmd5_rspauth,
|
||||
XMPP_NS_SASL, NULL, NULL, NULL);
|
||||
|
||||
xmpp_send(conn, auth);
|
||||
@@ -422,7 +422,7 @@ static int _handle_digestmd5_rspauth(xmpp_conn_t * const conn,
|
||||
if (!auth) {
|
||||
disconnect_mem_error(conn);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
xmpp_stanza_set_name(auth, "response");
|
||||
xmpp_stanza_set_ns(auth, XMPP_NS_SASL);
|
||||
xmpp_send(conn, auth);
|
||||
@@ -555,7 +555,7 @@ static xmpp_stanza_t *_make_starttls(xmpp_conn_t * const conn)
|
||||
xmpp_stanza_set_name(starttls, "starttls");
|
||||
xmpp_stanza_set_ns(starttls, XMPP_NS_TLS);
|
||||
}
|
||||
|
||||
|
||||
return starttls;
|
||||
}
|
||||
|
||||
@@ -571,14 +571,14 @@ static xmpp_stanza_t *_make_sasl_auth(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_set_ns(auth, XMPP_NS_SASL);
|
||||
xmpp_stanza_set_attribute(auth, "mechanism", mechanism);
|
||||
}
|
||||
|
||||
|
||||
return auth;
|
||||
}
|
||||
|
||||
/* authenticate the connection
|
||||
* this may get called multiple times. if any auth method fails,
|
||||
/* authenticate the connection
|
||||
* this may get called multiple times. if any auth method fails,
|
||||
* this will get called again until one auth method succeeds or every
|
||||
* method fails
|
||||
* method fails
|
||||
*/
|
||||
static void _auth(xmpp_conn_t * const conn)
|
||||
{
|
||||
@@ -619,7 +619,7 @@ static void _auth(xmpp_conn_t * const conn)
|
||||
return;
|
||||
}
|
||||
|
||||
handler_add(conn, _handle_proceedtls_default,
|
||||
handler_add(conn, _handle_proceedtls_default,
|
||||
XMPP_NS_TLS, NULL, NULL, NULL);
|
||||
|
||||
xmpp_send(conn, auth);
|
||||
@@ -644,7 +644,7 @@ static void _auth(xmpp_conn_t * const conn)
|
||||
/* SASL ANONYMOUS was tried, unset flag */
|
||||
conn->sasl_support &= ~SASL_MASK_ANONYMOUS;
|
||||
} else if (anonjid) {
|
||||
xmpp_error(conn->ctx, "auth",
|
||||
xmpp_error(conn->ctx, "auth",
|
||||
"No node in JID, and SASL ANONYMOUS unsupported.");
|
||||
xmpp_disconnect(conn);
|
||||
} else if (conn->sasl_support & SASL_MASK_SCRAMSHA1) {
|
||||
@@ -700,7 +700,7 @@ static void _auth(xmpp_conn_t * const conn)
|
||||
|
||||
}
|
||||
|
||||
handler_add(conn, _handle_digestmd5_challenge,
|
||||
handler_add(conn, _handle_digestmd5_challenge,
|
||||
XMPP_NS_SASL, NULL, NULL, NULL);
|
||||
|
||||
xmpp_send(conn, auth);
|
||||
@@ -718,7 +718,7 @@ static void _auth(xmpp_conn_t * const conn)
|
||||
if (!authdata) {
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
authid = _get_authid(conn);
|
||||
if (!authid) {
|
||||
disconnect_mem_error(conn);
|
||||
@@ -746,7 +746,7 @@ static void _auth(xmpp_conn_t * const conn)
|
||||
conn->sasl_support &= ~SASL_MASK_PLAIN;
|
||||
} else if (conn->type == XMPP_CLIENT) {
|
||||
/* legacy client authentication */
|
||||
|
||||
|
||||
iq = xmpp_stanza_new(conn->ctx);
|
||||
if (!iq) {
|
||||
disconnect_mem_error(conn);
|
||||
@@ -832,7 +832,7 @@ static void _auth(xmpp_conn_t * const conn)
|
||||
} else {
|
||||
xmpp_stanza_release(authdata);
|
||||
xmpp_stanza_release(iq);
|
||||
xmpp_error(conn->ctx, "auth",
|
||||
xmpp_error(conn->ctx, "auth",
|
||||
"Cannot authenticate without resource");
|
||||
xmpp_disconnect(conn);
|
||||
return;
|
||||
@@ -841,7 +841,7 @@ static void _auth(xmpp_conn_t * const conn)
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
handler_add_id(conn, _handle_legacy, "_xmpp_auth1", NULL);
|
||||
handler_add_timed(conn, _handle_missing_legacy,
|
||||
handler_add_timed(conn, _handle_missing_legacy,
|
||||
LEGACY_TIMEOUT, NULL);
|
||||
|
||||
xmpp_send(conn, iq);
|
||||
@@ -853,7 +853,7 @@ static void _auth(xmpp_conn_t * const conn)
|
||||
/** Set up handlers at stream start.
|
||||
* This function is called internally to Strophe for handling the opening
|
||||
* of an XMPP stream. It's called by the parser when a stream is opened
|
||||
* or reset, and adds the initial handlers for <stream:error/> and
|
||||
* or reset, and adds the initial handlers for <stream:error/> and
|
||||
* <stream:features/>. This function is not intended for use outside
|
||||
* of Strophe.
|
||||
*
|
||||
@@ -915,7 +915,7 @@ static int _handle_features_sasl(xmpp_conn_t * const conn,
|
||||
/* if bind is required, go ahead and start it */
|
||||
if (conn->bind_required) {
|
||||
/* bind resource */
|
||||
|
||||
|
||||
/* setup response handlers */
|
||||
handler_add_id(conn, _handle_bind, "_xmpp_bind1", NULL);
|
||||
handler_add_timed(conn, _handle_missing_bind,
|
||||
@@ -947,7 +947,7 @@ static int _handle_features_sasl(xmpp_conn_t * const conn,
|
||||
resource = NULL;
|
||||
}
|
||||
|
||||
/* if we have a resource to request, do it. otherwise the
|
||||
/* if we have a resource to request, do it. otherwise the
|
||||
server will assign us one */
|
||||
if (resource) {
|
||||
res = xmpp_stanza_new(conn->ctx);
|
||||
@@ -998,7 +998,7 @@ static int _handle_missing_features_sasl(xmpp_conn_t * const conn,
|
||||
xmpp_disconnect(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _handle_bind(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza,
|
||||
void * const userdata)
|
||||
@@ -1030,7 +1030,7 @@ static int _handle_bind(xmpp_conn_t * const conn,
|
||||
if (conn->session_required) {
|
||||
/* setup response handlers */
|
||||
handler_add_id(conn, _handle_session, "_xmpp_session1", NULL);
|
||||
handler_add_timed(conn, _handle_missing_session,
|
||||
handler_add_timed(conn, _handle_missing_session,
|
||||
SESSION_TIMEOUT, NULL);
|
||||
|
||||
/* send session request */
|
||||
@@ -1061,9 +1061,9 @@ static int _handle_bind(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_release(iq);
|
||||
} else {
|
||||
conn->authenticated = 1;
|
||||
|
||||
|
||||
/* call connection handler */
|
||||
conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL,
|
||||
conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL,
|
||||
conn->userdata);
|
||||
}
|
||||
} else {
|
||||
@@ -1100,7 +1100,7 @@ static int _handle_session(xmpp_conn_t * const conn,
|
||||
xmpp_debug(conn->ctx, "xmpp", "Session establishment successful.");
|
||||
|
||||
conn->authenticated = 1;
|
||||
|
||||
|
||||
/* call connection handler */
|
||||
conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user