Esempio n. 1
0
void iks_md5(const char *data, char *buf)
{
	iksmd5 *md5 = iks_md5_new();

	iks_md5_hash(md5, (const unsigned char*)data, strlen(data), 1);
	iks_md5_print(md5, buf);
	iks_md5_delete(md5);
}
Esempio n. 2
0
static iks *make_sasl_response(struct stream_data *data, char *message)
{
	iks *x = NULL;
	char *realm, *realm_end;
	char *nonce, *nonce_end;
	char cnonce[CNONCE_LEN * 8 + 1];
	iksmd5 *md5;
	unsigned char a1_h[16], a1[33], a2[33], response_value[33];
	char *response, *response_coded;
	int i;

	parse_digest(message, "realm=\"", &realm, &realm_end);
	parse_digest(message, "nonce=\"", &nonce, &nonce_end);

	/* nonce is necessary for auth */
	if(!nonce || !nonce_end) return NULL;
	*nonce_end = '\0';

	/* if no realm is given use the server hostname */
	if(realm)
	{
		if(!realm_end) return NULL;
		*realm_end = '\0';
	}
	else
	{
		realm = (char *) data->server;
	}

	/* generate random client challenge */
	for(i = 0; i < CNONCE_LEN; ++i)
		sprintf(cnonce + i * 8, "%08x", rand());

	md5 = iks_md5_new();
	if(!md5) return NULL;

	iks_md5_hash(md5, (const unsigned char*)data->auth_username, iks_strlen(data->auth_username), 0);
	iks_md5_hash(md5, (const unsigned char*)":", 1, 0);
	iks_md5_hash(md5, (const unsigned char*)realm, iks_strlen(realm), 0);
	iks_md5_hash(md5, (const unsigned char*)":", 1, 0);
	iks_md5_hash(md5, (const unsigned char*)data->auth_pass, iks_strlen(data->auth_pass), 1);
	iks_md5_digest(md5, a1_h);

	iks_md5_reset(md5);
	iks_md5_hash(md5, (const unsigned char*)a1_h, 16, 0);
	iks_md5_hash(md5, (const unsigned char*)":", 1, 0);
	iks_md5_hash(md5, (const unsigned char*)nonce, iks_strlen(nonce), 0);
	iks_md5_hash(md5, (const unsigned char*)":", 1, 0);
	iks_md5_hash(md5, (const unsigned char*)cnonce, iks_strlen(cnonce), 1);
	iks_md5_print(md5, (char*)a1);

	iks_md5_reset(md5);
	iks_md5_hash(md5, (const unsigned char*)"AUTHENTICATE:xmpp/", 18, 0);
	iks_md5_hash(md5, (const unsigned char*)data->server, iks_strlen(data->server), 1);
	iks_md5_print(md5, (char*)a2);

	iks_md5_reset(md5);
	iks_md5_hash(md5, (const unsigned char*)a1, 32, 0);
	iks_md5_hash(md5, (const unsigned char*)":", 1, 0);
	iks_md5_hash(md5, (const unsigned char*)nonce, iks_strlen(nonce), 0);
	iks_md5_hash(md5, (const unsigned char*)":00000001:", 10, 0);
	iks_md5_hash(md5, (const unsigned char*)cnonce, iks_strlen(cnonce), 0);
	iks_md5_hash(md5, (const unsigned char*)":auth:", 6, 0);
	iks_md5_hash(md5, (const unsigned char*)a2, 32, 1);
	iks_md5_print(md5, (char*)response_value);

	iks_md5_delete(md5);

	i = iks_strlen(data->auth_username) + iks_strlen(realm) +
	    iks_strlen(nonce) + iks_strlen(data->server) +
	    CNONCE_LEN * 8 + 136;
	response = iks_malloc(i);
	if(!response) return NULL;

	sprintf(response, "username=\"%s\",realm=\"%s\",nonce=\"%s\""
	        ",cnonce=\"%s\",nc=00000001,qop=auth,digest-uri=\""
	        "xmpp/%s\",response=%s,charset=utf-8",
	        data->auth_username, realm, nonce, cnonce,
	        data->server, response_value);

	response_coded = iks_base64_encode(response, 0);
	if(response_coded)
	{
		x = iks_new("response");
		iks_insert_cdata(x, response_coded, 0);
		iks_free(response_coded);
	}
	iks_free(response);

	return x;
}