re-factor SCRAM to be independent of the hash
This commit is contained in:
committed by
Dmitry Podgorny
parent
2ca2fcfedd
commit
fc064bc883
60
src/auth.c
60
src/auth.c
@@ -85,7 +85,7 @@ static int _handle_digestmd5_rspauth(xmpp_conn_t *const conn,
|
||||
static int _handle_scram_sha1_challenge(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata);
|
||||
static char *_make_scram_sha1_init_msg(xmpp_conn_t *const conn);
|
||||
static char *_make_scram_init_msg(xmpp_conn_t *const conn);
|
||||
|
||||
static int _handle_missing_features_sasl(xmpp_conn_t *const conn,
|
||||
void *const userdata);
|
||||
@@ -430,6 +430,11 @@ static int _handle_digestmd5_rspauth(xmpp_conn_t *const conn,
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct scram_user_data {
|
||||
char *scram_init;
|
||||
const struct hash_alg *alg;
|
||||
};
|
||||
|
||||
/* handle the challenge phase of SCRAM-SHA-1 auth */
|
||||
static int _handle_scram_sha1_challenge(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
@@ -437,14 +442,16 @@ static int _handle_scram_sha1_challenge(xmpp_conn_t *const conn,
|
||||
{
|
||||
char *text;
|
||||
char *response;
|
||||
xmpp_stanza_t *auth, *authdata;
|
||||
xmpp_stanza_t *auth;
|
||||
xmpp_stanza_t *authdata;
|
||||
const char *name;
|
||||
const char *scram_name;
|
||||
char *challenge;
|
||||
char *scram_init = (char *)userdata;
|
||||
struct scram_user_data *scram_ctx = (struct scram_user_data *)userdata;
|
||||
|
||||
name = xmpp_stanza_get_name(stanza);
|
||||
xmpp_debug(conn->ctx, "xmpp",
|
||||
"handle SCRAM-SHA-1 (challenge) called for %s", name);
|
||||
xmpp_debug(conn->ctx, "xmpp", "handle %s (challenge) called for %s",
|
||||
scram_ctx->alg->scram_name, name);
|
||||
|
||||
if (strcmp(name, "challenge") == 0) {
|
||||
text = xmpp_stanza_get_text(stanza);
|
||||
@@ -456,8 +463,8 @@ static int _handle_scram_sha1_challenge(xmpp_conn_t *const conn,
|
||||
if (!challenge)
|
||||
goto err;
|
||||
|
||||
response = sasl_scram_sha1(conn->ctx, challenge, scram_init, conn->jid,
|
||||
conn->pass);
|
||||
response = sasl_scram(conn->ctx, scram_ctx->alg, challenge,
|
||||
scram_ctx->scram_init, conn->jid, conn->pass);
|
||||
xmpp_free(conn->ctx, challenge);
|
||||
if (!response)
|
||||
goto err;
|
||||
@@ -481,8 +488,10 @@ static int _handle_scram_sha1_challenge(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_release(auth);
|
||||
|
||||
} else {
|
||||
xmpp_free(conn->ctx, scram_init);
|
||||
return _handle_sasl_result(conn, stanza, "SCRAM-SHA-1");
|
||||
scram_name = scram_ctx->alg->scram_name;
|
||||
xmpp_free(conn->ctx, scram_ctx->scram_init);
|
||||
xmpp_free(conn->ctx, scram_ctx);
|
||||
return _handle_sasl_result(conn, stanza, (void *)scram_name);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -492,12 +501,13 @@ err_release_auth:
|
||||
err_free_response:
|
||||
xmpp_free(conn->ctx, response);
|
||||
err:
|
||||
xmpp_free(conn->ctx, scram_init);
|
||||
xmpp_free(conn->ctx, scram_ctx->scram_init);
|
||||
xmpp_free(conn->ctx, scram_ctx);
|
||||
disconnect_mem_error(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *_make_scram_sha1_init_msg(xmpp_conn_t *const conn)
|
||||
static char *_make_scram_init_msg(xmpp_conn_t *const conn)
|
||||
{
|
||||
xmpp_ctx_t *ctx = conn->ctx;
|
||||
size_t message_len;
|
||||
@@ -559,8 +569,8 @@ static void _auth(xmpp_conn_t *const conn)
|
||||
{
|
||||
xmpp_stanza_t *auth;
|
||||
xmpp_stanza_t *authdata;
|
||||
struct scram_user_data *scram_ctx;
|
||||
char *authid;
|
||||
char *scram_init;
|
||||
char *str;
|
||||
int anonjid;
|
||||
|
||||
@@ -632,25 +642,30 @@ static void _auth(xmpp_conn_t *const conn)
|
||||
xmpp_error(conn->ctx, "auth",
|
||||
"No node in JID, and SASL ANONYMOUS unsupported.");
|
||||
xmpp_disconnect(conn);
|
||||
} else if (conn->sasl_support & SASL_MASK_SCRAMSHA1) {
|
||||
auth = _make_sasl_auth(conn, "SCRAM-SHA-1");
|
||||
} else if (conn->sasl_support & SASL_MASK_SCRAM) {
|
||||
scram_ctx = xmpp_alloc(conn->ctx, sizeof(*scram_ctx));
|
||||
scram_ctx->alg = &scram_sha1;
|
||||
auth = _make_sasl_auth(conn, scram_ctx->alg->scram_name);
|
||||
if (!auth) {
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* don't free scram_init on success */
|
||||
scram_init = _make_scram_sha1_init_msg(conn);
|
||||
if (!scram_init) {
|
||||
scram_ctx->scram_init = _make_scram_init_msg(conn);
|
||||
if (!scram_ctx->scram_init) {
|
||||
xmpp_free(conn->ctx, scram_ctx);
|
||||
xmpp_stanza_release(auth);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
str = xmpp_base64_encode(conn->ctx, (unsigned char *)scram_init,
|
||||
strlen(scram_init));
|
||||
str = xmpp_base64_encode(conn->ctx,
|
||||
(unsigned char *)scram_ctx->scram_init,
|
||||
strlen(scram_ctx->scram_init));
|
||||
if (!str) {
|
||||
xmpp_free(conn->ctx, scram_init);
|
||||
xmpp_free(conn->ctx, scram_ctx->scram_init);
|
||||
xmpp_free(conn->ctx, scram_ctx);
|
||||
xmpp_stanza_release(auth);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
@@ -659,7 +674,8 @@ static void _auth(xmpp_conn_t *const conn)
|
||||
authdata = xmpp_stanza_new(conn->ctx);
|
||||
if (!authdata) {
|
||||
xmpp_free(conn->ctx, str);
|
||||
xmpp_free(conn->ctx, scram_init);
|
||||
xmpp_free(conn->ctx, scram_ctx->scram_init);
|
||||
xmpp_free(conn->ctx, scram_ctx);
|
||||
xmpp_stanza_release(auth);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
@@ -670,13 +686,13 @@ static void _auth(xmpp_conn_t *const conn)
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
handler_add(conn, _handle_scram_sha1_challenge, XMPP_NS_SASL, NULL,
|
||||
NULL, (void *)scram_init);
|
||||
NULL, (void *)scram_ctx);
|
||||
|
||||
xmpp_send(conn, auth);
|
||||
xmpp_stanza_release(auth);
|
||||
|
||||
/* SASL SCRAM-SHA-1 was tried, unset flag */
|
||||
conn->sasl_support &= ~SASL_MASK_SCRAMSHA1;
|
||||
conn->sasl_support &= ~scram_ctx->alg->mask;
|
||||
} else if (conn->sasl_support & SASL_MASK_DIGESTMD5) {
|
||||
auth = _make_sasl_auth(conn, "DIGEST-MD5");
|
||||
if (!auth) {
|
||||
|
||||
Reference in New Issue
Block a user