Index: protocols/http_client.c
===================================================================
--- protocols/http_client.c	(revision cdca30b360c09399f1e5a2556d83ec997006cd75)
+++ protocols/http_client.c	(revision 4ff09664d2570be8358a3bde62123cc8e0a17c9e)
@@ -157,4 +157,6 @@
 	
 error:
+	req->status_string = g_strdup( "Error while writing HTTP request" );
+	
 	req->func( req );
 	
@@ -216,4 +218,5 @@
 			if( !sockerr_again() )
 			{
+				req->status_string = g_strdup( strerror( errno ) );
 				goto cleanup;
 			}
@@ -243,5 +246,8 @@
 	   support... */
 	if( req->bytes_read == 0 )
+	{
+		req->status_string = g_strdup( "Empty HTTP reply" );
 		goto cleanup;
+	}
 	
 	/* Zero termination is very convenient. */
@@ -264,4 +270,5 @@
 	else
 	{
+		req->status_string = g_strdup( "Malformed HTTP reply" );
 		goto cleanup;
 	}
@@ -279,8 +286,29 @@
 	{
 		if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 )
+		{
+			req->status_string = g_strdup( "Can't parse status code" );
 			req->status_code = -1;
-	}
-	else
-	{
+		}
+		else
+		{
+			char *eol;
+			
+			if( evil_server )
+				eol = strchr( end1, '\n' );
+			else
+				eol = strchr( end1, '\r' );
+			
+			req->status_string = g_strndup( end1 + 1, eol - end1 - 1 );
+			
+			/* Just to be sure... */
+			if( ( eol = strchr( req->status_string, '\r' ) ) )
+				*eol = 0;
+			if( ( eol = strchr( req->status_string, '\n' ) ) )
+				*eol = 0;
+		}
+	}
+	else
+	{
+		req->status_string = g_strdup( "Can't locate status code" );
 		req->status_code = -1;
 	}
@@ -291,7 +319,14 @@
 		int error = 0, new_port, new_proto;
 		
+		/* We might fill it again, so let's not leak any memory. */
+		g_free( req->status_string );
+		req->status_string = NULL;
+		
 		loc = strstr( req->reply_headers, "\nLocation: " );
 		if( loc == NULL ) /* We can't handle this redirect... */
+		{
+			req->status_string = g_strdup( "Can't locate Location: header" );
 			goto cleanup;
+		}
 		
 		loc += 11;
@@ -310,4 +345,6 @@
 			   don't need this yet anyway, I won't implement it. */
 			
+			req->status_string = g_strdup( "Can't handle recursive redirects" );
+			
 			goto cleanup;
 		}
@@ -327,4 +364,5 @@
 			if( !url_set( url, loc ) )
 			{
+				req->status_string = g_strdup( "Malformed redirect URL" );
 				g_free( url );
 				goto cleanup;
@@ -337,8 +375,10 @@
 			   going to use strcat(), whether you like it or not. :-) */
 			
-			/* First, find the GET/POST/whatever from the original request. */
-			s = strchr( req->request, ' ' );
+			sprintf( new_request, "GET %s HTTP/1.0", url->file );
+			
+			s = strstr( req->request, "\r\n" );
 			if( s == NULL )
 			{
+				req->status_string = g_strdup( "Error while rebuilding request string" );
 				g_free( new_request );
 				g_free( url );
@@ -346,17 +386,5 @@
 			}
 			
-			*s = 0;
-			sprintf( new_request, "%s %s HTTP/1.0\r\n", req->request, url->file );
-			*s = ' ';
-			
-			s = strstr( req->request, "\r\n" );
-			if( s == NULL )
-			{
-				g_free( new_request );
-				g_free( url );
-				goto cleanup;
-			}
-			
-			strcat( new_request, s + 2 );
+			strcat( new_request, s );
 			new_host = g_strdup( url->host );
 			new_port = url->port;
@@ -372,5 +400,5 @@
 		
 		req->fd = -1;
-		req->ssl = 0;
+		req->ssl = NULL;
 		
 		if( new_proto == PROTO_HTTPS )
@@ -390,4 +418,5 @@
 		if( error )
 		{
+			req->status_string = g_strdup( "Connection problem during redirect" );
 			g_free( new_request );
 			goto cleanup;
@@ -418,4 +447,5 @@
 	g_free( req->request );
 	g_free( req->reply_headers );
+	g_free( req->status_string );
 	g_free( req );
 	
Index: protocols/http_client.h
===================================================================
--- protocols/http_client.h	(revision cdca30b360c09399f1e5a2556d83ec997006cd75)
+++ protocols/http_client.h	(revision 4ff09664d2570be8358a3bde62123cc8e0a17c9e)
@@ -37,4 +37,5 @@
 	int request_length;
 	int status_code;
+	char *status_string;
 	char *reply_headers;
 	char *reply_body;
Index: protocols/msn/ns.c
===================================================================
--- protocols/msn/ns.c	(revision cdca30b360c09399f1e5a2556d83ec997006cd75)
+++ protocols/msn/ns.c	(revision 4ff09664d2570be8358a3bde62123cc8e0a17c9e)
@@ -656,6 +656,13 @@
 	if( key == NULL )
 	{
-		hide_login_progress( gc, "Error during Passport authentication" );
+		char *err;
+		
+		err = g_strdup_printf( "Error during Passport authentication (%s)",
+		                       rep->error_string ? rep->error_string : "Unknown error" );
+		
+		hide_login_progress( gc, err );
 		signoff( gc );
+		
+		g_free( err );
 	}
 	else
Index: protocols/msn/passport.c
===================================================================
--- protocols/msn/passport.c	(revision cdca30b360c09399f1e5a2556d83ec997006cd75)
+++ protocols/msn/passport.c	(revision 4ff09664d2570be8358a3bde62123cc8e0a17c9e)
@@ -69,6 +69,5 @@
 	}
 	
-	reqs = g_malloc( strlen( header ) + strlen( dummy ) + 128 );
-	sprintf( reqs, "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header );
+	reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header );
 	
 	*dummy = 0;
@@ -88,5 +87,5 @@
 	struct passport_reply *rep = req->data;
 	
-	if( !g_slist_find( msn_connections, rep->data ) || !req->finished || !req->reply_headers )
+	if( !g_slist_find( msn_connections, rep->data ) )
 	{
 		destroy_reply( rep );
@@ -94,5 +93,5 @@
 	}
 	
-	if( req->status_code == 200 )
+	if( req->finished && req->reply_headers && req->status_code == 200 )
 	{
 		char *dummy;
@@ -109,4 +108,13 @@
 			rep->result = g_strdup( dummy );
 		}
+		else
+		{
+			rep->error_string = g_strdup( "Could not parse Passport server response" );
+		}
+	}
+	else
+	{
+		rep->error_string = g_strdup_printf( "HTTP error: %s",
+		                      req->status_string ? req->status_string : "Unknown error" );
 	}
 	
@@ -145,5 +153,4 @@
 }
 
-#define PPR_REQUEST "GET /rdr/pprdr.asp HTTP/1.0\r\n\r\n"
 static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header )
 {
@@ -155,5 +162,5 @@
 	rep->header = header;
 	
-	req = http_dorequest( "nexus.passport.com", 443, 1, PPR_REQUEST, passport_retrieve_dalogin_ready, rep );
+	req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep );
 	
 	if( !req )
@@ -169,5 +176,5 @@
 	char *urlend;
 	
-	if( !g_slist_find( msn_connections, rep->data ) || !req->finished || !req->reply_headers )
+	if( !g_slist_find( msn_connections, rep->data ) )
 	{
 		destroy_reply( rep );
@@ -175,8 +182,18 @@
 	}
 	
+	if( !req->finished || !req->reply_headers || req->status_code != 200 )
+	{
+		rep->error_string = g_strdup_printf( "HTTP error while fetching DALogin: %s",
+		                        req->status_string ? req->status_string : "Unknown error" );
+		goto failure;
+	}
+	
 	dalogin = strstr( req->reply_headers, "DALogin=" );	
 	
 	if( !dalogin )
+	{
+		rep->error_string = g_strdup( "Parse error while fetching DALogin" );
 		goto failure;
+	}
 	
 	dalogin += strlen( "DALogin=" );
@@ -208,4 +225,5 @@
 	g_free( rep->result );
 	g_free( rep->header );
+	g_free( rep->error_string );
 	g_free( rep );
 }
Index: protocols/msn/passport.h
===================================================================
--- protocols/msn/passport.h	(revision cdca30b360c09399f1e5a2556d83ec997006cd75)
+++ protocols/msn/passport.h	(revision 4ff09664d2570be8358a3bde62123cc8e0a17c9e)
@@ -39,4 +39,5 @@
 	char *result;
 	char *header;
+	char *error_string;
 };
 
Index: protocols/msn/sb.c
===================================================================
--- protocols/msn/sb.c	(revision cdca30b360c09399f1e5a2556d83ec997006cd75)
+++ protocols/msn/sb.c	(revision 4ff09664d2570be8358a3bde62123cc8e0a17c9e)
@@ -529,12 +529,12 @@
 		{
 			msn_sb_destroy( sb );
-			return( 0 );
-		}
-		if( err->flags & STATUS_FATAL )
+			return 0;
+		}
+		else if( err->flags & STATUS_FATAL )
 		{
 			signoff( gc );
-			return( 0 );
-		}
-		if( err->flags & STATUS_SB_IM_SPARE )
+			return 0;
+		}
+		else if( err->flags & STATUS_SB_IM_SPARE )
 		{
 			if( sb->who )
@@ -559,4 +559,6 @@
 				sb->msgq = NULL;
 			}
+			
+			/* Do NOT return 0 here, we want to keep this sb. */
 		}
 	}
Index: protocols/msn/tables.c
===================================================================
--- protocols/msn/tables.c	(revision cdca30b360c09399f1e5a2556d83ec997006cd75)
+++ protocols/msn/tables.c	(revision 4ff09664d2570be8358a3bde62123cc8e0a17c9e)
@@ -127,5 +127,5 @@
 	
 	{ 910, "Server is busy",                                        STATUS_FATAL },
-	{ 911, "Authentication failed",                                 STATUS_FATAL },
+	{ 911, "Authentication failed",                                 STATUS_SB_FATAL | STATUS_FATAL },
 	{ 912, "Server is busy",                                        STATUS_FATAL },
 	{ 913, "Not allowed when hiding",                               0 },
