libpurple/protocols/msn/nexus.c

branch
cpw.qulogic.msn
changeset 23788
b5ab3fd1c440
parent 23780
fda6e23ac6f6
child 23805
024a2801725c
--- a/libpurple/protocols/msn/nexus.c	Sat Jun 14 07:47:38 2008 +0000
+++ b/libpurple/protocols/msn/nexus.c	Sun Jun 15 06:22:25 2008 +0000
@@ -239,31 +239,70 @@
 	gpointer data;
 };
 
-static void
-save_tokens(GHashTable *table, const char *str)
+static gboolean
+nexus_parse_token(MsnNexus *nexus, int id, xmlnode *node)
 {
+	char *token_str, *expiry_str;
+	const char *id_str;
 	char **elems, **cur, **tokens;
+	xmlnode *token = xmlnode_get_child(node, "RequestedSecurityToken/BinarySecurityToken");
+	xmlnode *secret = xmlnode_get_child(node, "RequestedProofToken/BinarySecret");
+	xmlnode *expires = xmlnode_get_child(node, "LifeTime/Expires");
+
+	if (!token)
+		return FALSE;
 
-	elems = g_strsplit(str, "&", 0);
+	/* Use the ID that the server sent us */
+	if (id == -1) {
+		id_str = xmlnode_get_attrib(token, "Id");
+		if (id_str == NULL)
+			return FALSE;
+
+		id = atol(id_str + 7) - 1;	/* 'Compact#' or 'PPToken#' */
+		if (id >= nexus->token_len)
+			return FALSE;	/* Where did this come from? */
+	}
+
+	token_str = xmlnode_get_data(token);
+	if (token_str == NULL)
+		return FALSE;
+
+	elems = g_strsplit(token_str, "&", 0);
 
 	for (cur = elems; *cur != NULL; cur++) {
 		tokens = g_strsplit(*cur, "=", 2);
-		g_hash_table_insert(table, tokens[0], tokens[1]);
+		g_hash_table_insert(nexus->tokens[id].token, tokens[0], tokens[1]);
 		/* Don't free each of the tokens, only the array. */
 		g_free(tokens);
 	}
 	g_strfreev(elems);
+	g_free(token_str);
+
+	if (secret)
+		nexus->tokens[id].secret = xmlnode_get_data(secret);
+	else
+		nexus->tokens[id].secret = NULL;
+
+	/* Yay for MS using ISO-8601 */
+	expiry_str = xmlnode_get_data(expires);
+	nexus->tokens[id].expiry = purple_str_to_time(expiry_str,
+		FALSE, NULL, NULL, NULL);
+	g_free(expiry_str);
+
+	purple_debug_info("msnp15", "Updated ticket for domain '%s', expires at %" G_GINT64_FORMAT ".\n",
+	                  ticket_domains[id][SSO_VALID_TICKET_DOMAIN],
+	                  (gint64)nexus->tokens[id].expiry);
+	return TRUE;
 }
 
 static gboolean
-nexus_parse_response(MsnNexus *nexus, int id, xmlnode *xml)
+nexus_parse_response(MsnNexus *nexus, xmlnode *xml)
 {
 	xmlnode *node;
 	xmlnode *cipher;
 	xmlnode *secret;
 	char *data;
-	gboolean result = FALSE;
-	gboolean parse_all = (id == -1);
+	gboolean result;
 
 	node = xmlnode_get_child(xml, "Body/RequestSecurityTokenResponseCollection/RequestSecurityTokenResponse");
 
@@ -278,46 +317,9 @@
 	nexus->secret = (char *)purple_base64_decode(data, NULL);
 	g_free(data);
 
-	for (node = node->next; node; node = node->next) {
-		xmlnode *token = xmlnode_get_child(node, "RequestedSecurityToken/BinarySecurityToken");
-		xmlnode *secret = xmlnode_get_child(node, "RequestedProofToken/BinarySecret");
-		xmlnode *expires = xmlnode_get_child(node, "LifeTime/Expires");
-
-		if (token) {
-			char *token_str, *expiry_str;
-			const char *id_str = xmlnode_get_attrib(token, "Id");
-
-			if (id_str == NULL) continue;
-
-			if (parse_all)
-				id = atol(id_str + 7) - 1;	/* 'Compact#' or 'PPToken#' */
-			if (id >= nexus->token_len)
-				continue;	/* Where did this come from? */
-
-			token_str = xmlnode_get_data(token);
-			if (token_str == NULL) continue;
-
-			save_tokens(nexus->tokens[id].token, token_str);
-			g_free(token_str);
-
-			if (secret)
-				nexus->tokens[id].secret = xmlnode_get_data(secret);
-			else
-				nexus->tokens[id].secret = NULL;
-
-			/* Yay for MS using ISO-8601 */
-			expiry_str = xmlnode_get_data(expires);
-
-			nexus->tokens[id].expiry = purple_str_to_time(expiry_str,
-				FALSE, NULL, NULL, NULL);
-
-			g_free(expiry_str);
-
-			purple_debug_info("msnp15", "Updated ticket for domain '%s'\n",
-			                  ticket_domains[id][SSO_VALID_TICKET_DOMAIN]);
-			result = TRUE;
-		}
-	}
+	result = TRUE;
+	for (node = node->next; node && result; node = node->next)
+		result = nexus_parse_token(nexus, -1, node);
 
 	return result;
 }
@@ -335,7 +337,7 @@
 		return;
 	}
 
-	if (!nexus_parse_response(nexus, -1, resp->xml)) {
+	if (!nexus_parse_response(nexus, resp->xml)) {
 		msn_session_set_error(session, MSN_ERROR_SERVCONN, _("Windows Live ID authentication:Invalid response"));
 		return;
 	}
@@ -400,7 +402,9 @@
 	gsize len;
 	char *key;
 
+#if 0
 	char *decrypted_pp;
+#endif
 	char *decrypted_data;
 
 	purple_debug_info("msnp15", "Got Update Response for %s.\n", ticket_domains[ud->id][SSO_VALID_TICKET_DOMAIN]);
@@ -422,31 +426,34 @@
 	g_free(tmp);
 	g_free(nonce);
 
+#if 0
+	/* Don't know what this is for yet */
 	tmp = xmlnode_get_data(xmlnode_get_child(resp->xml,
 		"Header/EncryptedPP/EncryptedData/CipherData/CipherValue"));
 	if (tmp) {
-		/* Don't know what this is for yet */
 		decrypted_pp = des3_cbc(key, iv, tmp, len, TRUE);
 		g_free(tmp);
 		purple_debug_info("msnp15", "Got Response Header EncryptedPP: %s\n", decrypted_pp);
 		g_free(decrypted_pp);
 	}
+#endif
 
 	tmp = xmlnode_get_data(xmlnode_get_child(resp->xml,
 		"Body/EncryptedData/CipherData/CipherValue"));
 	if (tmp) {
 		char *unescaped;
 		xmlnode *rstresponse;
+
 		unescaped = (char *)purple_base64_decode(tmp, &len);
 		g_free(tmp);
+
 		decrypted_data = des3_cbc(key, iv, unescaped, len, TRUE);
 		g_free(unescaped);
+		purple_debug_info("msnp15", "Got Response Body EncryptedData: %s\n", decrypted_data);
+
 		rstresponse = xmlnode_from_str(decrypted_data, -1);
 		g_hash_table_remove_all(nexus->tokens[ud->id].token);
-		save_tokens(nexus->tokens[ud->id].token,
-			xmlnode_get_data(xmlnode_get_child(rstresponse,
-				"RequestSecurityTokenResponse/RequestedSecurityToken/BinarySecurityToken")));
-		purple_debug_info("msnp15", "Got Response Body EncryptedData: %s\n", decrypted_data);
+		nexus_parse_token(nexus, ud->id, rstresponse);
 		g_free(decrypted_data);
 	}
 
@@ -501,7 +508,7 @@
 	sha1 = purple_cipher_context_new_by_name("sha1", NULL);
 
 	domain = g_strdup_printf(MSN_SSO_RST_TEMPLATE,
-	                         0,
+	                         id,
 	                         ticket_domains[id][SSO_VALID_TICKET_DOMAIN],
 	                         ticket_domains[id][SSO_VALID_TICKET_POLICY] != NULL ?
 	                             ticket_domains[id][SSO_VALID_TICKET_POLICY] :
@@ -527,6 +534,7 @@
 	purple_cipher_context_destroy(sha1);
 
 	signedinfo = g_strdup_printf(MSN_SSO_SIGNEDINFO_TEMPLATE,
+	                             id,
 	                             domain_b64,
 	                             timestamp_b64);
 

mercurial