[Projeler-commits] r409 - in iksemel: . src

projeler-commits at pardus.org.tr projeler-commits at pardus.org.tr
1 Ağu 2007 Çar 23:09:47 EEST


Author: gurer
Date: Wed Aug  1 23:09:47 2007
New Revision: 409

Modified:
   iksemel/ChangeLog
   iksemel/src/stream.c
Log:
code cleanup in iks_sasl_challenge


Modified: iksemel/ChangeLog
=================================================================
--- iksemel/ChangeLog	(original)
+++ iksemel/ChangeLog	Wed Aug  1 23:09:47 2007
@@ -4,6 +4,9 @@
 	* sha.c: 64bit fix (long -> int)
 	* iks.c: new funcs: iks_append, iks_prepend
 	  iks_append_cdata, iks_prepend_cdata
+	* stream.c: iks_sasl_challenge split into smaller functions
+	  This change also fixes some possible leaks which are detected
+	  by Coverity Inc's excellent Prevent product.
 
 2006-05-19  Gurer
 	* dom.c: fixed (size % FILE_IO_BUFFER_SIZE) problem in iks_load()

Modified: iksemel/src/stream.c
=================================================================
--- iksemel/src/stream.c	(original)
+++ iksemel/src/stream.c	Wed Aug  1 23:09:47 2007
@@ -122,106 +122,143 @@
 #define CNONCE_LEN 4
 
 static void
-iks_sasl_challenge (struct stream_data *data, iks *challenge)
+parse_digest (char *message, const char *key, char **value_ptr, char **value_end_ptr)
 {
-	char *b;
-	iks *x;
+	char *t;
 
-	b = iks_cdata (iks_child (challenge));
-	if (!b) return;
+	*value_ptr = NULL;
+	*value_end_ptr = NULL;
 
-	b = iks_base64_decode (b);
+	t = strstr(message, key);
+	if (t) {
+		t += strlen(key);
+		*value_ptr = t;
+		while (t[0] != '\0') {
+			if (t[0] != '\\' && t[1] == '"') {
+				++t;
+				*value_end_ptr = t;
+				return;
+			}
+			++t;
+		}
+	}
+}
 
-	if (strstr (b, "rspauth")) {
-		x = iks_new("response");
+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 {
-		char *realm, *nonce, *charset = NULL, *algorithm = NULL;
-		char *realm_end, *nonce_end, cnonce[CNONCE_LEN*8 + 1];
-		unsigned char a1_h[16], a1[33], a2[33], response_value[33];
-		char *response, *response_coded;
-		iksmd5 *md5;
-		int i;
-
-		realm = strstr (b, "realm");
-		if (realm) {
-			realm += 7;
-			do {
-				realm_end = strchr(realm, '"');
-			} while (*(realm_end - 1) == '\\');
-		} else {
-			realm_end = 0;
-			realm = (char *) data->server;
-		}
-		nonce = strstr (b, "nonce");
-		if (nonce) {
-			nonce += 7;
-			do {
-				nonce_end = strchr (nonce, '"');
-			} while (*(nonce - 1) == '\\');
-		} else {
-			iks_free (b);
-			return;
-		}
-		charset = strstr (b, "charset");
-		if (charset) charset += 8;
-		algorithm = strstr (b, "algorithm");
-		if (algorithm) algorithm += 10;
-		if (realm_end) *realm_end = 0;
-		*nonce_end = 0;
-
-		for (i = 0; i < CNONCE_LEN; ++i)
-			sprintf (cnonce + i*8, "%08x", rand());
-
-		md5 = iks_md5_new();
-		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);
-		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);
+		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);
 		iks_free (response_coded);
 	}
-	iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL);
-	iks_send (data->prs, x);
-	iks_delete (x);
-	iks_free (b);
+	iks_free (response);
+
+	return x;
+}
+
+static void
+iks_sasl_challenge (struct stream_data *data, iks *challenge)
+{
+	char *message;
+	iks *x;
+	char *tmp;
+
+	tmp = iks_cdata (iks_child (challenge));
+	if (!tmp) return;
+
+	/* decode received blob */
+	message = iks_base64_decode (tmp);
+	if (!message) return;
+
+	/* reply the challenge */
+	if (strstr (message, "rspauth")) {
+		x = iks_new ("response");
+	} else {
+		x = make_sasl_response (data, message);
+	}
+	if (x) {
+		iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL);
+		iks_send (data->prs, x);
+		iks_delete (x);
+	}
+	iks_free (message);
 }
 
 static int


Projeler-commits mesaj listesiyle ilgili daha fazla bilgi