Ejemplo n.º 1
0
/* split key, value pairs into a hash */
static hash_t *_parse_digest_challenge(xmpp_ctx_t *ctx, const char *msg)
{
    hash_t *result;
    unsigned char *text;
    char *key, *value;
    unsigned char *s, *t;

    text = (unsigned char *)xmpp_base64_decode_str(ctx, msg, strlen(msg));
    if (text == NULL) {
	xmpp_error(ctx, "SASL", "couldn't Base64 decode challenge!");
	return NULL;
    }

    result = hash_new(ctx, 10, xmpp_free);
    if (result != NULL) {
	s = text;
	while (*s != '\0') {
	    /* skip any leading commas and spaces */
	    while ((*s == ',') || (*s == ' ')) s++;
	    /* accumulate a key ending at '=' */
	    t = s;
	    while ((*t != '=') && (*t != '\0')) t++;
	    if (*t == '\0') break; /* bad string */
	    key = _make_string(ctx, (char *)s, (t-s));
	    if (key == NULL) break;
            /* advance our start pointer past the key */
	    s = t + 1;
	    t = s;
	    /* if we see quotes, grab the string in between */
	    if ((*s == '\'') || (*s == '"')) {
		t++;
		while ((*t != *s) && (*t != '\0'))
		    t++;
		value = _make_string(ctx, (char *)s+1, (t-s-1));
		if (*t == *s) {
		    s = t + 1;
		} else {
		    s = t;
		}
	    /* otherwise, accumulate a value ending in ',' or '\0' */
	    } else {
		while ((*t != ',') && (*t != '\0')) t++;
		value = _make_string(ctx, (char *)s, (t-s));
		s = t;
	    }
	    if (value == NULL) {
		xmpp_free(ctx, key);
		break;
	    }
	    /* TODO: check for collisions per spec */
	    hash_add(result, key, value);
	    /* hash table now owns the value, free the key */
	    xmpp_free(ctx, key);
	}
    }
    xmpp_free(ctx, text);

    return result;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
    xmpp_ctx_t *ctx;
    unsigned char *udec;
    char *dec;
    char *enc;
    size_t len;
    int i;

    printf("BASE64 tests.\n");

    ctx = xmpp_ctx_new(NULL, NULL);
    if (ctx == NULL) {
        fprintf(stderr, "failed to create context\n");
        return 1;
    }

    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
        printf("Test #%d: ", (int)i + 1);
        enc = xmpp_base64_encode(ctx, (unsigned char *)tests[i].raw,
                                 strlen(tests[i].raw));
        assert(enc != NULL);
        COMPARE(tests[i].base64, enc);
        xmpp_free(ctx, enc);

        dec = xmpp_base64_decode_str(ctx, tests[i].base64,
                                     strlen(tests[i].base64));
        assert(dec != NULL);
        COMPARE_BUF(tests[i].raw, strlen(tests[i].raw), dec, strlen(dec));
        xmpp_free(ctx, dec);
        printf("ok\n");
    }

    printf("Test with binary data: ");
    enc = xmpp_base64_encode(ctx, bin_data, sizeof(bin_data));
    assert(enc != NULL);
    xmpp_base64_decode_bin(ctx, enc, strlen(enc), &udec, &len);
    assert(udec != NULL);
    assert(len != 0);
    assert(len == sizeof(bin_data));
    COMPARE_BUF(bin_data, sizeof(bin_data), udec, len);
    xmpp_free(ctx, udec);
    xmpp_free(ctx, enc);
    printf("ok\n");

    xmpp_ctx_free(ctx);

    return 0;
}
Ejemplo n.º 3
0
/* 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,
					void * const userdata)
{
    char *text;
    char *response;
    xmpp_stanza_t *auth, *authdata;
    const char *name;
    char *challenge;
    char *scram_init = (char *)userdata;

    name = xmpp_stanza_get_name(stanza);
    xmpp_debug(conn->ctx, "xmpp",
               "handle SCRAM-SHA-1 (challenge) called for %s", name);

    if (strcmp(name, "challenge") == 0) {
        text = xmpp_stanza_get_text(stanza);
        if (!text)
            goto err;

        challenge = xmpp_base64_decode_str(conn->ctx, text, strlen(text));
        xmpp_free(conn->ctx, text);
        if (!challenge)
            goto err;

        response = sasl_scram_sha1(conn->ctx, challenge, scram_init,
                                   conn->jid, conn->pass);
        xmpp_free(conn->ctx, challenge);
        if (!response)
            goto err;

        auth = xmpp_stanza_new(conn->ctx);
        if (!auth)
            goto err_free_response;
        xmpp_stanza_set_name(auth, "response");
        xmpp_stanza_set_ns(auth, XMPP_NS_SASL);

        authdata = xmpp_stanza_new(conn->ctx);
        if (!authdata)
            goto err_release_auth;
        xmpp_stanza_set_text(authdata, response);
        xmpp_free(conn->ctx, response);

        xmpp_stanza_add_child(auth, authdata);
        xmpp_stanza_release(authdata);

        xmpp_send(conn, auth);
        xmpp_stanza_release(auth);

    } else {
        xmpp_free(conn->ctx, scram_init);
        return _handle_sasl_result(conn, stanza, "SCRAM-SHA-1");
    }

    return 1;

err_release_auth:
    xmpp_stanza_release(auth);
err_free_response:
    xmpp_free(conn->ctx, response);
err:
    xmpp_free(conn->ctx, scram_init);
    disconnect_mem_error(conn);
    return 0;
}