Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision 4aa8a046968bff0a08dc5ae96e228861fa21fcbe)
+++ protocols/msn/msn.c	(revision 27053b516db4d0e648d666e6d9e36856af428775)
@@ -64,5 +64,5 @@
 	md->away_state = msn_away_state_list;
 	md->domaintree = g_tree_new( msn_domaintree_cmp );
-	md->ns->fd = md->auth->fd = -1;
+	md->ns->fd = -1;
 	
 	msn_connections = g_slist_prepend( msn_connections, ic );
@@ -87,5 +87,4 @@
 		
 		msn_ns_close( md->ns );
-		msn_ns_close( md->auth );
 		
 		while( md->switchboards )
@@ -97,4 +96,5 @@
 			g_free( md->tokens[i] );
 		g_free( md->lock_key );
+		g_free( md->pp_policy );
 		
 		while( md->groups )
@@ -181,6 +181,4 @@
 	struct msn_data *md = ic->proto_data;
 	
-	strcpy( md->tokens[1], md->tokens[2] );
-	
 	if( state == NULL )
 		md->away_state = msn_away_state_list;
@@ -284,5 +282,5 @@
 static void msn_rem_permit( struct im_connection *ic, char *who )
 {
-	//msn_buddy_list_remove( ic, MSN_BUDDY_AL, who, NULL );
+	msn_buddy_list_remove( ic, MSN_BUDDY_AL, who, NULL );
 }
 
@@ -302,5 +300,5 @@
 static void msn_rem_deny( struct im_connection *ic, char *who )
 {
-	//msn_buddy_list_remove( ic, MSN_BUDDY_BL, who, NULL );
+	msn_buddy_list_remove( ic, MSN_BUDDY_BL, who, NULL );
 }
 
Index: protocols/msn/msn.h
===================================================================
--- protocols/msn/msn.h	(revision 4aa8a046968bff0a08dc5ae96e228861fa21fcbe)
+++ protocols/msn/msn.h	(revision 27053b516db4d0e648d666e6d9e36856af428775)
@@ -81,4 +81,5 @@
 	MSN_GOT_PROFILE_DN = 2,
 	MSN_DONE_ADL = 4,
+	MSN_REAUTHING = 8,
 } msn_flags_t;
 
@@ -103,5 +104,5 @@
 	struct im_connection *ic;
 	
-	struct msn_handler_data ns[1], auth[1];
+	struct msn_handler_data ns[1];
 	msn_flags_t flags;
 	
Index: protocols/msn/ns.c
===================================================================
--- protocols/msn/ns.c	(revision 4aa8a046968bff0a08dc5ae96e228861fa21fcbe)
+++ protocols/msn/ns.c	(revision 27053b516db4d0e648d666e6d9e36856af428775)
@@ -275,9 +275,4 @@
 			md->pp_policy = g_strdup( cmd[4] );
 			msn_soap_passport_sso_request( ic, cmd[5] );
-			if( handler == md->auth )
-			{
-				msn_ns_close( md->auth );
-				return 0;
-			}
 		}
 		else if( strcmp( cmd[2], "OK" ) == 0 )
Index: protocols/msn/soap.c
===================================================================
--- protocols/msn/soap.c	(revision 4aa8a046968bff0a08dc5ae96e228861fa21fcbe)
+++ protocols/msn/soap.c	(revision 27053b516db4d0e648d666e6d9e36856af428775)
@@ -48,4 +48,5 @@
 	MSN_SOAP_OK,
 	MSN_SOAP_RETRY,
+	MSN_SOAP_REAUTH,
 	MSN_SOAP_ABORT,
 } msn_soap_result_t;
@@ -134,4 +135,6 @@
 	}
 	
+	msn_soap_debug_print( http_req->reply_headers, http_req->reply_body );
+	
 	if( http_req->body_size > 0 )
 	{
@@ -143,14 +146,13 @@
 		if( http_req->status_code == 500 &&
 		    ( err = xt_find_path( parser->root, "soap:Body/soap:Fault/detail/errorcode" ) ) &&
-		    err->text_len > 0 && strcmp( err->text, "PassportAuthFail" ) == 0 )
+		    err->text_len > 0 )
 		{
-			struct msn_data *md = soap_req->ic->proto_data;
-			
-			xt_free( parser );
-			if( md->auth->fd == -1 )
-				msn_ns_connect( soap_req->ic, md->auth, MSN_NS_HOST, MSN_NS_PORT );
-			md->soapq = g_slist_prepend( md->soapq, soap_req );
-			
-			return;
+			if( strcmp( err->text, "PassportAuthFail" ) == 0 )
+			{
+				xt_free( parser );
+				st = MSN_SOAP_REAUTH;
+				goto fail;
+			}
+			/* TODO: Handle/report other errors. */
 		}
 		
@@ -159,8 +161,7 @@
 	}
 	
-	msn_soap_debug_print( http_req->reply_headers, http_req->reply_body );
-	
 	st = soap_req->handle_response( soap_req );
-	
+
+fail:	
 	g_free( soap_req->url );
 	g_free( soap_req->action );
@@ -169,5 +170,19 @@
 	
 	if( st == MSN_SOAP_RETRY && --soap_req->ttl )
+	{
 		msn_soap_send_request( soap_req );
+	}
+	else if( st == MSN_SOAP_REAUTH )
+	{
+		struct msn_data *md = soap_req->ic->proto_data;
+		
+		if( !( md->flags & MSN_REAUTHING ) )
+		{
+			/* Nonce shouldn't actually be touched for re-auths. */
+			msn_soap_passport_sso_request( soap_req->ic, "blaataap" );
+			md->flags |= MSN_REAUTHING; 
+		}
+		md->soapq = g_slist_append( md->soapq, soap_req );
+	}
 	else
 	{
@@ -242,5 +257,4 @@
 static int msn_soap_passport_sso_build_request( struct msn_soap_req_data *soap_req )
 {
-	struct msn_soap_passport_sso_data *sd = soap_req->data;
 	struct im_connection *ic = soap_req->ic;
 	struct msn_data *md = ic->proto_data;
@@ -423,5 +437,5 @@
 	char *msg;
 	int number;
-	int need_retry;
+	msn_soap_result_t need_retry;
 };
 
@@ -444,9 +458,10 @@
 	
 	g_free( display_name_b64 );
-	
-	return MSN_SOAP_OK;
-}
-
-static xt_status msn_soap_oim_send_challenge( struct xt_node *node, gpointer data )
+	oim->need_retry = MSN_SOAP_OK;
+	
+	return MSN_SOAP_OK;
+}
+
+static xt_status msn_soap_oim_reauth( struct xt_node *node, gpointer data )
 {
 	struct msn_soap_req_data *soap_req = data;
@@ -454,9 +469,16 @@
 	struct im_connection *ic = soap_req->ic;
 	struct msn_data *md = ic->proto_data;
-	
-	g_free( md->lock_key );
-	md->lock_key = msn_p11_challenge( node->text );
-	
-	oim->need_retry = 1;
+	struct xt_node *c;
+	
+	if( ( c = xt_find_node( node->children, "LockKeyChallenge" ) ) && c->text_len > 0 )
+	{
+		g_free( md->lock_key );
+		md->lock_key = msn_p11_challenge( c->text );
+		oim->need_retry = MSN_SOAP_RETRY;
+	}
+	if( xt_find_node( node->children, "RequiredAuthPolicy" ) )
+	{
+		oim->need_retry = MSN_SOAP_REAUTH;
+	}
 	
 	return XT_HANDLED;
@@ -464,6 +486,6 @@
 
 static const struct xt_handler_entry msn_soap_oim_send_parser[] = {
-	{ "LockKeyChallenge", "detail", msn_soap_oim_send_challenge },
-	{ NULL,               NULL,     NULL                        }
+	{ "detail", "soap:Fault", msn_soap_oim_reauth },
+	{ NULL,     NULL,         NULL                }
 };
 
@@ -474,6 +496,5 @@
 	if( soap_req->http_req->status_code == 500 && oim->need_retry && soap_req->ttl > 0 )
 	{
-		oim->need_retry = 0;
-		return MSN_SOAP_RETRY;
+		return oim->need_retry;
 	}
 	else if( soap_req->http_req->status_code == 200 )
Index: protocols/msn/soap.h
===================================================================
--- protocols/msn/soap.h	(revision 4aa8a046968bff0a08dc5ae96e228861fa21fcbe)
+++ protocols/msn/soap.h	(revision 27053b516db4d0e648d666e6d9e36856af428775)
@@ -126,5 +126,5 @@
                "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI_SSL\"></wsse:PolicyReference>" \
            "</wst:RequestSecurityToken>" \
-           "<wst:RequestSecurityToken Id=\"RST3\">" \
+           "<wst:RequestSecurityToken Id=\"RST4\">" \
                "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \
                "<wsp:AppliesTo>" \
