changeset 8171:d0ba2f7b40e7

[gaim-migrate @ 8884] Committing one of shx's MSN patches, which splits off the Nexus connection code into nexus.[ch] and cleans it up a bit. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Tue, 27 Jan 2004 04:46:05 +0000
parents 9d1a984681fe
children e68b1486c7ad
files src/protocols/msn/Makefile.am src/protocols/msn/Makefile.mingw src/protocols/msn/nexus.c src/protocols/msn/nexus.h src/protocols/msn/notification.c src/protocols/msn/session.c src/protocols/msn/session.h
diffstat 7 files changed, 417 insertions(+), 404 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/msn/Makefile.am	Sun Jan 25 22:15:42 2004 +0000
+++ b/src/protocols/msn/Makefile.am	Tue Jan 27 04:46:05 2004 +0000
@@ -21,6 +21,8 @@
 	msnobject.h \
 	msnslp.c \
 	msnslp.h \
+	nexus.c \
+	nexus.h \
 	notification.c \
 	notification.h \
 	page.c \
--- a/src/protocols/msn/Makefile.mingw	Sun Jan 25 22:15:42 2004 +0000
+++ b/src/protocols/msn/Makefile.mingw	Tue Jan 27 04:46:05 2004 +0000
@@ -77,6 +77,7 @@
 			msnobject.c \
 			msnslp.c \
 			notification.c \
+			nexus.c \
 			page.c \
 			servconn.c \
 			session.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/msn/nexus.c	Tue Jan 27 04:46:05 2004 +0000
@@ -0,0 +1,372 @@
+#include "msn.h"
+#include "nexus.h"
+#include "notification.h"
+
+/**************************************************************************
+ * Util
+ **************************************************************************/
+
+static size_t
+msn_ssl_read(GaimSslConnection *gsc, char **dest_buffer)
+{
+	size_t size = 0, s;
+	char *buffer = NULL;
+	char temp_buf[4096];
+
+	while ((s = gaim_ssl_read(gsc, temp_buf, sizeof(temp_buf))) > 0)
+	{
+		buffer = g_realloc(buffer, size + s + 1);
+
+		strncpy(buffer + size, temp_buf, s);
+
+		buffer[size + s] = '\0';
+
+		size += s;
+	}
+
+	*dest_buffer = buffer;
+
+	return size;
+}
+
+/**************************************************************************
+ * Login
+ **************************************************************************/
+
+static void
+login_error_cb(GaimSslConnection *gsc, GaimSslErrorType error, void *data)
+{
+	MsnNexus *nexus;
+	MsnSession *session;
+	GaimAccount *account;
+	GaimConnection *gc;
+
+	nexus = data;
+	g_return_if_fail(nexus != NULL);
+
+	session = nexus->session;
+	g_return_if_fail(session != NULL);
+
+	account = session->account;
+	g_return_if_fail(account != NULL);
+
+	gc = gaim_account_get_connection(account);
+	g_return_if_fail(gc != NULL);
+
+	gaim_connection_error(gc, _("Unable to connect to server"));
+
+	msn_nexus_destroy(nexus);
+	session->nexus = NULL;
+}
+
+static void
+login_connect_cb(gpointer data, GaimSslConnection *gsc,
+				 GaimInputCondition cond)
+{
+	MsnNexus *nexus;
+	MsnSession *session;
+	GaimConnection *gc;
+	char *username, *password;
+	char *request_str;
+	char *buffer = NULL;
+	size_t s;
+
+	nexus = data;
+	g_return_if_fail(nexus != NULL);
+
+	session = nexus->session;
+	g_return_if_fail(session != NULL);
+
+	gc = gaim_account_get_connection(session->account);
+	g_return_if_fail(gc != NULL);
+
+	username =
+		g_strdup(gaim_url_encode(gaim_account_get_username(session->account)));
+
+	password =
+		g_strdup(gaim_url_encode(gaim_account_get_password(session->account)));
+
+	request_str = g_strdup_printf(
+		"GET %s HTTP/1.1\r\n"
+		"Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s,pwd=%s,"
+		"lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%s,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"
+		"\r\n",
+		nexus->login_path,
+		(char *)g_hash_table_lookup(nexus->challenge_data, "ru"),
+		username, password,
+		(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"),
+		(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);
+
+	gaim_debug(GAIM_DEBUG_MISC, "msn", "Sending: {%s}\n", request_str);
+
+	g_free(username);
+	g_free(password);
+
+	if ((s = gaim_ssl_write(gsc, request_str, strlen(request_str))) <= 0)
+	{
+		g_free(request_str);
+		gaim_connection_error(gc, _("Unable to write to MSN Nexus server."));
+
+		return;
+	}
+
+	g_free(request_str);
+
+	if ((s = msn_ssl_read(gsc, &buffer)) <= 0)
+	{
+		gaim_connection_error(gc, _("Unable to write to MSN Nexus server."));
+		return;
+	}
+
+	gaim_ssl_close(gsc);
+
+	gaim_debug(GAIM_DEBUG_MISC, "msn", "ssl buffer: {%s}", buffer);
+
+	if (strstr(buffer, "HTTP/1.1 302") != NULL)
+	{
+		/* Redirect. */
+		char *location, *c;
+
+		location = strstr(buffer, "Location: ");
+		if (location == NULL)
+		{
+			gaim_connection_error(gc,
+				_("MSN Nexus server returned invalid redirect information."));
+
+			g_free(buffer);
+
+			return;
+		}
+
+		location = strchr(location, ' ') + 1;
+
+		if ((c = strchr(location, '\r')) != NULL)
+			*c = '\0';
+
+		/* Skip the http:// */
+		if ((c = strchr(location, '/')) != NULL)
+			location = c + 2;
+
+		if ((c = strchr(location, '/')) != NULL)
+		{
+			g_free(nexus->login_path);
+			nexus->login_path = g_strdup(c);
+
+			*c = '\0';
+		}
+
+		g_free(nexus->login_host);
+		nexus->login_host = g_strdup(location);
+
+		gaim_ssl_connect(session->account, nexus->login_host,
+						 GAIM_SSL_DEFAULT_PORT, login_connect_cb,
+						 login_error_cb, nexus);
+	}
+	else if (strstr(buffer, "HTTP/1.1 401 Unauthorized") != NULL)
+	{
+		GaimConnection *gc;
+		const char *error, *c;
+		char *temp;
+
+		if ((error = strstr(buffer, "WWW-Authenticate")) != NULL)
+		{
+			if ((error = strstr(error, "cbtxt=")) != NULL)
+			{
+				error += strlen("cbtxt=");
+
+				if ((c = strchr(error, '\n')) == NULL)
+					c = error + strlen(error);
+
+				temp = g_strndup(error, c - error);
+				error = gaim_url_decode(temp);
+				g_free(temp);
+			}
+		}
+
+		gc = gaim_account_get_connection(session->account);
+
+		if (error == NULL)
+		{
+			gaim_connection_error(gc,
+				_("Unknown error when attempting to authorize with "
+				  "MSN login server."));
+		}
+		else
+			gaim_connection_error(gc, error);
+	}
+	else if (strstr(buffer, "HTTP/1.1 200 OK"))
+	{
+		char outparams[MSN_BUF_LEN];
+		char *base, *c;
+		char *login_params;
+
+#if 0
+		/* All your base are belong to us. */
+		base = buffer;
+
+		/* For great cookie! */
+		while ((base = strstr(base, "Set-Cookie: ")) != NULL)
+		{
+			base += strlen("Set-Cookie: ");
+
+			c = strchr(base, ';');
+
+			session->login_cookies =
+				g_list_append(session->login_cookies,
+							  g_strndup(base, c - base));
+		}
+#endif
+
+		base  = strstr(buffer, "Authentication-Info: ");
+
+		if(base == NULL)
+		{
+			gaim_debug(GAIM_DEBUG_ERROR, "msn",
+					   "Authentication information was not found. This did "
+					   "not just happen, but if it did, you're screwed. "
+					   "Report this.\n");
+
+			return;
+		}
+
+		base  = strstr(base, "from-PP='");
+		base += strlen("from-PP='");
+		c     = strchr(base, '\'');
+
+		login_params = g_strndup(base, c - base);
+
+		g_snprintf(outparams, sizeof(outparams),
+			"TWN S %s", login_params);
+
+		msn_servconn_send_command(session->notification_conn, "USR",
+								  outparams);
+
+		g_free(login_params);
+
+		msn_nexus_destroy(nexus);
+		session->nexus = NULL;
+	}
+
+	g_free(buffer);
+}
+
+static void
+nexus_connect_cb(gpointer data, GaimSslConnection *gsc,
+				 GaimInputCondition cond)
+{
+	MsnNexus *nexus;
+	MsnSession *session;
+	char *request_str;
+	char *da_login;
+	char *base, *c;
+	char *buffer = NULL;
+	size_t s;
+
+	nexus = data;
+	g_return_if_fail(nexus != NULL);
+
+	session = nexus->session;
+	g_return_if_fail(session != NULL);
+
+	request_str = g_strdup_printf("GET /rdr/pprdr.asp\r\n\r\n");
+
+	if ((s = gaim_ssl_write(gsc, request_str, strlen(request_str))) <= 0)
+	{
+		g_free(request_str);
+		return;
+	}
+
+	g_free(request_str);
+
+	/* Get the PassportURLs line. */
+	if ((s = msn_ssl_read(gsc, &buffer)) <= 0)
+		return;
+
+	base = strstr(buffer, "PassportURLs");
+
+	if (base == NULL)
+	{
+		g_free(buffer);
+		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(buffer);
+
+	gaim_ssl_close(gsc);
+
+	/* Now begin the connection to the login server. */
+	gaim_ssl_connect(session->account, nexus->login_host,
+					 GAIM_SSL_DEFAULT_PORT, login_connect_cb,
+					 login_error_cb, nexus);
+}
+
+/**************************************************************************
+ * Nexus
+ **************************************************************************/
+
+MsnNexus *
+msn_nexus_new(MsnSession *session)
+{
+	MsnNexus *nexus;
+
+	nexus = g_new0(MsnNexus, 1);
+	nexus->session = session;
+	nexus->challenge_data = g_hash_table_new_full(g_str_hash, g_str_equal,
+												  g_free, g_free);
+
+	return nexus;
+}
+
+void
+msn_nexus_destroy(MsnNexus *nexus)
+{
+	if (nexus->login_host != NULL)
+		g_free(nexus->login_host);
+
+	if (nexus->login_path != NULL)
+		g_free(nexus->login_path);
+
+	if (nexus->challenge_data != NULL)
+		g_hash_table_destroy(nexus->challenge_data);
+
+	g_free(nexus);
+}
+
+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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/msn/nexus.h	Tue Jan 27 04:46:05 2004 +0000
@@ -0,0 +1,21 @@
+#ifndef _MSN_NEXUS_H_
+#define _MSN_NEXUS_H_
+
+typedef struct _MsnNexus MsnNexus;
+
+#include "session.h"
+
+struct _MsnNexus
+{
+	MsnSession *session;
+
+	char *login_host;
+	char *login_path;
+	GHashTable *challenge_data;
+};
+
+void msn_nexus_connect(MsnNexus *nexus);
+MsnNexus *msn_nexus_new(MsnSession *session);
+void msn_nexus_destroy(MsnNexus *nexus);
+
+#endif // _MSN_NEXUS_H_
--- a/src/protocols/msn/notification.c	Sun Jan 25 22:15:42 2004 +0000
+++ b/src/protocols/msn/notification.c	Tue Jan 27 04:46:05 2004 +0000
@@ -128,38 +128,6 @@
 	return TRUE;
 }
 
-static size_t
-msn_ssl_read(GaimSslConnection *gsc, char **dest_buffer)
-{
-	size_t size = 0, s;
-	char *buffer = NULL;
-	char temp_buf[4096];
-
-	while ((s = gaim_ssl_read(gsc, temp_buf, sizeof(temp_buf))) > 0)
-	{
-		char *new_buffer = g_new(char, size + s + 1);
-
-		if (buffer != NULL)
-		{
-			strncpy(new_buffer, buffer, size);
-
-			g_free(buffer);
-		}
-
-		buffer = new_buffer;
-
-		strncpy(buffer + size, temp_buf, s);
-
-		buffer[size + s] = '\0';
-
-		size += s;
-	}
-
-	*dest_buffer = buffer;
-
-	return size;
-}
-
 /**************************************************************************
  * Callbacks
  **************************************************************************/
@@ -312,300 +280,6 @@
 	return TRUE;
 }
 
-static void
-login_error_cb(GaimSslConnection *gsc, GaimSslErrorType error, void *data)
-{
-	MsnServConn *servconn = (MsnServConn *)data;
-	GaimAccount *account = servconn->session->account;
-	GaimConnection *gc = gaim_account_get_connection(account);
-
-	gaim_connection_error(gc, _("Unable to connect to server"));
-}
-
-static void
-login_connect_cb(gpointer data, GaimSslConnection *gsc,
-				 GaimInputCondition cond)
-{
-	MsnServConn *servconn = (MsnServConn *)data;
-	MsnSession *session = servconn->session;
-	GaimConnection *gc = gaim_account_get_connection(session->account);
-	char *username, *password;
-	char *request_str;
-	char *buffer = NULL;
-	char *tpf;
-	size_t s;
-
-	username =
-		g_strdup(gaim_url_encode(gaim_account_get_username(session->account)));
-	password =
-		g_strdup(gaim_url_encode(gaim_account_get_password(session->account)));
-
-	tpf = (char *)g_hash_table_lookup(session->ssl_challenge_data, "tpf");
-
-	request_str = g_strdup_printf(
-		"GET %s HTTP/1.1\r\n"
-		"Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s,pwd=%s,"
-		"lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%s,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"
-		"\r\n",
-		session->ssl_login_path,
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "ru"),
-		username, password,
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "lc"),
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "id"),
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "tw"),
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "fs"),
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "ru"),
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "ct"),
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "kpp"),
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "kv"),
-		(char *)g_hash_table_lookup(session->ssl_challenge_data, "ver"),
-		(tpf == NULL ? "" : tpf),
-		session->ssl_login_host);
-
-	gaim_debug(GAIM_DEBUG_MISC, "msn", "Sending: {%s}\n", request_str);
-
-	g_free(username);
-	g_free(password);
-
-	if ((s = gaim_ssl_write(gsc, request_str, strlen(request_str))) <= 0)
-	{
-		g_free(request_str);
-		gaim_connection_error(gc, _("Unable to write to MSN Nexus server."));
-
-		return;
-	}
-
-	g_free(request_str);
-
-	if ((s = msn_ssl_read(gsc, &buffer)) <= 0)
-	{
-		gaim_connection_error(gc, _("Unable to read from MSN Nexus server."));
-
-		if (buffer != NULL)
-			g_free(buffer);
-
-		return;
-	}
-
-	gaim_ssl_close(gsc);
-
-	gaim_debug(GAIM_DEBUG_MISC, "msn", "ssl buffer: {%s}", buffer);
-
-	if (strstr(buffer, "HTTP/1.1 302") != NULL)
-	{
-		/* Redirect. */
-		char *location, *c;
-
-		if ((location = strstr(buffer, "Location: ")) == NULL)
-		{
-			gaim_connection_error(gc,
-				_("MSN Nexus server returned invalid redirect information."));
-
-			g_free(buffer);
-
-			return;
-		}
-
-		location = strchr(location, ' ') + 1;
-
-		if ((c = strchr(location, '\r')) != NULL)
-			*c = '\0';
-
-		/* Skip the http:// */
-		if ((c = strchr(location, '/')) != NULL)
-			location = c + 2;
-
-		if ((c = strchr(location, '/')) != NULL)
-		{
-			session->ssl_login_path = g_strdup(c);
-
-			*c = '\0';
-		}
-
-		session->ssl_login_host = g_strdup(location);
-
-		session->ssl_conn = gaim_ssl_connect(session->account,
-											 session->ssl_login_host,
-											 GAIM_SSL_DEFAULT_PORT,
-											 login_connect_cb, login_error_cb,
-											 servconn);
-	}
-	else if (strstr(buffer, "HTTP/1.1 401 Unauthorized") != NULL)
-	{
-		const char *error, *c;
-		char *temp;
-
-		if ((error = strstr(buffer, "WWW-Authenticate")) != NULL)
-		{
-			if ((error = strstr(error, "cbtxt=")) != NULL)
-			{
-				error += strlen("cbtxt=");
-
-				if ((c = strchr(error, '\n')) == NULL)
-					c = error + strlen(error);
-
-				temp = g_strndup(error, c - error);
-				error = gaim_url_decode(temp);
-				g_free(temp);
-			}
-		}
-
-		if (error == NULL)
-		{
-			gaim_connection_error(gc,
-				_("Unknown error when attempting to authorize with "
-				  "MSN login server."));
-		}
-		else
-			gaim_connection_error(gc, error);
-	}
-	else
-	{
-		char *base, *c;
-		char outparams[MSN_BUF_LEN];
-
-		g_free(session->ssl_login_host);
-		g_free(session->ssl_login_path);
-		g_hash_table_destroy(session->ssl_challenge_data);
-
-		session->ssl_login_host = NULL;
-		session->ssl_login_path = NULL;
-		session->ssl_challenge_data = NULL;
-
-#if 0
-		/* All your base are belong to us. */
-		base = buffer;
-
-		/* For great cookie! */
-		while ((base = strstr(base, "Set-Cookie: ")) != NULL)
-		{
-			base += strlen("Set-Cookie: ");
-
-			c = strchr(base, ';');
-
-			session->login_cookies =
-				g_list_append(session->login_cookies,
-							  g_strndup(base, c - base));
-		}
-#endif
-
-		if ((base = strstr(buffer, "Authentication-Info: ")) == NULL)
-		{
-			gaim_debug(GAIM_DEBUG_ERROR, "msn",
-					   "Authentication information was not found. This did "
-					   "not just happen, but if it did, you're screwed. "
-					   "Report this.\n");
-
-			return;
-		}
-
-		base  = strstr(base, "from-PP='");
-		base += strlen("from-PP='");
-		c     = strchr(base, '\'');
-
-		session->ssl_login_params = g_strndup(base, c - base);
-
-		g_snprintf(outparams, sizeof(outparams),
-				   "TWN S %s", session->ssl_login_params);
-
-		g_free(session->ssl_login_params);
-		session->ssl_login_params = NULL;
-
-		if (!msn_servconn_send_command(session->notification_conn, "USR",
-									   outparams))
-		{
-			gaim_connection_error(gc, _("Unable to request USR\n"));
-		}
-	}
-
-	g_free(buffer);
-}
-
-static void
-nexus_connect_cb(gpointer data, GaimSslConnection *gsc,
-				 GaimInputCondition cond)
-{
-	MsnServConn *servconn = (MsnServConn *)data;
-	MsnSession *session = servconn->session;
-	GaimConnection *gc = gaim_account_get_connection(session->account);
-	char *request_str;
-	char *da_login;
-	char *base, *c;
-	char *buffer = NULL;
-	size_t s;
-
-	request_str = g_strdup_printf("GET /rdr/pprdr.asp\r\n\r\n");
-
-	if ((s = gaim_ssl_write(gsc, request_str, strlen(request_str))) <= 0)
-	{
-		g_free(request_str);
-		gaim_connection_error(gc, _("Unable to write to MSN Nexus server."));
-		return;
-	}
-
-	g_free(request_str);
-
-	if (session->ssl_url != NULL)
-	{
-		g_free(session->ssl_url);
-		session->ssl_url = NULL;
-	}
-
-	/* Get the PassportURLs line. */
-	if ((s = msn_ssl_read(gsc, &buffer)) <= 0)
-	{
-		gaim_connection_error(gc, _("Unable to read from MSN Nexus server."));
-
-		if (buffer != NULL)
-			g_free(buffer);
-
-		return;
-	}
-
-	if ((base = strstr(buffer, "PassportURLs")) == NULL)
-	{
-		gaim_connection_error(gc,
-				_("MSN Nexus server returned invalid information."));
-
-		g_free(buffer);
-
-		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)
-		{
-			session->ssl_login_path = g_strdup(c);
-
-			*c = '\0';
-		}
-
-		session->ssl_login_host = g_strdup(da_login);
-	}
-
-	g_free(buffer);
-
-	gaim_ssl_close(gsc);
-
-	/* Now begin the connection to the login server. */
-	session->ssl_conn = gaim_ssl_connect(session->account,
-										 session->ssl_login_host,
-										 GAIM_SSL_DEFAULT_PORT,
-										 login_connect_cb, login_error_cb,
-										 servconn);
-}
-
 static gboolean
 usr_cmd(MsnServConn *servconn, const char *command, const char **params,
 		size_t param_count)
@@ -643,75 +317,25 @@
 	}
 	else if (!g_ascii_strcasecmp(params[1], "TWN"))
 	{
-		/* Passport authentication */
-		char *challenge_data;
-		char *key, *value = NULL;
-		char *c;
+		char **elems, **cur, **tokens;
 
-		if (session->ssl_challenge_data != NULL)
-			g_hash_table_destroy(session->ssl_challenge_data);
-
-		session->ssl_challenge_data =
-			g_hash_table_new_full(g_str_hash, g_str_equal,
-								  g_free, g_free);
+		/* Passport authentication */
+		session->nexus = msn_nexus_new(session);
 
 		/* Parse the challenge data. */
-
-		challenge_data = g_strdup(params[3]);
-
-		for (c = challenge_data, key = challenge_data; *c != '\0'; c++)
-		{
-			if (*c == '=')
-			{
-				*c = '\0';
+		elems = g_strsplit(params[3], ",", 0);
 
-				value = c + 1;
-			}
-			else if (*c == ',')
-			{
-				*c = '\0';
-
-				g_hash_table_insert(session->ssl_challenge_data,
-									g_strdup(key), g_strdup(value));
-
-				key = c + 1;
-			}
+		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);
 		}
 
-		if (key < value)
-		{
-			/* Let's not forget the last one, it doesn't end with a ',' */
-			g_hash_table_insert(session->ssl_challenge_data,
-								g_strdup(key), g_strdup(value));
-		}
-
-		g_free(challenge_data);
-
-#if 0
-		passport_str = g_strdup(gaim_url_decode(params[3]));
+		g_strfreev(elems);
 
-		for (c = passport_str; *c != '\0'; c++)
-		{
-			if (*c == ',')
-				*c = '&';
-		}
-
-		session->ssl_url = passport_str;
-#endif
-
-		session->ssl_conn = gaim_ssl_connect(session->account,
-											 "nexus.passport.com",
-											 GAIM_SSL_DEFAULT_PORT,
-											 nexus_connect_cb, login_error_cb,
-											 servconn);
-
-		if (session->ssl_conn == NULL)
-		{
-			gaim_connection_error(gc,
-				_("Unable to connect to passport server"));
-
-			return FALSE;
-		}
+		msn_nexus_connect(session->nexus);
 
 		gaim_connection_update_progress(gc, _("Password sent"),
 										6, MSN_CONNECT_STEPS);
--- a/src/protocols/msn/session.c	Sun Jan 25 22:15:42 2004 +0000
+++ b/src/protocols/msn/session.c	Tue Jan 27 04:46:05 2004 +0000
@@ -62,12 +62,6 @@
 	if (session->dispatch_server != NULL)
 		g_free(session->dispatch_server);
 
-	if (session->ssl_login_path != NULL)
-		g_free(session->ssl_login_path);
-
-	if (session->ssl_login_host != NULL)
-		g_free(session->ssl_login_host);
-
 	while (session->switches != NULL)
 		msn_switchboard_destroy(session->switches->data);
 
@@ -98,6 +92,9 @@
 	if (session->away_state != NULL)
 		g_free(session->away_state);
 
+	if (session->nexus != NULL)
+		msn_nexus_destroy(session->nexus);
+
 	g_free(session);
 }
 
--- a/src/protocols/msn/session.h	Sun Jan 25 22:15:42 2004 +0000
+++ b/src/protocols/msn/session.h	Tue Jan 27 04:46:05 2004 +0000
@@ -24,12 +24,13 @@
 
 typedef struct _MsnSession MsnSession;
 
+#include "group.h"
+#include "nexus.h"
+#include "servconn.h"
 #include "sslconn.h"
-
-#include "servconn.h"
 #include "switchboard.h"
 #include "user.h"
-#include "group.h"
+
 
 struct _MsnSession
 {
@@ -47,17 +48,12 @@
 	MsnServConn *dispatch_conn;
 	MsnServConn *notification_conn;
 
+	MsnNexus *nexus;
+
 	unsigned int trId;
 
 	gboolean http_method;
 
-	char *ssl_url;
-	char *ssl_login_host;
-	char *ssl_login_path;
-	char *ssl_login_params;
-	GHashTable *ssl_challenge_data;
-	GaimSslConnection *ssl_conn;
-
 	MsnUsers *users;
 	MsnGroups *groups;