Implement SASL ANONYMOUS authentication.
This commit is contained in:
118
src/auth.c
118
src/auth.c
@@ -66,7 +66,7 @@ static int _handle_legacy(xmpp_conn_t * const conn,
|
|||||||
static int _handle_features_sasl(xmpp_conn_t * const conn,
|
static int _handle_features_sasl(xmpp_conn_t * const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t * const stanza,
|
||||||
void * const userdata);
|
void * const userdata);
|
||||||
static int _handle_digestmd5_default(xmpp_conn_t * const conn,
|
static int _handle_sasl_result(xmpp_conn_t * const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t * const stanza,
|
||||||
void * const userdata);
|
void * const userdata);
|
||||||
static int _handle_digestmd5_challenge(xmpp_conn_t * const conn,
|
static int _handle_digestmd5_challenge(xmpp_conn_t * const conn,
|
||||||
@@ -223,6 +223,8 @@ static int _handle_features(xmpp_conn_t * const conn,
|
|||||||
conn->sasl_support |= SASL_MASK_PLAIN;
|
conn->sasl_support |= SASL_MASK_PLAIN;
|
||||||
else if (strcasecmp(text, "DIGEST-MD5") == 0)
|
else if (strcasecmp(text, "DIGEST-MD5") == 0)
|
||||||
conn->sasl_support |= SASL_MASK_DIGESTMD5;
|
conn->sasl_support |= SASL_MASK_DIGESTMD5;
|
||||||
|
else if (strcasecmp(text, "ANONYMOUS") == 0)
|
||||||
|
conn->sasl_support |= SASL_MASK_ANONYMOUS;
|
||||||
|
|
||||||
xmpp_free(conn->ctx, text);
|
xmpp_free(conn->ctx, text);
|
||||||
}
|
}
|
||||||
@@ -284,49 +286,39 @@ static int _handle_proceedtls_default(xmpp_conn_t * const conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _handle_sasl_result(xmpp_conn_t * const conn,
|
||||||
static int _handle_digestmd5_default(xmpp_conn_t * const conn,
|
xmpp_stanza_t * const stanza,
|
||||||
xmpp_stanza_t * const stanza,
|
void * const userdata)
|
||||||
void * const userdata)
|
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
name = xmpp_stanza_get_name(stanza);
|
name = xmpp_stanza_get_name(stanza);
|
||||||
xmpp_debug(conn->ctx, "xmpp",
|
|
||||||
"handle digest-md5 (default) called for %s", name);
|
|
||||||
|
|
||||||
|
/* the server should send a <success> or <failure> stanza */
|
||||||
if (strcmp(name, "failure") == 0) {
|
if (strcmp(name, "failure") == 0) {
|
||||||
/* TODO: handle errors */
|
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth failed",
|
||||||
xmpp_debug(conn->ctx, "xmpp", "SASL DIGEST-MD5 auth failed!");
|
(char *)userdata);
|
||||||
|
|
||||||
/* fall back to next auth method */
|
/* fall back to next auth method */
|
||||||
_auth(conn);
|
_auth(conn);
|
||||||
|
|
||||||
/* remove handler */
|
|
||||||
ret = 0;
|
|
||||||
} else if (strcmp(name, "success") == 0) {
|
} else if (strcmp(name, "success") == 0) {
|
||||||
/* SASL DIGEST-MD5 auth successful, we need to restart the stream */
|
/* SASL PLAIN auth successful, we need to restart the stream */
|
||||||
xmpp_debug(conn->ctx, "xmpp", "SASL DIGEST-MD5 auth successful");
|
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth successful",
|
||||||
|
(char *)userdata);
|
||||||
|
|
||||||
/* reset parser */
|
/* reset parser */
|
||||||
parser_prepare_reset(conn, _handle_open_sasl);
|
parser_prepare_reset(conn, _handle_open_sasl);
|
||||||
|
|
||||||
/* send stream tag */
|
/* send stream tag */
|
||||||
conn_open_stream(conn);
|
conn_open_stream(conn);
|
||||||
|
|
||||||
/* remove handler */
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
} else {
|
||||||
/* got unexpected reply */
|
/* got unexpected reply */
|
||||||
xmpp_error(conn->ctx, "xmpp", "Got unexpected reply to SASL "
|
xmpp_error(conn->ctx, "xmpp", "Got unexpected reply to SASL %s"\
|
||||||
"DIGEST-MD5 authentication.");
|
"authentication.", (char *)userdata);
|
||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
|
|
||||||
/* remove handler */
|
|
||||||
ret = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle the challenge phase of digest auth */
|
/* handle the challenge phase of digest auth */
|
||||||
@@ -379,7 +371,7 @@ static int _handle_digestmd5_challenge(xmpp_conn_t * const conn,
|
|||||||
xmpp_stanza_release(auth);
|
xmpp_stanza_release(auth);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return _handle_digestmd5_default(conn, stanza, userdata);
|
return _handle_sasl_result(conn, stanza, "DIGEST-MD5");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove ourselves */
|
/* remove ourselves */
|
||||||
@@ -411,51 +403,12 @@ static int _handle_digestmd5_rspauth(xmpp_conn_t * const conn,
|
|||||||
xmpp_send(conn, auth);
|
xmpp_send(conn, auth);
|
||||||
xmpp_stanza_release(auth);
|
xmpp_stanza_release(auth);
|
||||||
} else {
|
} else {
|
||||||
return _handle_digestmd5_default(conn, stanza, userdata);
|
return _handle_sasl_result(conn, stanza, "DIGEST-MD5");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _handle_plain(xmpp_conn_t * const conn,
|
|
||||||
xmpp_stanza_t * const stanza,
|
|
||||||
void * const userdata)
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
name = xmpp_stanza_get_name(stanza);
|
|
||||||
xmpp_debug(conn->ctx, "xmpp", "handle plain called for %s", name);
|
|
||||||
|
|
||||||
/* the server should send a <success> or <failure> stanza */
|
|
||||||
if (strcmp(name, "failure") == 0) {
|
|
||||||
/* TODO: handle errors */
|
|
||||||
|
|
||||||
/* 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 PLAIN auth successful");
|
|
||||||
|
|
||||||
/* reset parser */
|
|
||||||
parser_prepare_reset(conn, _handle_open_sasl);
|
|
||||||
|
|
||||||
/* remove this handler */
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
/* send stream tag */
|
|
||||||
conn_open_stream(conn);
|
|
||||||
} else {
|
|
||||||
/* got unexpected reply */
|
|
||||||
xmpp_error(conn->ctx, "xmpp", "Got unexpected reply to SASL PLAIN "\
|
|
||||||
"authentication.");
|
|
||||||
xmpp_disconnect(conn);
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmpp_stanza_t *_make_starttls(xmpp_conn_t * const conn)
|
static xmpp_stanza_t *_make_starttls(xmpp_conn_t * const conn)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *starttls;
|
xmpp_stanza_t *starttls;
|
||||||
@@ -495,6 +448,16 @@ static void _auth(xmpp_conn_t * const conn)
|
|||||||
{
|
{
|
||||||
xmpp_stanza_t *auth, *authdata, *query, *child, *iq;
|
xmpp_stanza_t *auth, *authdata, *query, *child, *iq;
|
||||||
char *str, *authid;
|
char *str, *authid;
|
||||||
|
int anonjid;
|
||||||
|
|
||||||
|
/* if there is no node in conn->jid, we assume anonymous connect */
|
||||||
|
str = xmpp_jid_node(conn->ctx, conn->jid);
|
||||||
|
if (str == NULL) {
|
||||||
|
anonjid = 1;
|
||||||
|
} else {
|
||||||
|
xmpp_free(conn->ctx, str);
|
||||||
|
anonjid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (conn->tls_support)
|
if (conn->tls_support)
|
||||||
{
|
{
|
||||||
@@ -527,6 +490,26 @@ static void _auth(xmpp_conn_t * const conn)
|
|||||||
|
|
||||||
/* TLS was tried, unset flag */
|
/* TLS was tried, unset flag */
|
||||||
conn->tls_support = 0;
|
conn->tls_support = 0;
|
||||||
|
} else if (anonjid && conn->sasl_support & SASL_MASK_ANONYMOUS) {
|
||||||
|
/* some crap here */
|
||||||
|
auth = _make_sasl_auth(conn, "ANONYMOUS");
|
||||||
|
if (!auth) {
|
||||||
|
disconnect_mem_error(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler_add(conn, _handle_sasl_result, XMPP_NS_SASL,
|
||||||
|
NULL, NULL, "ANONYMOUS");
|
||||||
|
|
||||||
|
xmpp_send(conn, auth);
|
||||||
|
xmpp_stanza_release(auth);
|
||||||
|
|
||||||
|
/* SASL ANONYMOUS was tried, unset flag */
|
||||||
|
conn->sasl_support &= ~SASL_MASK_ANONYMOUS;
|
||||||
|
} else if (anonjid) {
|
||||||
|
xmpp_error(conn->ctx, "auth",
|
||||||
|
"No node in JID, and SASL ANONYMOUS unsupported.");
|
||||||
|
xmpp_disconnect(conn);
|
||||||
} else if (conn->sasl_support & SASL_MASK_DIGESTMD5) {
|
} else if (conn->sasl_support & SASL_MASK_DIGESTMD5) {
|
||||||
auth = _make_sasl_auth(conn, "DIGEST-MD5");
|
auth = _make_sasl_auth(conn, "DIGEST-MD5");
|
||||||
if (!auth) {
|
if (!auth) {
|
||||||
@@ -570,8 +553,8 @@ static void _auth(xmpp_conn_t * const conn)
|
|||||||
xmpp_stanza_add_child(auth, authdata);
|
xmpp_stanza_add_child(auth, authdata);
|
||||||
xmpp_stanza_release(authdata);
|
xmpp_stanza_release(authdata);
|
||||||
|
|
||||||
handler_add(conn, _handle_plain,
|
handler_add(conn, _handle_sasl_result,
|
||||||
XMPP_NS_SASL, NULL, NULL, NULL);
|
XMPP_NS_SASL, NULL, NULL, "PLAIN");
|
||||||
|
|
||||||
xmpp_send(conn, auth);
|
xmpp_send(conn, auth);
|
||||||
xmpp_stanza_release(auth);
|
xmpp_stanza_release(auth);
|
||||||
@@ -996,3 +979,4 @@ static int _handle_missing_legacy(xmpp_conn_t * const conn,
|
|||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user