Index: protocols/msn/Makefile
===================================================================
--- protocols/msn/Makefile	(revision 21029d0fe2b7b11512d2cc67495d590e9df53f85)
+++ protocols/msn/Makefile	(revision e5a8118236442d51eb202a8bdebe5866449554e4)
@@ -10,5 +10,5 @@
 
 # [SH] Program variables
-objects = msn.o msn_util.o ns.o passport.o sb.o tables.o
+objects = msn.o msn_util.o ns.o passport.o sb.o soap.o tables.o
 
 CFLAGS += -Wall
Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision 21029d0fe2b7b11512d2cc67495d590e9df53f85)
+++ protocols/msn/msn.c	(revision e5a8118236442d51eb202a8bdebe5866449554e4)
@@ -99,4 +99,6 @@
 			g_free( md->grouplist[--md->groupcount] );
 		g_free( md->grouplist );
+		
+		g_free( md->passport_token );
 		
 		g_free( md );
Index: protocols/msn/msn.h
===================================================================
--- protocols/msn/msn.h	(revision 21029d0fe2b7b11512d2cc67495d590e9df53f85)
+++ protocols/msn/msn.h	(revision e5a8118236442d51eb202a8bdebe5866449554e4)
@@ -42,6 +42,9 @@
 
 /* This should be MSN Messenger 7.0.0813 */
-#define MSNP11_PROD_KEY "CFHUR$52U_{VIX5T"
-#define MSNP11_PROD_ID  "PROD0101{0RM?UBW"
+//#define MSNP11_PROD_KEY "CFHUR$52U_{VIX5T"
+//#define MSNP11_PROD_ID  "PROD0101{0RM?UBW"
+
+#define MSNP11_PROD_KEY "O4BG@C7BWLYQX?5G"
+#define MSNP11_PROD_ID  "PROD01065C%ZFN6F"
 
 #define MSN_SB_NEW         -24062002
@@ -68,4 +71,6 @@
 	
 	int trId;
+	char *passport_token;
+	char *lock_key;
 	
 	GSList *msgq;
Index: protocols/msn/ns.c
===================================================================
--- protocols/msn/ns.c	(revision 21029d0fe2b7b11512d2cc67495d590e9df53f85)
+++ protocols/msn/ns.c	(revision e5a8118236442d51eb202a8bdebe5866449554e4)
@@ -737,4 +737,6 @@
 		char buf[1024];
 		
+		md->passport_token = g_strdup( mad->token );
+		
 		g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, mad->token );
 		msn_write( ic, buf, strlen( buf ) );
Index: protocols/msn/sb.c
===================================================================
--- protocols/msn/sb.c	(revision 21029d0fe2b7b11512d2cc67495d590e9df53f85)
+++ protocols/msn/sb.c	(revision e5a8118236442d51eb202a8bdebe5866449554e4)
@@ -29,4 +29,5 @@
 #include "passport.h"
 #include "md5.h"
+#include "soap.h"
 
 static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond );
@@ -606,4 +607,15 @@
 		const struct msn_status_code *err = msn_status_by_number( num );
 		
+		if( num == 217 )
+		{
+			GSList *l;
+			
+			for( l = sb->msgq; l; l = l->next )
+			{
+				struct msn_message *m = l->data;
+				msn_soap_oim_send( ic, m->who, m->text );
+			}
+		}
+		
 		imcb_error( ic, "Error reported by switchboard server: %s", err->text );
 		
Index: protocols/msn/soap.c
===================================================================
--- protocols/msn/soap.c	(revision e5a8118236442d51eb202a8bdebe5866449554e4)
+++ protocols/msn/soap.c	(revision e5a8118236442d51eb202a8bdebe5866449554e4)
@@ -0,0 +1,216 @@
+/** soap.c
+ *
+ * SOAP-related functions. Some manager at Microsoft apparently thought
+ * MSNP wasn't XMLy enough so someone stepped up and changed that. This
+ * is the result.
+ *
+ * Copyright (C) 2010 Wilmer van der Gaast <wilmer@gaast.net>
+ *
+ * This program is free software; you can redistribute it and/or modify             
+ * it under the terms of the GNU General Public License version 2                   
+ * as published by the Free Software Foundation                                     
+ *                                                                                   
+ * This program is distributed in the hope that is will be useful,                  
+ * bit WITHOU ANY WARRANTY; without even the implied warranty of                   
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    
+ * GNU General Public License for more details.                                     
+ *                                                                                   
+ * You should have received a copy of the GNU General Public License                
+ * along with this program; if not, write to the Free Software                      
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA          
+ *
+ */
+
+#include "http_client.h"
+#include "soap.h"
+#include "msn.h"
+#include "bitlbee.h"
+#include "url.h"
+#include "misc.h"
+#include "base64.h"
+#include "xmltree.h"
+#include <ctype.h>
+#include <errno.h>
+
+typedef enum
+{
+	MSN_SOAP_OK,
+	MSN_SOAP_RETRY,
+	MSN_SOAP_ABORT,
+} msn_soap_result_t;
+
+struct msn_soap_req_data;
+
+typedef int (*msn_soap_func) ( struct msn_soap_req_data * );
+
+struct msn_soap_req_data
+{
+	void *data;
+	struct im_connection *ic;
+	int ttl;
+	
+	char *url, *action, *payload;
+	struct http_request *http_req;
+	
+	const struct xt_handler_entry *xml_parser;
+	msn_soap_func build_request, handle_response, free_data;
+};
+
+struct msn_soap_oim_send_data
+{
+	char *to;
+	char *msg;
+	int number;
+	int need_retry;
+};
+
+static int msn_soap_send_request( struct msn_soap_req_data *req );
+
+static int msn_soap_start( struct im_connection *ic,
+                    void *data,
+                    msn_soap_func build_request,
+                    const struct xt_handler_entry *xml_parser,
+                    msn_soap_func handle_response,
+                    msn_soap_func free_data )
+{
+	struct msn_soap_req_data *req = g_new0( struct msn_soap_req_data, 1 );
+	
+	req->ic = ic;
+	req->data = data;
+	req->xml_parser = xml_parser;
+	req->build_request = build_request;
+	req->handle_response = handle_response;
+	req->free_data = free_data;
+	req->ttl = 3;
+	
+	return msn_soap_send_request( req );
+}
+
+static void msn_soap_handle_response( struct http_request *http_req );
+
+static int msn_soap_send_request( struct msn_soap_req_data *soap_req )
+{
+	char *http_req;
+	url_t url;
+	
+	soap_req->build_request( soap_req );
+	
+	url_set( &url, soap_req->url );
+	http_req = g_strdup_printf( SOAP_HTTP_REQUEST, url.file, url.host,
+		soap_req->action, strlen( soap_req->payload ), soap_req->payload );
+	
+	soap_req->http_req = http_dorequest( url.host, url.port, url.proto == PROTO_HTTPS,
+		http_req, msn_soap_handle_response, soap_req );
+	
+	return soap_req->http_req != NULL;
+}
+
+static void msn_soap_handle_response( struct http_request *http_req )
+{
+	struct msn_soap_req_data *soap_req = http_req->data;
+	int st;
+	
+	if( http_req->body_size > 0 )
+	{
+		struct xt_parser *parser;
+		
+		parser = xt_new( soap_req->xml_parser, soap_req );
+		xt_feed( parser, http_req->reply_body, http_req->body_size );
+		xt_handle( parser, NULL, -1 );
+		xt_free( parser );
+	}
+	
+	st = soap_req->handle_response( soap_req );
+	
+	if( st == MSN_SOAP_RETRY && --soap_req->ttl )
+		msn_soap_send_request( soap_req );
+	else
+	{
+		soap_req->free_data( soap_req );
+		g_free( soap_req->url );
+		g_free( soap_req->action );
+		g_free( soap_req->payload );
+		g_free( soap_req );
+	}
+}
+
+static int msn_soap_oim_build_request( struct msn_soap_req_data *soap_req )
+{
+	struct msn_soap_oim_send_data *oim = soap_req->data;
+	struct im_connection *ic = soap_req->ic;
+	struct msn_data *md = ic->proto_data;
+	char *display_name_b64;
+	
+	display_name_b64 = tobase64( ic->displayname );
+	
+	soap_req->url = g_strdup( SOAP_OIM_SEND_URL );
+	soap_req->action = g_strdup( SOAP_OIM_ACTION_URL );
+	soap_req->payload = g_markup_printf_escaped( SOAP_OIM_SEND_PAYLOAD,
+		ic->acc->user, display_name_b64, oim->to, md->passport_token,
+		MSNP11_PROD_ID, md->lock_key ? : "", oim->number, oim->number, oim->msg );
+	
+	g_free( display_name_b64 );
+	
+	return 1;
+}
+
+static xt_status msn_soap_oim_send_challenge( struct xt_node *node, gpointer data )
+{
+	struct msn_soap_req_data *soap_req = data;
+	struct msn_soap_oim_send_data *oim = soap_req->data;
+	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;
+	
+	return XT_HANDLED;
+}
+
+static const struct xt_handler_entry msn_soap_oim_send_parser[] = {
+	{ "LockKeyChallenge", "detail", msn_soap_oim_send_challenge },
+	{ NULL,               NULL,     NULL                        }
+};
+
+static int msn_soap_oim_handle_response( struct msn_soap_req_data *soap_req )
+{
+	struct msn_soap_oim_send_data *oim = soap_req->data;
+	
+	if( soap_req->http_req->status_code == 500 && oim->need_retry )
+	{
+		oim->need_retry = 0;
+		return MSN_SOAP_RETRY;
+	}
+	else if( soap_req->http_req->status_code == 200 )
+		return MSN_SOAP_OK;
+	else
+		return MSN_SOAP_ABORT;
+}
+
+static int msn_soap_oim_free_data( struct msn_soap_req_data *soap_req )
+{
+	struct msn_soap_oim_send_data *oim = soap_req->data;
+	
+	g_free( oim->to );
+	g_free( oim->msg );
+	g_free( oim );
+	
+	return 0;
+}
+
+int msn_soap_oim_send( struct im_connection *ic, const char *to, const char *msg )
+{
+	struct msn_soap_oim_send_data *data;
+	
+	data = g_new0( struct msn_soap_oim_send_data, 1 );
+	data->to = g_strdup( to );
+	data->msg = tobase64( msg );
+	data->number = 1;
+	
+	return msn_soap_start( ic, data, msn_soap_oim_build_request,
+	                                 msn_soap_oim_send_parser,
+	                                 msn_soap_oim_handle_response,
+	                                 msn_soap_oim_free_data );
+}
Index: protocols/msn/soap.h
===================================================================
--- protocols/msn/soap.h	(revision e5a8118236442d51eb202a8bdebe5866449554e4)
+++ protocols/msn/soap.h	(revision e5a8118236442d51eb202a8bdebe5866449554e4)
@@ -0,0 +1,85 @@
+/* soap.h
+ *
+ * SOAP-related functions. Some manager at Microsoft apparently thought
+ * MSNP wasn't XMLy enough so someone stepped up and changed that. This
+ * is the result.
+ *
+ * Copyright (C) 2010 Wilmer van der Gaast <wilmer@gaast.net>
+ *
+ * This program is free software; you can redistribute it and/or modify             
+ * it under the terms of the GNU General Public License version 2                   
+ * as published by the Free Software Foundation                                     
+ *                                                                                   
+ * This program is distributed in the hope that is will be useful,                  
+ * bit WITHOU ANY WARRANTY; without even the implied warranty of                   
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    
+ * GNU General Public License for more details.                                     
+ *                                                                                   
+ * You should have received a copy of the GNU General Public License                
+ * along with this program; if not, write to the Free Software                      
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA          
+ */
+
+/* Thanks to http://msnpiki.msnfanatic.com/ for lots of info on this! */
+
+#ifndef __SOAP_H__
+#define __SOAP_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#endif
+#include "nogaim.h"
+
+
+#define SOAP_HTTP_REQUEST \
+"POST %s HTTP/1.0\r\n" \
+"Host: %s\r\n" \
+"Accept: */*\r\n" \
+"SOAPAction: \"%s\"\r\n" \
+"User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \
+"Content-Type: text/xml; charset=utf-8\r\n" \
+"Content-Length: %d\r\n" \
+"Cache-Control: no-cache\r\n" \
+"\r\n" \
+"%s"
+
+
+#define SOAP_OIM_SEND_URL "https://ows.messenger.msn.com/OimWS/oim.asmx"
+#define SOAP_OIM_ACTION_URL "http://messenger.msn.com/ws/2004/09/oim/Store"
+
+#define SOAP_OIM_SEND_PAYLOAD \
+"<?xml version=\"1.0\" encoding=\"utf-8\"?>" \
+"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
+"<soap:Header>" \
+  "<From memberName=\"%s\" friendlyName=\"=?utf-8?B?%s?=\" xml:lang=\"nl-nl\" proxy=\"MSNMSGR\" xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\" msnpVer=\"MSNP13\" buildVer=\"8.0.0328\"/>" \
+  "<To memberName=\"%s\" xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\"/>" \
+  "<Ticket passport=\"%s\" appid=\"%s\" lockkey=\"%s\" xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\"/>" \
+  "<Sequence xmlns=\"http://schemas.xmlsoap.org/ws/2003/03/rm\">" \
+    "<Identifier xmlns=\"http://schemas.xmlsoap.org/ws/2002/07/utility\">http://messenger.msn.com</Identifier>" \
+    "<MessageNumber>%d</MessageNumber>" \
+  "</Sequence>" \
+"</soap:Header>" \
+"<soap:Body>" \
+  "<MessageType xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\">text</MessageType>" \
+  "<Content xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\">MIME-Version: 1.0\r\n" \
+    "Content-Type: text/plain; charset=UTF-8\r\n" \
+    "Content-Transfer-Encoding: base64\r\n" \
+    "X-OIM-Message-Type: OfflineMessage\r\n" \
+    "X-OIM-Run-Id: {89527393-8723-4F4F-8005-287532973298}\r\n" \
+    "X-OIM-Sequence-Num: %d\r\n" \
+    "\r\n" \
+    "%s" \
+  "</Content>" \
+"</soap:Body>" \
+"</soap:Envelope>"
+
+int msn_soap_oim_send( struct im_connection *ic, const char *to, const char *msg );
+
+#endif /* __SOAP_H__ */
