src/protocols/msn/nexus.c

branch
soc.2006.msnp13
changeset 13853
cccd9dd599eb
parent 13201
8c224ef70efa
child 13854
ab947cf0c2bb
--- a/src/protocols/msn/nexus.c	Thu Jun 22 08:33:54 2006 +0000
+++ b/src/protocols/msn/nexus.c	Sat Jun 24 12:04:32 2006 +0000
@@ -68,19 +68,25 @@
 msn_ssl_read(MsnNexus *nexus)
 {
 	gssize len;
+	gssize total_len = 0;
 	char temp_buf[4096];
 
-	if ((len = gaim_ssl_read(nexus->gsc, temp_buf,
+	if((len = gaim_ssl_read(nexus->gsc, temp_buf,
 			sizeof(temp_buf))) > 0)
 	{
+#if 0
+		g_string_append(nexus->read_buf,temp_buf);
+#else
+		total_len += len;
 		nexus->read_buf = g_realloc(nexus->read_buf,
 			nexus->read_len + len + 1);
 		strncpy(nexus->read_buf + nexus->read_len, temp_buf, len);
 		nexus->read_len += len;
 		nexus->read_buf[nexus->read_len] = '\0';
+#endif
 	}
-
-	return len;
+//	gaim_debug_info("MaYuan","nexus ssl read:{%s}\n",nexus->read_buf);
+	return total_len;
 }
 
 static void
@@ -91,6 +97,10 @@
 
 	total_len = strlen(nexus->write_buf);
 
+	/* 
+	 * write the content to SSL server,
+	 * We use SOAP to request Windows Live ID authentication
+	 */
 	len = gaim_ssl_write(nexus->gsc,
 		nexus->write_buf + nexus->written_len,
 		total_len - nexus->written_len);
@@ -157,12 +167,11 @@
 		nexus->input_handler = gaim_input_add(nexus->gsc->fd,
 			GAIM_INPUT_READ, nexus_login_written_cb, nexus);
 
-
+	/*read the request header*/
 	len = msn_ssl_read(nexus);
-
-	if (len < 0 && errno == EAGAIN)
+	if (len < 0 && errno == EAGAIN){
 		return;
-	else if (len < 0) {
+	}else if (len < 0) {
 		gaim_input_remove(nexus->input_handler);
 		nexus->input_handler = -1;
 		g_free(nexus->read_buf);
@@ -172,20 +181,22 @@
 		return;
 	}
 
+	if(nexus->read_buf == NULL){
+		return;
+	}
 	if (g_strstr_len(nexus->read_buf, nexus->read_len,
-			"\r\n\r\n") == NULL)
+			"</S:Envelope>") == NULL){
 		return;
+	}
 
 	gaim_input_remove(nexus->input_handler);
 	nexus->input_handler = -1;
-
 	gaim_ssl_close(nexus->gsc);
 	nexus->gsc = NULL;
 
-	gaim_debug_misc("msn", "ssl buffer: {%s}", nexus->read_buf);
+//	gaim_debug_misc("msn", "TWN Server Reply: {%s}", nexus->read_buf);
 
-	if (strstr(nexus->read_buf, "HTTP/1.1 302") != NULL)
-	{
+	if (strstr(nexus->read_buf, "HTTP/1.1 302") != NULL){
 		/* Redirect. */
 		char *location, *c;
 
@@ -221,15 +232,11 @@
 		gaim_ssl_connect(session->account, nexus->login_host,
 			GAIM_SSL_DEFAULT_PORT, login_connect_cb,
 			login_error_cb, nexus);
-	}
-	else if (strstr(nexus->read_buf, "HTTP/1.1 401 Unauthorized") != NULL)
-	{
+	}else if (strstr(nexus->read_buf, "HTTP/1.1 401 Unauthorized") != NULL){
 		const char *error;
 
-		if ((error = strstr(nexus->read_buf, "WWW-Authenticate")) != NULL)
-		{
-			if ((error = strstr(error, "cbtxt=")) != NULL)
-			{
+		if ((error = strstr(nexus->read_buf, "WWW-Authenticate")) != NULL)	{
+			if ((error = strstr(error, "cbtxt=")) != NULL){
 				const char *c;
 				char *temp;
 
@@ -243,45 +250,60 @@
 				g_free(temp);
 			}
 		}
-
 		msn_session_set_error(session, MSN_ERROR_AUTH, error);
-	}
-	else if (strstr(nexus->read_buf, "HTTP/1.1 200 OK"))
-	{
+	}else if (strstr(nexus->read_buf, "HTTP/1.1 200 OK")){
+		/*reply OK, we should process the SOAP body*/
 		char *base, *c;
 		char *login_params;
-
-#if 0
-		/* All your base are belong to us. */
-		base = buffer;
+		char *length_start,*length_end,*body_len;
 
-		/* For great cookie! */
-		while ((base = strstr(base, "Set-Cookie: ")) != NULL)
-		{
-			base += strlen("Set-Cookie: ");
-
-			c = strchr(base, ';');
+		char **elems, **cur, **tokens;
+		const char * cert_str;
 
-			session->login_cookies =
-				g_list_append(session->login_cookies,
-							  g_strndup(base, c - base));
-		}
-#endif
+		gaim_debug_info("MaYuan","Receive 200\n");
+#if 0
+		length_start = strstr(nexus->read_buf, "Content-Length: ");
+		length_start += strlen("Content-Length: ");
+		length_end = strstr(length_start, "\r\n");
+		body_len = g_strndup(length_start,length_end - length_start);
+//		gaim_debug_info("MaYuan","body length is :%s\n",body_len);
 
-		base  = strstr(nexus->read_buf, "Authentication-Info: ");
-
-		g_return_if_fail(base != NULL);
-
-		base  = strstr(base, "from-PP='");
-		base += strlen("from-PP='");
-		c     = strchr(base, '\'');
-
+		g_free(body_len);
+//		g_return_if_fail(body_len != NULL);
+#endif
+		//TODO: we should parse it using XML
+		base  = strstr(base, TWN_START_TOKEN);
+		base += strlen(TWN_START_TOKEN);
+//		gaim_debug_info("MaYuan","base is :%s\n",base);
+		c     = strstr(base, TWN_END_TOKEN);
+//		gaim_debug_info("MaYuan","c is :%s\n",c);
+//		gaim_debug_info("MaYuan","len is :%d\n",c-base);
 		login_params = g_strndup(base, c - base);
 
-		msn_got_login_params(session, login_params);
+		gaim_debug_info("msn", "TWN Cert: {%s}\n", login_params);
+
+		/* Parse the challenge data. */
+		elems = g_strsplit(login_params, "&amp;", 0);
+
+		for (cur = elems; *cur != NULL; cur++){
+				tokens = g_strsplit(*cur, "=", 2);
+				g_hash_table_insert(session->nexus->challenge_data, tokens[0], tokens[1]);
+				/* Don't free each of the tokens, only the array. */
+				g_free(tokens);
+		}
 
+		g_strfreev(elems);
+
+		cert_str = g_strdup_printf("t=%s&p=%s",
+			(char *)g_hash_table_lookup(nexus->challenge_data, "t"),
+			(char *)g_hash_table_lookup(nexus->challenge_data, "p")
+		);
+		msn_got_login_params(session, cert_str);
+
+		g_free(cert_str);
+//		g_free(body_len);
 		g_free(login_params);
-
+//		return;
 		msn_nexus_destroy(nexus);
 		session->nexus = NULL;
 		return;
@@ -290,7 +312,6 @@
 	g_free(nexus->read_buf);
 	nexus->read_buf = NULL;
 	nexus->read_len = 0;
-
 }
 
 
@@ -301,10 +322,11 @@
 	MsnNexus *nexus;
 	MsnSession *session;
 	char *username, *password;
-	char *request_str, *head, *tail;
+	char *request_str, *head, *tail,*challenge_str;
 	char *buffer = NULL;
 	guint32 ctint;
 
+	gaim_debug_info("MaYuan","starting Windows Live ID authentication\n");
 	nexus = data;
 	g_return_if_fail(nexus != NULL);
 
@@ -315,44 +337,44 @@
 
 	msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE);
 
-	username =
-		g_strdup(gaim_url_encode(gaim_account_get_username(session->account)));
-
-	password =
-		g_strdup(gaim_url_encode(gaim_connection_get_password(session->account->gc)));
-
-	ctint = strtoul((char *)g_hash_table_lookup(nexus->challenge_data, "ct"), NULL, 10) + 200;
+	username = g_strdup(gaim_account_get_username(session->account));
 
-	head = g_strdup_printf(
-		"GET %s HTTP/1.1\r\n"
-		"Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s",
-		nexus->login_path,
-		(char *)g_hash_table_lookup(nexus->challenge_data, "ru"),
-		username);
+	password = g_strdup(gaim_connection_get_password(session->account->gc));
+//		g_strdup(gaim_url_encode(gaim_connection_get_password(session->account->gc)));
 
-	tail = g_strdup_printf(
-		"lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%" G_GUINT32_FORMAT ",kpp=%s,kv=%s,ver=%s,tpf=%s\r\n"
-		"User-Agent: MSMSGS\r\n"
-		"Host: %s\r\n"
-		"Connection: Keep-Alive\r\n"
-		"Cache-Control: no-cache\r\n",
+	challenge_str = g_strdup_printf(
+		"lc=%s&amp;id=%s&amp;tw=%s&amp;fs=%s&amp;ru=%s&amp;ct=%s&amp;kpp=%s&amp;kv=%s&amp;ver=%s&amp;rn=%s&amp;tpf=%s\r\n",
 		(char *)g_hash_table_lookup(nexus->challenge_data, "lc"),
 		(char *)g_hash_table_lookup(nexus->challenge_data, "id"),
 		(char *)g_hash_table_lookup(nexus->challenge_data, "tw"),
 		(char *)g_hash_table_lookup(nexus->challenge_data, "fs"),
 		(char *)g_hash_table_lookup(nexus->challenge_data, "ru"),
-		ctint,
+		(char *)g_hash_table_lookup(nexus->challenge_data, "ct"),
 		(char *)g_hash_table_lookup(nexus->challenge_data, "kpp"),
 		(char *)g_hash_table_lookup(nexus->challenge_data, "kv"),
 		(char *)g_hash_table_lookup(nexus->challenge_data, "ver"),
-		(char *)g_hash_table_lookup(nexus->challenge_data, "tpf"),
-		nexus->login_host);
+		(char *)g_hash_table_lookup(nexus->challenge_data, "rn"),
+		(char *)g_hash_table_lookup(nexus->challenge_data, "tpf")
+		);
+
+	/*build the SOAP windows Live ID XML body */
+	tail = g_strdup_printf(TWN_ENVELOP_TEMPLATE,username,password,challenge_str	);
 
-	buffer = g_strdup_printf("%s,pwd=XXXXXXXX,%s\r\n", head, tail);
-	request_str = g_strdup_printf("%s,pwd=%s,%s\r\n", head, password, tail);
+	nexus->login_path = g_strdup(TWN_POST_URL);
+	head = g_strdup_printf(
+					"POST %s HTTP/1.1\r\n"
+					"Accept: text/*\r\n"
+					"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n"
+					"Host: %s\r\n"
+					"Content-Length: %d\r\n"
+					"Connection: Keep-Alive\r\n"
+					"Cache-Control: no-cache\r\n\r\n",
+					nexus->login_path,nexus->login_host,strlen(tail));
 
-	gaim_debug_misc("msn", "Sending: {%s}\n", buffer);
+	request_str = g_strdup_printf("%s%s", head,tail);
+//	gaim_debug_misc("msn", "TWN Sending: {%s}\n", request_str);
 
+//	g_free(nexus->login_path);
 	g_free(buffer);
 	g_free(head);
 	g_free(tail);
@@ -372,123 +394,18 @@
 	nexus_write_cb(nexus, gsc->fd, GAIM_INPUT_WRITE);
 
 	return;
-
-
 }
 
-static void
-nexus_connect_written_cb(gpointer data, gint source, GaimInputCondition cond)
+/**************************************************************************
+ * Connect
+ **************************************************************************/
+void
+msn_nexus_connect(MsnNexus *nexus)
 {
-	MsnNexus *nexus = data;
-	int len;
-	char *da_login;
-	char *base, *c;
-
-	if (nexus->input_handler == -1)
-		nexus->input_handler = gaim_input_add(nexus->gsc->fd,
-			GAIM_INPUT_READ, nexus_connect_written_cb, nexus);
-
-	/* Get the PassportURLs line. */
-	len = msn_ssl_read(nexus);
-
-	if (len < 0 && errno == EAGAIN)
-		return;
-	else if (len < 0) {
-		gaim_input_remove(nexus->input_handler);
-		nexus->input_handler = -1;
-		g_free(nexus->read_buf);
-		nexus->read_buf = NULL;
-		nexus->read_len = 0;
-		/* TODO: error handling */
-		return;
-	}
-
-	if (g_strstr_len(nexus->read_buf, nexus->read_len,
-			"\r\n\r\n") == NULL)
-		return;
-
-	gaim_input_remove(nexus->input_handler);
-	nexus->input_handler = -1;
-
-	base = strstr(nexus->read_buf, "PassportURLs");
-
-	if (base == NULL)
-	{
-		g_free(nexus->read_buf);
-		nexus->read_buf = NULL;
-		nexus->read_len = 0;
-		return;
-	}
-
-	if ((da_login = strstr(base, "DALogin=")) != NULL)
-	{
-		if ((da_login = strchr(da_login, '=')) != NULL)
-			da_login++;
-
-		if ((c = strchr(da_login, ',')) != NULL)
-			*c = '\0';
-
-		if ((c = strchr(da_login, '/')) != NULL)
-		{
-			nexus->login_path = g_strdup(c);
-			*c = '\0';
-		}
-
-		nexus->login_host = g_strdup(da_login);
-	}
-
-	g_free(nexus->read_buf);
-	nexus->read_buf = NULL;
-	nexus->read_len = 0;
-
-	gaim_ssl_close(nexus->gsc);
-	nexus->gsc = NULL;
-
-	/* Now begin the connection to the login server. */
+	/*  Authenticate via Windows Live ID. */
+	gaim_debug_info("MaYuan","msn_nexus_connect...\n");
+	nexus->login_host = g_strdup(TWN_SERVER);
 	gaim_ssl_connect(nexus->session->account, nexus->login_host,
 		GAIM_SSL_DEFAULT_PORT, login_connect_cb, login_error_cb,
 		nexus);
 }
-
-
-/**************************************************************************
- * Connect
- **************************************************************************/
-
-static void
-nexus_connect_cb(gpointer data, GaimSslConnection *gsc,
-				 GaimInputCondition cond)
-{
-	MsnNexus *nexus;
-	MsnSession *session;
-
-	nexus = data;
-	g_return_if_fail(nexus != NULL);
-
-	session = nexus->session;
-	g_return_if_fail(session != NULL);
-
-	nexus->gsc = gsc;
-
-	msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH);
-
-	nexus->write_buf = g_strdup("GET /rdr/pprdr.asp\r\n\r\n");
-	nexus->written_len = 0;
-
-	nexus->read_len = 0;
-
-	nexus->written_cb = nexus_connect_written_cb;
-
-	nexus->input_handler = gaim_input_add(gsc->fd, GAIM_INPUT_WRITE,
-		nexus_write_cb, nexus);
-
-	nexus_write_cb(nexus, gsc->fd, GAIM_INPUT_WRITE);
-}
-
-void
-msn_nexus_connect(MsnNexus *nexus)
-{
-	gaim_ssl_connect(nexus->session->account, "nexus.passport.com",
-		GAIM_SSL_DEFAULT_PORT, nexus_connect_cb,
-		login_error_cb, nexus);
-}

mercurial