changeset 20530:719ce4acfcb9

the new soap code finally doesn't crash on startup, still can't authenticate though
author Ka-Hing Cheung <khc@hxbc.us>
date Fri, 28 Sep 2007 05:51:49 +0000
parents 1180920ffcec
children a96b5015395a
files libpurple/protocols/msn/nexus.c libpurple/protocols/msn/session.c libpurple/protocols/msn/soap2.c libpurple/protocols/msn/soap2.h
diffstat 4 files changed, 120 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/msn/nexus.c	Mon Sep 24 06:04:54 2007 +0000
+++ b/libpurple/protocols/msn/nexus.c	Fri Sep 28 05:51:49 2007 +0000
@@ -22,7 +22,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 #include "msn.h"
-#include "soap.h"
+#include "soap2.h"
 #include "nexus.h"
 #include "notification.h"
 
@@ -43,7 +43,7 @@
 	nexus = g_new0(MsnNexus, 1);
 	nexus->session = session;
 	/*we must use SSL connection to do Windows Live ID authentication*/
-	nexus->soapconn = msn_soap_new(session,nexus,1);
+	//nexus->soapconn = msn_soap_new(session,nexus,1);
 
 	nexus->challenge_data = g_hash_table_new_full(g_str_hash,
 		g_str_equal, g_free, g_free);
@@ -57,7 +57,7 @@
 	if (nexus->challenge_data != NULL)
 		g_hash_table_destroy(nexus->challenge_data);
 
-	msn_soap_destroy(nexus->soapconn);
+	//msn_soap_destroy(nexus->soapconn);
 	g_free(nexus);
 }
 
@@ -140,6 +140,66 @@
 	 * to destroy it here, or we'd crash */
 }
 
+static void
+nexus_got_response_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
+{
+	MsnNexus *nexus = data;
+	MsnSession *session = nexus->session;
+	xmlnode *node;
+
+	if (resp == NULL) {
+		msn_session_set_error(session, MSN_ERROR_AUTH, _("Windows Live ID authentication:Unable to connect"));
+		return;
+	}
+
+	node = msn_soap_xml_get(resp->xml,	"Body/"
+		"RequestSecurityTokenResponseCollection/RequestSecurityTokenResponse");
+
+	for (; node; node = node->next) {
+		xmlnode *token = msn_soap_xml_get(node,
+			"RequestedSecurityToken/BinarySecurityToken");
+
+		if (token) {
+			char **elems, **cur, **tokens;
+			char *msn_twn_t, *msn_twn_p, *cert_str;
+
+			elems = g_strsplit(token->data, "&amp;", 0);
+
+			for (cur = elems; *cur != NULL; cur++){
+				tokens = g_strsplit(*cur, "=", 2);
+				g_hash_table_insert(nexus->challenge_data, tokens[0], tokens[1]);
+				/* Don't free each of the tokens, only the array. */
+				g_free(tokens);
+			}
+
+			g_strfreev(elems);
+
+			msn_twn_t = g_hash_table_lookup(nexus->challenge_data, "t");
+			msn_twn_p = g_hash_table_lookup(nexus->challenge_data, "p");
+
+			/*setup the t and p parameter for session*/
+			if (session->passport_info.t != NULL){
+				g_free(session->passport_info.t);
+			}
+			session->passport_info.t = g_strdup(msn_twn_t);
+
+			if (session->passport_info.p != NULL)
+				g_free(session->passport_info.p);
+			session->passport_info.p = g_strdup(msn_twn_p);
+
+			cert_str = g_strdup_printf("t=%s&p=%s",msn_twn_t,msn_twn_p);
+			msn_got_login_params(session, cert_str);
+
+			purple_debug_info("MSN Nexus","Close nexus connection!\n");
+			g_free(cert_str);
+			msn_nexus_destroy(nexus);
+			session->nexus = NULL;
+
+			return;
+		}
+	}
+}
+#if 0
 /*process the SOAP reply, get the Authentication Info*/
 static void
 nexus_login_read_cb(gpointer data, gint source, PurpleInputCondition cond)
@@ -221,16 +281,16 @@
 	soapconn->read_cb = nexus_login_read_cb;
 //	msn_soap_read_cb(data,source,cond);
 }
-
+#endif
 
 /*when connect, do the SOAP Style windows Live ID authentication */
 void
 nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc,
 				 PurpleInputCondition cond)
 {
-	MsnSoapConn *soapconn;
-	MsnNexus * nexus;
-	MsnSession *session;
+	//MsnSoapConn *soapconn;
+	MsnNexus *nexus = data;
+	MsnSession *session = nexus->session;
 	char *ru,*lc,*id,*tw,*ct,*kpp,*kv,*ver,*rn,*tpf;
 	char *fs0,*fs;
 	char *username, *password;
@@ -241,8 +301,10 @@
 	char *rst1_str,*rst2_str,*rst3_str;
 #endif
 
+	MsnSoapMessage *soap;
+
 	purple_debug_info("MSN Nexus","Starting Windows Live ID authentication\n");
-
+/*
 	soapconn = data;
 	g_return_if_fail(soapconn != NULL);
 
@@ -251,6 +313,7 @@
 
 	session = soapconn->session;
 	g_return_if_fail(session != NULL);
+*/
 
 	msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE);
 
@@ -322,6 +385,11 @@
 #endif
 	g_free(fs);
 
+	soap = msn_soap_message_new(NULL, xmlnode_from_str(tail, -1));
+	msn_soap_message_send(nexus->session, soap, MSN_TWN_SERVER, TWN_POST_URL,
+		nexus_got_response_cb, nexus);
+
+#if 0
 	soapconn->login_path = g_strdup(TWN_POST_URL);
 	head = g_strdup_printf(
 					"POST %s HTTP/1.1\r\n"
@@ -345,7 +413,7 @@
 
 	/*prepare to send the SOAP request*/
 	msn_soap_write(soapconn,request_str,nexus_login_written_cb);
-
+#endif
 	return;
 }
 
@@ -467,8 +535,11 @@
 void
 msn_nexus_connect(MsnNexus *nexus)
 {
+#if 0
 	/*  Authenticate via Windows Live ID. */
 	purple_debug_info("MSN Nexus","msn_nexus_connect()\n");
 	msn_soap_init(nexus->soapconn,MSN_TWN_SERVER,1,nexus_login_connect_cb,nexus_login_error_cb);
 	msn_soap_connect(nexus->soapconn);
+#endif
+	nexus_login_connect_cb(nexus, NULL, 0);
 }
--- a/libpurple/protocols/msn/session.c	Mon Sep 24 06:04:54 2007 +0000
+++ b/libpurple/protocols/msn/session.c	Fri Sep 28 05:51:49 2007 +0000
@@ -142,11 +142,6 @@
 
 	if (session->notification != NULL)
 		msn_notification_close(session->notification);
-
-	if (session->soap_table) {
-		g_hash_table_destroy(session->soap_table);
-		session->soap_table = NULL;
-	}
 }
 
 /* TODO: This must go away when conversation is redesigned */
--- a/libpurple/protocols/msn/soap2.c	Mon Sep 24 06:04:54 2007 +0000
+++ b/libpurple/protocols/msn/soap2.c	Fri Sep 28 05:51:49 2007 +0000
@@ -170,6 +170,7 @@
 
 		if (strcmp(body->name, "Fault")) {
 			xmlnode *fault = xmlnode_get_child(body, "faultcode");
+			MsnSoapRequest *request;
 
 			if (fault != NULL) {
 				if (strcmp(fault->data, "psf:Redirect") == 0) {
@@ -190,10 +191,11 @@
 				}
 			}
 
-			conn->current_request->cb(conn->current_request->message, response,
-				conn->current_request->cb_data);
-			msn_soap_request_destroy(conn->current_request);
+			request = conn->current_request;
 			conn->current_request = NULL;
+			conn->current_request->cb(request->message, response,
+				request->cb_data);
+			msn_soap_request_destroy(request);
 		}
 	}
 
@@ -216,9 +218,9 @@
 	if (count < 0 && errno == EAGAIN)
 		return;
 	else if (count <= 0) {
-		msn_soap_connection_handle_next(conn);
 		purple_ssl_close(conn->ssl);
 		conn->ssl = NULL;
+		msn_soap_connection_handle_next(conn);
 		return;
 	}
 
@@ -287,11 +289,7 @@
 			if ((conn->response_code == 301 || conn->response_code == 300)
 				&& strcmp(key, "Location") == 0) {
 
-				if (!msn_soap_handle_redirect(conn, value) &&
-					conn->current_request->cb) {
-					conn->current_request->cb(conn->current_request->message,
-						NULL, conn->current_request->cb_data);
-				}
+				msn_soap_handle_redirect(conn, value);
 
 				handled = TRUE;
 				break;
@@ -448,18 +446,21 @@
 static void
 msn_soap_connection_handle_next(MsnSoapConnection *conn)
 {
-	if (conn->current_request) {
-		msn_soap_connection_destroy_foreach_cb(conn->current_request, conn);
-		conn->current_request = NULL;
-	}
-
 	purple_input_remove(conn->event_handle);
 	conn->event_handle = 0;
 
 	msn_soap_message_destroy(conn->message);
+	conn->message = NULL;
 	g_string_free(conn->buf, TRUE);
+	conn->buf = NULL;
 
 	conn->event_handle = purple_timeout_add(0, msn_soap_connection_run,	conn);
+
+	if (conn->current_request) {
+		MsnSoapRequest *req = conn->current_request;
+		conn->current_request = NULL;
+		msn_soap_connection_destroy_foreach_cb(req, conn);
+	}
 }
 
 static void
@@ -477,8 +478,9 @@
 msn_soap_connection_destroy(MsnSoapConnection *conn)
 {
 	if (conn->current_request) {
-		msn_soap_connection_destroy_foreach_cb(conn->current_request, conn);
+		MsnSoapRequest *req = conn->current_request;
 		conn->current_request = NULL;
+		msn_soap_connection_destroy_foreach_cb(req, conn);
 	}
 
 	g_queue_foreach(conn->queue, msn_soap_connection_destroy_foreach_cb, conn);
@@ -516,7 +518,8 @@
 		g_slist_foreach(message->headers, (GFunc)g_free, NULL);
 		g_slist_free(message->headers);
 		g_free(message->action);
-		xmlnode_free(message->xml);
+		if (message->xml)
+			xmlnode_free(message->xml);
 		g_free(message);
 	}
 }
@@ -537,3 +540,22 @@
 	msn_soap_message_destroy(req->message);
 	g_free(req);
 }
+
+xmlnode *
+msn_soap_xml_get(xmlnode *parent, const char *node)
+{
+	xmlnode *ret;
+	char **tokens = g_strsplit(node, "/", -1);
+	int i;
+
+	for (i = 0; tokens[i]; i++) {
+		if ((ret = xmlnode_get_child(parent, tokens[i])) != NULL)
+			parent = ret;
+		else
+			break;
+	}
+
+	g_strfreev(tokens);
+	return ret;
+}
+
--- a/libpurple/protocols/msn/soap2.h	Mon Sep 24 06:04:54 2007 +0000
+++ b/libpurple/protocols/msn/soap2.h	Fri Sep 28 05:51:49 2007 +0000
@@ -53,4 +53,6 @@
 
 void msn_soap_message_destroy(MsnSoapMessage *message);
 
+xmlnode *msn_soap_xml_get(xmlnode *parent, const char *node);
+
 #endif