changeset 23493:c5891c8d0c28

Sometimes (after 24h+) when you request a MSN token update, you get a Collection of Responses, with (presumably) some updated CipherValue and BinarySecret data that should be used for subsequent update requests. References #4875.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sat, 21 Jun 2008 06:15:38 +0000
parents 8fd6a97b9c67
children c1cba867b3da
files libpurple/protocols/msn/nexus.c
diffstat 1 files changed, 31 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/msn/nexus.c	Sat Jun 21 06:11:29 2008 +0000
+++ b/libpurple/protocols/msn/nexus.c	Sat Jun 21 06:15:38 2008 +0000
@@ -267,6 +267,8 @@
 	if (token_str == NULL)
 		return FALSE;
 
+	g_hash_table_remove_all(nexus->tokens[id].token);
+
 	elems = g_strsplit(token_str, "&", 0);
 
 	for (cur = elems; *cur != NULL; cur++) {
@@ -296,30 +298,37 @@
 }
 
 static gboolean
-nexus_parse_response(MsnNexus *nexus, xmlnode *xml)
+nexus_parse_collection(MsnNexus *nexus, int id, xmlnode *collection)
 {
 	xmlnode *node;
-	xmlnode *cipher;
-	xmlnode *secret;
-	char *data;
 	gboolean result;
 
-	node = xmlnode_get_child(xml, "Body/RequestSecurityTokenResponseCollection/RequestSecurityTokenResponse");
+	node = xmlnode_get_child(collection, "RequestSecurityTokenResponse");
 
 	if (!node)
 		return FALSE;
 
-	/* The first node contains the stuff for updating tokens. */
-	cipher = xmlnode_get_child(node, "RequestedSecurityToken/EncryptedData/CipherData/CipherValue");
-	nexus->cipher = xmlnode_get_data(cipher);
-	secret = xmlnode_get_child(node, "RequestedProofToken/BinarySecret");
-	data = xmlnode_get_data(secret);
-	nexus->secret = (char *)purple_base64_decode(data, NULL);
-	g_free(data);
+	result = TRUE;
+	for (; node && result; node = node->next) {
+		xmlnode *endpoint = xmlnode_get_child(node, "AppliesTo/EndpointReference/Address");
+		char *address = xmlnode_get_data(endpoint);
+
+		if (g_str_equal(address, "http://Passport.NET/tb")) {
+			/* This node contains the stuff for updating tokens. */
+			char *data;
+			xmlnode *cipher = xmlnode_get_child(node, "RequestedSecurityToken/EncryptedData/CipherData/CipherValue");
+			xmlnode *secret = xmlnode_get_child(node, "RequestedProofToken/BinarySecret");
 
-	result = TRUE;
-	for (node = node->next; node && result; node = node->next)
-		result = nexus_parse_token(nexus, -1, node);
+			nexus->cipher = xmlnode_get_data(cipher);
+			data = xmlnode_get_data(secret);
+			nexus->secret = (char *)purple_base64_decode(data, NULL);
+			g_free(data);
+
+		} else {
+			result = nexus_parse_token(nexus, id, node);
+		}
+		g_free(address);
+	}
 
 	return result;
 }
@@ -337,7 +346,9 @@
 		return;
 	}
 
-	if (!nexus_parse_response(nexus, resp->xml)) {
+	if (!nexus_parse_collection(nexus, -1,
+	                            xmlnode_get_child(resp->xml,
+	                                              "Body/RequestSecurityTokenResponseCollection"))) {
 		msn_session_set_error(session, MSN_ERROR_SERVCONN, _("Windows Live ID authentication:Invalid response"));
 		return;
 	}
@@ -452,8 +463,10 @@
 		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);
-		nexus_parse_token(nexus, ud->id, rstresponse);
+		if (g_str_equal(rstresponse->name, "RequestSecurityTokenResponse"))
+			nexus_parse_token(nexus, ud->id, rstresponse);
+		else
+			nexus_parse_collection(nexus, ud->id, rstresponse);
 		g_free(decrypted_data);
 	}