aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordequis <dx@dxzone.com.ar>2018-01-10 00:05:23 -0300
committerdequis <dx@dxzone.com.ar>2018-01-10 00:05:23 -0300
commit7ec2ce8fd7d30a536823ef9e08a3dad80ce76d4e (patch)
tree15f0ad9918bd45898308683f6c549af5fa8e79f4
parent4a9c6b0b15eb3738897dc1635fda2e4be67414ad (diff)
Remove MSN. Use the skypeweb purple plugin instead.
RIP As per http://ismsndeadyet.com/ all versions up to MSNP22 died a few months ago. We had a MSNP21 implementation, bought us two extra years. Implementing MSNP24 is technically possible but also pointless given skypeweb, and the authentication requires some fairly messed up crypto and legacy old-skype-protocol servers. For a long time I tried to reverse a potentially simpler method, and got fairly close, but never completed that. I haven't done any attempts to continue it in the last year, so I'm fine with giving up at this point.
-rwxr-xr-xconfigure11
-rw-r--r--doc/user-guide/Installation.xml5
-rw-r--r--doc/user-guide/commands.xml46
-rw-r--r--doc/user-guide/misc.xml51
-rw-r--r--doc/user-guide/quickstart.xml4
-rw-r--r--protocols/msn/Makefile46
-rw-r--r--protocols/msn/gw.c223
-rw-r--r--protocols/msn/msn.c372
-rw-r--r--protocols/msn/msn.h254
-rw-r--r--protocols/msn/msn_util.c424
-rw-r--r--protocols/msn/ns.c779
-rw-r--r--protocols/msn/soap.c1032
-rw-r--r--protocols/msn/soap.h341
-rw-r--r--protocols/msn/tables.c162
-rw-r--r--protocols/nogaim.c5
15 files changed, 8 insertions, 3747 deletions
diff --git a/configure b/configure
index e2357815..3f1769df 100755
--- a/configure
+++ b/configure
@@ -32,7 +32,6 @@ configure_args="$@"
# If the user sets one of these to 1, purple won't disable them.
# Otherwise, if it's still default-on, it gets included in normal builds,
# but not purple ones.
-msn="default-on"
jabber="default-on"
oscar="default-on"
@@ -129,7 +128,6 @@ Option Description Default
--verbose=0/1 Disable/enable verbose build $verbose
---msn=0/1 Disable/enable MSN part $msn
--jabber=0/1 Disable/enable Jabber part $jabber
--oscar=0/1 Disable/enable Oscar part (ICQ, AIM) $oscar
--twitter=0/1 Disable/enable Twitter part $twitter
@@ -845,7 +843,6 @@ EOF
protoobjs=$protoobjs'purple_mod.o '
# only disable these if the user didn't enable them explicitly
- [ "$msn" = "default-on" ] && msn=0
[ "$jabber" = "default-on" ] && jabber=0
[ "$oscar" = "default-on" ] && oscar=0
@@ -868,14 +865,6 @@ case "$CC" in
done
esac
-if [ "$msn" = 0 ]; then
- echo '#undef WITH_MSN' >> config.h
-else
- echo '#define WITH_MSN' >> config.h
- protocols=$protocols'msn '
- protoobjs=$protoobjs'msn_mod.o '
-fi
-
if [ "$jabber" = 0 ]; then
echo '#undef WITH_JABBER' >> config.h
else
diff --git a/doc/user-guide/Installation.xml b/doc/user-guide/Installation.xml
index 9d555d46..879649f6 100644
--- a/doc/user-guide/Installation.xml
+++ b/doc/user-guide/Installation.xml
@@ -35,7 +35,7 @@ specify them all separately, just specifying prefix (or keeping the default
<listitem><para>config - The place where BitlBee will save all the per-user
settings and buddy information. <filename>/var/lib/bitlbee/</filename>
is the default value.</para></listitem>
-<listitem><para>msn, jabber, oscar, twitter - By default, support for all
+<listitem><para>jabber, oscar, twitter - By default, support for all
these IM-protocols (OSCAR is the protocol used by both ICQ and AIM) will
be compiled in. To make the binary a bit smaller, you can use these options
to leave out support for protocols you're not planning to use.</para></listitem>
@@ -49,8 +49,7 @@ will be stripped out to make it as small as possible. If you don't want this
<listitem><para>flood - To secure your BitlBee server against flooding attacks,
you can use this option. It's not compiled in by default because it needs
more testing first.</para></listitem>
-<listitem><para>ssl - The MSN and Jabber modules require an SSL library for
-some of their tasks. BitlBee can use three different SSL libraries: GnuTLS,
+<listitem><para>ssl - BitlBee can use three different SSL libraries: GnuTLS,
mozilla-nss and OpenSSL. (OpenSSL is, however, a bit troublesome because of
licensing issues, so don't forget to read the information configure will
give you when you try to use OpenSSL!) By default, configure will try to
diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml
index f20e3298..78567bc1 100644
--- a/doc/user-guide/commands.xml
+++ b/doc/user-guide/commands.xml
@@ -42,16 +42,6 @@
</description>
</bitlbee-command>
- <bitlbee-command name="msn">
- <syntax>account add msn &lt;handle@server.tld&gt; [&lt;password&gt;]</syntax>
-
- <description>
- <para>
- For MSN connections there are no special arguments.
- </para>
- </description>
- </bitlbee-command>
-
<bitlbee-command name="oscar">
<syntax>account add oscar &lt;handle&gt; [&lt;password&gt;]</syntax>
@@ -923,13 +913,10 @@
<bitlbee-setting name="display_name" type="string" scope="account">
<description>
<para>
- Currently only available for MSN connections, and for jabber groupchats.
- </para>
- <para>
- For MSN: This setting allows you to read and change your "friendly name" for this connection. Since this is a server-side setting, it can't be changed when the account is off-line.
+ Currently only available for jabber groupchats.
</para>
<para>
- For jabber groupchats: this sets the default value of 'nick' for newly created groupchats. There is no way to set an account-wide nick like MSN.
+ For jabber groupchats: this sets the default value of 'nick' for newly created groupchats. There is no way to set an account-wide nick.
</para>
</description>
</bitlbee-setting>
@@ -1027,17 +1014,6 @@
</bitlbee-setting>
- <bitlbee-setting name="local_display_name" type="boolean" scope="account">
- <default>false</default>
-
- <description>
- <para>
- Mostly meant to work around a bug in MSN servers (forgetting the display name set by the user), this setting tells BitlBee to store your display name locally and set this name on the MSN servers when connecting.
- </para>
- </description>
-
- </bitlbee-setting>
-
<bitlbee-setting name="mail_notifications" type="boolean" scope="account">
<default>false</default>
@@ -1619,24 +1595,6 @@
</description>
</bitlbee-setting>
- <bitlbee-setting name="switchboard_keepalives" type="boolean" scope="account">
- <default>false</default>
-
- <description>
- <para>
- Turn on this flag if you have difficulties talking to offline/invisible contacts.
- </para>
-
- <para>
- With this setting enabled, BitlBee will send keepalives to MSN switchboards with offline/invisible contacts every twenty seconds. This should keep the server and client on the other side from shutting it down.
- </para>
-
- <para>
- This is useful because BitlBee doesn't support MSN offline messages yet and the MSN servers won't let the user reopen switchboards to offline users. Once offline messaging is supported, this flag might be removed.
- </para>
- </description>
- </bitlbee-setting>
-
<bitlbee-setting name="tag" type="string" scope="account">
<description>
<para>
diff --git a/doc/user-guide/misc.xml b/doc/user-guide/misc.xml
index 457d5d35..1201467f 100644
--- a/doc/user-guide/misc.xml
+++ b/doc/user-guide/misc.xml
@@ -1,53 +1,6 @@
<chapter id="misc">
<title>Misc Stuff</title>
-<sect1 id="smileys">
-<title>Smileys</title>
-
-<para>
-All MSN smileys (except one) are case insensitive and work without the nose too.
-</para>
-
-<variablelist>
- <varlistentry><term>(Y)</term><listitem><para>Thumbs up</para></listitem></varlistentry>
- <varlistentry><term>(N)</term><listitem><para>Thumbs down</para></listitem></varlistentry>
- <varlistentry><term>(B)</term><listitem><para>Beer mug</para></listitem></varlistentry>
- <varlistentry><term>(D)</term><listitem><para>Martini glass</para></listitem></varlistentry>
- <varlistentry><term>(X)</term><listitem><para>Girl</para></listitem></varlistentry>
- <varlistentry><term>(Z)</term><listitem><para>Boy</para></listitem></varlistentry>
- <varlistentry><term>(6)</term><listitem><para>Devil smiley</para></listitem></varlistentry>
- <varlistentry><term>:-[</term><listitem><para>Vampire bat</para></listitem></varlistentry>
- <varlistentry><term>(})</term><listitem><para>Right hug</para></listitem></varlistentry>
- <varlistentry><term>({)</term><listitem><para>Left hug</para></listitem></varlistentry>
- <varlistentry><term>(M)</term><listitem><para>MSN Messenger or Windows Messenger icon (think a BitlBee logo here ;)</para></listitem></varlistentry>
- <varlistentry><term>:-S</term><listitem><para>Crooked smiley (Confused smiley)</para></listitem></varlistentry>
- <varlistentry><term>:-$</term><listitem><para>Embarrassed smiley</para></listitem></varlistentry>
- <varlistentry><term>(H)</term><listitem><para>Smiley with sunglasses</para></listitem></varlistentry>
- <varlistentry><term>:-@</term><listitem><para>Angry smiley</para></listitem></varlistentry>
- <varlistentry><term>(A)</term><listitem><para>Angel smiley</para></listitem></varlistentry>
- <varlistentry><term>(L)</term><listitem><para>Red heart (Love)</para></listitem></varlistentry>
- <varlistentry><term>(U)</term><listitem><para>Broken heart</para></listitem></varlistentry>
- <varlistentry><term>(K)</term><listitem><para>Red lips (Kiss)</para></listitem></varlistentry>
- <varlistentry><term>(G)</term><listitem><para>Gift with bow</para></listitem></varlistentry>
- <varlistentry><term>(F)</term><listitem><para>Red rose</para></listitem></varlistentry>
- <varlistentry><term>(W)</term><listitem><para>Wilted rose</para></listitem></varlistentry>
- <varlistentry><term>(P)</term><listitem><para>Camera</para></listitem></varlistentry>
- <varlistentry><term>(~)</term><listitem><para>Film strip</para></listitem></varlistentry>
- <varlistentry><term>(T)</term><listitem><para>Telephone receiver</para></listitem></varlistentry>
- <varlistentry><term>(@)</term><listitem><para>Cat face</para></listitem></varlistentry>
- <varlistentry><term>(&amp;)</term><listitem><para>Dog's head</para></listitem></varlistentry>
- <varlistentry><term>(C)</term><listitem><para>Coffee cup</para></listitem></varlistentry>
- <varlistentry><term>(I)</term><listitem><para>Light bulb</para></listitem></varlistentry>
- <varlistentry><term>(S)</term><listitem><para>Half-moon (Case sensitive!)</para></listitem></varlistentry>
- <varlistentry><term>(*)</term><listitem><para>Star</para></listitem></varlistentry>
- <varlistentry><term>(8)</term><listitem><para>Musical eighth note</para></listitem></varlistentry>
- <varlistentry><term>(E)</term><listitem><para>Envelope</para></listitem></varlistentry>
- <varlistentry><term>(^)</term><listitem><para>Birthday cake</para></listitem></varlistentry>
- <varlistentry><term>(O)</term><listitem><para>Clock</para></listitem></varlistentry>
-</variablelist>
-
-</sect1>
-
<sect1 id="groupchats">
<title>Groupchats</title>
<para>
@@ -152,7 +105,7 @@ Control channels are where you see your contacts. By default, you will have one
</para>
<para>
-For example, you can have one channel with all contacts from your MSN Messenger account in it. Or all contacts from the group called "Work".
+For example, you can have one channel with all contacts from your jabber account in it. Or all contacts from the group called "Work".
</para>
<para>
@@ -169,7 +122,7 @@ When you create a new channel, BitlBee will try to guess from its name which con
</para>
<para>
-Any valid account ID (so a number, protocol name or part of screenname, as long as it's unique) can also be used as a channel name. So if you just join &amp;msn, it will contain all your MSN contacts. And if you have a Facebook account set up, you can see its contacts by just joining &amp;facebook.
+Any valid account ID (so a number, protocol name or part of screenname, as long as it's unique) can also be used as a channel name. So if you just join &amp;jabber, it will contain all your jabber contacts. And if you have a Facebook account set up, you can see its contacts by just joining &amp;facebook.
</para>
<para>
diff --git a/doc/user-guide/quickstart.xml b/doc/user-guide/quickstart.xml
index 2eda6be1..6de9b953 100644
--- a/doc/user-guide/quickstart.xml
+++ b/doc/user-guide/quickstart.xml
@@ -42,7 +42,7 @@ For instance, suppose you have a Jabber account at jabber.org with handle <empha
</ircexample>
<para>
-Other built-in IM protocols include msn, oscar and twitter. OSCAR is the protocol used by ICQ and AOL. Some protocols may be available as plugins that you can install, such as facebook, steam, discord and omegle. And you can get even more protocols by using the libpurple variant of BitlBee.
+Other built-in IM protocols include oscar and twitter. OSCAR is the protocol used by ICQ and AOL. Some protocols may be available as plugins that you can install, such as facebook, steam, discord and omegle. And you can get even more protocols by using the libpurple variant of BitlBee.
</para>
<para>
@@ -123,7 +123,7 @@ You know the basics. If you want to know about some of the neat features BitlBee
</para>
<para>
-With multiple channel support you can have contacts for specific protocols in their own channels, for instance, if you <emphasis>/join &amp;msn</emphasis> you will join a channel that only contains your MSN contacts.
+With multiple channel support you can have contacts for specific protocols in their own channels, for instance, if you <emphasis>/join &amp;jabber</emphasis> you will join a channel that only contains your jabber contacts.
</para>
<para>
diff --git a/protocols/msn/Makefile b/protocols/msn/Makefile
deleted file mode 100644
index 089297f6..00000000
--- a/protocols/msn/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-###########################
-## Makefile for BitlBee ##
-## ##
-## Copyright 2002 Lintux ##
-###########################
-
-### DEFINITIONS
-
--include ../../Makefile.settings
-ifdef _SRCDIR_
-_SRCDIR_ := $(_SRCDIR_)protocols/msn/
-endif
-
-# [SH] Program variables
-objects = msn.o msn_util.o ns.o soap.o tables.o gw.o
-
-LFLAGS += -r
-
-# [SH] Phony targets
-all: msn_mod.o
-check: all
-lcov: check
-gcov:
- gcov *.c
-
-.PHONY: all clean distclean
-
-clean:
- rm -f *.o core
-
-distclean: clean
- rm -rf .depend
-
-### MAIN PROGRAM
-
-$(objects): ../../Makefile.settings Makefile
-
-$(objects): %.o: $(_SRCDIR_)%.c
- @echo '*' Compiling $<
- $(VERBOSE) $(CC) -c $(CFLAGS) $(CFLAGS_BITLBEE) $< -o $@
-
-msn_mod.o: $(objects)
- @echo '*' Linking msn_mod.o
- $(VERBOSE) $(LD) $(LFLAGS) $(objects) -o msn_mod.o
-
--include .depend/*.d
diff --git a/protocols/msn/gw.c b/protocols/msn/gw.c
deleted file mode 100644
index f9cc74fd..00000000
--- a/protocols/msn/gw.c
+++ /dev/null
@@ -1,223 +0,0 @@
-#include "bitlbee.h"
-#include "lib/http_client.h"
-#include "msn.h"
-
-#define GATEWAY_HOST "geo.gateway.messenger.live.com"
-#define GATEWAY_PORT 443
-
-#define REQUEST_TEMPLATE \
- "POST /gateway/gateway.dll?SessionID=%s&%s HTTP/1.1\r\n" \
- "Host: %s\r\n" \
- "Content-Length: %zd\r\n" \
- "\r\n" \
- "%s"
-
-static gboolean msn_gw_poll_timeout(gpointer data, gint source, b_input_condition cond);
-
-struct msn_gw *msn_gw_new(struct im_connection *ic)
-{
- struct msn_gw *gw = g_new0(struct msn_gw, 1);
- gw->last_host = g_strdup(GATEWAY_HOST);
- gw->port = GATEWAY_PORT;
- gw->ssl = (GATEWAY_PORT == 443);
- gw->poll_timeout = -1;
- gw->write_timeout = -1;
- gw->ic = ic;
- gw->md = ic->proto_data;
- gw->in = g_byte_array_new();
- gw->out = g_byte_array_new();
- return gw;
-}
-
-void msn_gw_free(struct msn_gw *gw)
-{
- if (gw->poll_timeout != -1) {
- b_event_remove(gw->poll_timeout);
- }
-
- if (gw->write_timeout != -1) {
- b_event_remove(gw->write_timeout);
- }
-
- g_byte_array_free(gw->in, TRUE);
- g_byte_array_free(gw->out, TRUE);
- g_free(gw->session_id);
- g_free(gw->last_host);
- g_free(gw);
-}
-
-static struct msn_gw *msn_gw_from_ic(struct im_connection *ic)
-{
- if (g_slist_find(msn_connections, ic) == NULL) {
- return NULL;
- } else {
- struct msn_data *md = ic->proto_data;
- return md->gw;
- }
-}
-
-static gboolean msn_gw_parse_session_header(struct msn_gw *gw, char *value)
-{
- int i;
- char **subvalues;
- gboolean closed = FALSE;
-
- subvalues = g_strsplit(value, "; ", 0);
-
- for (i = 0; subvalues[i]; i++) {
- if (strcmp(subvalues[i], "Session=close") == 0) {
- /* gateway closed, signal the death of the socket */
- closed = TRUE;
- } else if (g_str_has_prefix(subvalues[i], "SessionID=")) {
- /* copy the part after the = to session_id*/
- g_free(gw->session_id);
- gw->session_id = g_strdup(subvalues[i] + 10);
- }
- }
-
- g_strfreev(subvalues);
-
- return !closed;
-}
-
-void msn_gw_callback(struct http_request *req)
-{
- struct msn_gw *gw;
- char *value;
-
- if (!(gw = msn_gw_from_ic(req->data))) {
- return;
- }
-
- gw->waiting = FALSE;
- gw->polling = FALSE;
-
- if (req->status_code != 200 || !req->reply_body) {
- gw->callback(gw->md, -1, B_EV_IO_READ);
- return;
- }
-
- if (getenv("BITLBEE_DEBUG")) {
- fprintf(stderr, "\n\x1b[90mHTTP:%s\n", req->reply_body);
- fprintf(stderr, "\n\x1b[97m\n");
- }
-
- if ((value = get_rfc822_header(req->reply_headers, "X-MSN-Messenger", 0))) {
- if (!msn_gw_parse_session_header(gw, value)) {
- gw->callback(gw->md, -1, B_EV_IO_READ);
- g_free(value);
- return;
- }
- g_free(value);
- }
-
- if ((value = get_rfc822_header(req->reply_headers, "X-MSN-Host", 0))) {
- g_free(gw->last_host);
- gw->last_host = value; /* transfer */
- }
-
- if (req->body_size) {
- g_byte_array_append(gw->in, (const guint8 *) req->reply_body, req->body_size);
-
- if (!gw->callback(gw->md, -1, B_EV_IO_READ)) {
- return;
- }
- }
-
- if (gw->poll_timeout != -1) {
- b_event_remove(gw->poll_timeout);
- }
- gw->poll_timeout = b_timeout_add(500, msn_gw_poll_timeout, gw->ic);
-
-}
-
-void msn_gw_dorequest(struct msn_gw *gw, char *args)
-{
- char *request = NULL;
- char *body = NULL;
- size_t bodylen = 0;
-
- if (gw->out) {
- bodylen = gw->out->len;
- g_byte_array_append(gw->out, (guint8 *) "", 1); /* nullnullnull */
- body = (char *) g_byte_array_free(gw->out, FALSE);
- gw->out = g_byte_array_new();
- }
-
- if (!bodylen && !args) {
- args = "Action=poll&Lifespan=60";
- gw->polling = TRUE;
- }
-
- request = g_strdup_printf(REQUEST_TEMPLATE,
- gw->session_id ? : "", args ? : "", gw->last_host, bodylen, body ? : "");
-
- http_dorequest(gw->last_host, gw->port, gw->ssl, request, msn_gw_callback, gw->ic);
- gw->open = TRUE;
- gw->waiting = TRUE;
-
- g_free(body);
- g_free(request);
-}
-
-void msn_gw_open(struct msn_gw *gw)
-{
- msn_gw_dorequest(gw, "Action=open&Server=NS");
-}
-
-static gboolean msn_gw_poll_timeout(gpointer data, gint source, b_input_condition cond)
-{
- struct msn_gw *gw;
-
- if (!(gw = msn_gw_from_ic(data))) {
- return FALSE;
- }
-
- gw->poll_timeout = -1;
- if (!gw->waiting) {
- msn_gw_dorequest(gw, NULL);
- }
- return FALSE;
-}
-
-ssize_t msn_gw_read(struct msn_gw *gw, char **buf)
-{
- size_t bodylen;
- if (!gw->open) {
- return 0;
- }
-
- bodylen = gw->in->len;
- g_byte_array_append(gw->in, (guint8 *) "", 1); /* nullnullnull */
- *buf = (char *) g_byte_array_free(gw->in, FALSE);
- gw->in = g_byte_array_new();
- return bodylen;
-}
-
-static gboolean msn_gw_write_cb(gpointer data, gint source, b_input_condition cond)
-{
- struct msn_gw *gw;
-
- if (!(gw = msn_gw_from_ic(data))) {
- return FALSE;
- }
-
- if (!gw->open) {
- msn_gw_open(gw);
- } else if (gw->polling || !gw->waiting) {
- msn_gw_dorequest(gw, NULL);
- }
-
- gw->write_timeout = -1;
- return FALSE;
-}
-
-void msn_gw_write(struct msn_gw *gw, char *buf, size_t len)
-{
- g_byte_array_append(gw->out, (const guint8 *) buf, len);
-
- /* do a bit of buffering here to send several commands with a single request */
- if (gw->write_timeout == -1) {
- gw->write_timeout = b_timeout_add(1, msn_gw_write_cb, gw->ic);
- }
-}
diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c
deleted file mode 100644
index 8d3e7787..00000000
--- a/protocols/msn/msn.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/********************************************************************\
- * BitlBee -- An IRC to other IM-networks gateway *
- * *
- * Copyright 2002-2013 Wilmer van der Gaast and others *
- \********************************************************************/
-
-/* MSN module - Main file; functions to be called from BitlBee */
-
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT 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 with
- the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
- if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
- Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include "nogaim.h"
-#include "soap.h"
-#include "msn.h"
-
-int msn_chat_id;
-GSList *msn_connections;
-
-static char *set_eval_display_name(set_t *set, char *value);
-
-static void msn_init(account_t *acc)
-{
- set_t *s;
-
- s = set_add(&acc->set, "display_name", NULL, set_eval_display_name, acc);
- s->flags |= SET_NOSAVE | ACC_SET_ONLINE_ONLY;
-
- s = set_add(&acc->set, "server", NULL, set_eval_account, acc);
- s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
-
- s = set_add(&acc->set, "port", MSN_NS_PORT, set_eval_int, acc);
- s->flags |= ACC_SET_OFFLINE_ONLY;
-
- s = set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
- s->flags |= ACC_SET_OFFLINE_ONLY;
-
- s = set_add(&acc->set, "mail_notifications_handle", NULL, NULL, acc);
- s->flags |= ACC_SET_OFFLINE_ONLY | SET_NULL_OK;
-
- acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
- ACC_FLAG_HANDLE_DOMAINS;
-}
-
-static void msn_login(account_t *acc)
-{
- struct im_connection *ic = imcb_new(acc);
- struct msn_data *md = g_new0(struct msn_data, 1);
- char *server = set_getstr(&ic->acc->set, "server");
-
- ic->proto_data = md;
- ic->flags |= OPT_PONGS | OPT_PONGED;
-
- if (!server) {
- server = "geo.gateway.messenger.live.com";
- }
-
- if (strchr(acc->user, '@') == NULL) {
- imcb_error(ic, "Invalid account name");
- imc_logout(ic, FALSE);
- return;
- }
-
- md->ic = ic;
- md->away_state = msn_away_state_list;
- md->domaintree = g_tree_new(msn_domaintree_cmp);
- md->fd = -1;
- md->is_http = TRUE;
-
- msn_connections = g_slist_prepend(msn_connections, ic);
-
- imcb_log(ic, "Connecting");
- msn_ns_connect(ic, server,
- set_getint(&ic->acc->set, "port"));
-
- if (set_getbool(&acc->set, "mail_notifications") && set_getstr(&acc->set, "mail_notifications_handle")) {
- imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL);
- }
-}
-
-static void msn_logout(struct im_connection *ic)
-{
- struct msn_data *md = ic->proto_data;
- GSList *l;
- int i;
-
- if (md) {
- msn_ns_close(md);
-
- msn_soapq_flush(ic, FALSE);
-
- for (i = 0; i < sizeof(md->tokens) / sizeof(md->tokens[0]); i++) {
- g_free(md->tokens[i]);
- }
- g_free(md->lock_key);
- g_free(md->pp_policy);
- g_free(md->uuid);
-
- while (md->groups) {
- struct msn_group *mg = md->groups->data;
- md->groups = g_slist_remove(md->groups, mg);
- g_free(mg->id);
- g_free(mg->name);
- g_free(mg);
- }
-
- g_free(md->profile_rid);
-
- if (md->domaintree) {
- g_tree_destroy(md->domaintree);
- }
- md->domaintree = NULL;
-
- while (md->grpq) {
- struct msn_groupadd *ga = md->grpq->data;
- md->grpq = g_slist_remove(md->grpq, ga);
- g_free(ga->group);
- g_free(ga->who);
- g_free(ga);
- }
-
- g_free(md);
- }
-
- for (l = ic->permit; l; l = l->next) {
- g_free(l->data);
- }
- g_slist_free(ic->permit);
-
- for (l = ic->deny; l; l = l->next) {
- g_free(l->data);
- }
- g_slist_free(ic->deny);
-
- msn_connections = g_slist_remove(msn_connections, ic);
-}
-
-static int msn_buddy_msg(struct im_connection *ic, char *who, char *message, int away)
-{
- struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who);
- msn_ns_send_message(ic, bu, message);
- return 0;
-}
-
-static GList *msn_away_states(struct im_connection *ic)
-{
- static GList *l = NULL;
- int i;
-
- if (l == NULL) {
- for (i = 0; *msn_away_state_list[i].code; i++) {
- if (*msn_away_state_list[i].name) {
- l = g_list_append(l, (void *) msn_away_state_list[i].name);
- }
- }
- }
-
- return l;
-}
-
-static void msn_set_away(struct im_connection *ic, char *state, char *message)
-{
- struct msn_data *md = ic->proto_data;
- char *nick, *psm, *idle, *statecode, *body, *buf;
-
- if (state == NULL) {
- md->away_state = msn_away_state_list;
- } else if ((md->away_state = msn_away_state_by_name(state)) == NULL) {
- md->away_state = msn_away_state_list + 1;
- }
-
- statecode = (char *) md->away_state->code;
- nick = set_getstr(&ic->acc->set, "display_name");
- psm = message ? message : "";
- idle = (strcmp(statecode, "IDL") == 0) ? "false" : "true";
-
- body = g_markup_printf_escaped(MSN_PUT_USER_BODY,
- nick, psm, psm, md->uuid, statecode, md->uuid, idle, statecode,
- MSN_CAP1, MSN_CAP2, MSN_CAP1, MSN_CAP2
- );
-
- buf = g_strdup_printf(MSN_PUT_HEADERS, ic->acc->user, ic->acc->user, md->uuid,
- "/user", "application/user+xml",
- strlen(body), body);
- msn_ns_write(ic, -1, "PUT %d %zd\r\n%s", ++md->trId, strlen(buf), buf);
-
- g_free(buf);
- g_free(body);
-}
-
-static void msn_get_info(struct im_connection *ic, char *who)
-{
- /* Just make an URL and let the user fetch the info */
- imcb_log(ic, "%s\n%s: %s%s", _("User Info"), _("For now, fetch yourself"), PROFILE_URL, who);
-}
-
-static void msn_add_buddy(struct im_connection *ic, char *who, char *group)
-{
- struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who);
-
- msn_buddy_list_add(ic, MSN_BUDDY_FL, who, who, group);
- if (bu && bu->group) {
- msn_buddy_list_remove(ic, MSN_BUDDY_FL, who, bu->group->name);
- }
-}
-
-static void msn_remove_buddy(struct im_connection *ic, char *who, char *group)
-{
- msn_buddy_list_remove(ic, MSN_BUDDY_FL, who, NULL);
-}
-
-static void msn_chat_msg(struct groupchat *c, char *message, int flags)
-{
- /* TODO: groupchats*/
-}
-
-static void msn_chat_invite(struct groupchat *c, char *who, char *message)
-{
- /* TODO: groupchats*/
-}
-
-static void msn_chat_leave(struct groupchat *c)
-{
- /* TODO: groupchats*/
-}
-
-static struct groupchat *msn_chat_with(struct im_connection *ic, char *who)
-{
- /* TODO: groupchats*/
- struct groupchat *c = imcb_chat_new(ic, who);
- return c;
-}
-
-static void msn_keepalive(struct im_connection *ic)
-{
- msn_ns_write(ic, -1, "PNG\r\n");
-}
-
-static void msn_add_permit(struct im_connection *ic, char *who)
-{
- msn_buddy_list_add(ic, MSN_BUDDY_AL, who, who, NULL);
-}
-
-static void msn_rem_permit(struct im_connection *ic, char *who)
-{
- msn_buddy_list_remove(ic, MSN_BUDDY_AL, who, NULL);
-}
-
-static void msn_add_deny(struct im_connection *ic, char *who)
-{
- msn_buddy_list_add(ic, MSN_BUDDY_BL, who, who, NULL);
-}
-
-static void msn_rem_deny(struct im_connection *ic, char *who)
-{
- msn_buddy_list_remove(ic, MSN_BUDDY_BL, who, NULL);
-}
-
-static int msn_send_typing(struct im_connection *ic, char *who, int typing)
-{
- struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who);
-
- if (!(bu->flags & BEE_USER_ONLINE)) {
- return 0;
- } else if (typing & OPT_TYPING) {
- return msn_ns_send_typing(ic, bu);
- } else {
- return 1;
- }
-}
-
-static char *set_eval_display_name(set_t *set, char *value)
-{
- account_t *acc = set->data;
- struct im_connection *ic = acc->ic;
- struct msn_data *md = ic->proto_data;
-
- if (md->flags & MSN_EMAIL_UNVERIFIED) {
- imcb_log(ic, "Warning: Your e-mail address is unverified. MSN doesn't allow "
- "changing your display name until your e-mail address is verified.");
- }
-
- if (md->flags & MSN_GOT_PROFILE_DN) {
- msn_soap_profile_set_dn(ic, value);
- } else {
- msn_soap_addressbook_set_display_name(ic, value);
- }
-
- return msn_ns_set_display_name(ic, value) ? value : NULL;
-}
-
-static void msn_buddy_data_add(bee_user_t *bu)
-{
- struct msn_data *md = bu->ic->proto_data;
- struct msn_buddy_data *bd;
- char *handle;
-
- bd = bu->data = g_new0(struct msn_buddy_data, 1);
- g_tree_insert(md->domaintree, bu->handle, bu);
-
- for (handle = bu->handle; g_ascii_isdigit(*handle); handle++) {
- ;
- }
- if (*handle == ':') {
- /* Pass a nick hint so hopefully the stupid numeric prefix
- won't show up to the user. */
- char *s = strchr(++handle, '@');
- if (s) {
- handle = g_strndup(handle, s - handle);
- imcb_buddy_nick_hint(bu->ic, bu->handle, handle);
- g_free(handle);
- }
-
- bd->flags |= MSN_BUDDY_FED;
- }
-}
-
-static void msn_buddy_data_free(bee_user_t *bu)
-{
- struct msn_data *md = bu->ic->proto_data;
- struct msn_buddy_data *bd = bu->data;
-
- g_free(bd->cid);
- g_free(bd);
-
- g_tree_remove(md->domaintree, bu->handle);
-}
-
-void msn_initmodule()
-{
- struct prpl *ret = g_new0(struct prpl, 1);
-
- ret->name = "msn";
- ret->mms = 1409; /* this guess taken from libotr UPGRADING file */
- ret->login = msn_login;
- ret->init = msn_init;
- ret->logout = msn_logout;
- ret->buddy_msg = msn_buddy_msg;
- ret->away_states = msn_away_states;
- ret->set_away = msn_set_away;
- ret->get_info = msn_get_info;
- ret->add_buddy = msn_add_buddy;
- ret->remove_buddy = msn_remove_buddy;
- ret->chat_msg = msn_chat_msg;
- ret->chat_invite = msn_chat_invite;
- ret->chat_leave = msn_chat_leave;
- ret->chat_with = msn_chat_with;
- ret->keepalive = msn_keepalive;
- ret->add_permit = msn_add_permit;
- ret->rem_permit = msn_rem_permit;
- ret->add_deny = msn_add_deny;
- ret->rem_deny = msn_rem_deny;
- ret->send_typing = msn_send_typing;
- ret->handle_cmp = g_strcasecmp;
- ret->buddy_data_add = msn_buddy_data_add;
- ret->buddy_data_free = msn_buddy_data_free;
-
- register_protocol(ret);
-}
diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h
deleted file mode 100644
index b2e7995d..00000000
--- a/protocols/msn/msn.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/********************************************************************\
- * BitlBee -- An IRC to other IM-networks gateway *
- * *
- * Copyright 2002-2012 Wilmer van der Gaast and others *
- \********************************************************************/
-
-/* MSN module */
-
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT 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 with
- the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
- if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
- Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef _MSN_H
-#define _MSN_H
-
-/* This should be MSN Messenger 7.0.0813
-#define MSNP11_PROD_KEY "CFHUR$52U_{VIX5T"
-#define MSNP11_PROD_ID "PROD0101{0RM?UBW"
-*/
-
-#define MSN_NS_HOST "messenger.hotmail.com"
-#define MSN_NS_PORT "1863"
-
-/* Some other version.
-#define MSNP11_PROD_KEY "O4BG@C7BWLYQX?5G"
-#define MSNP11_PROD_ID "PROD01065C%ZFN6F"
-*/
-
-/* <= BitlBee 3.0.5
-#define MSNP11_PROD_KEY "ILTXC!4IXB5FB*PX"
-#define MSNP11_PROD_ID "PROD0119GSJUC$18"
-*/
-
-#define MSNP11_PROD_KEY "C1BX{V4W}Q3*10SM"
-#define MSNP11_PROD_ID "PROD0120PW!CCV9@"
-#define MSNP_VER "MSNP21"
-#define MSNP_BUILD "14.0.8117.416"
-
-#define MSN_SB_NEW -24062002
-
-#define MSN_CAP1 0xC000
-#define MSN_CAP2 0x0000
-
-#define MSN_BASE_HEADERS \
- "Routing: 1.0\r\n" \
- "To: 1:%s\r\n" \
- "From: 1:%s;epid={%s}\r\n" \
- "\r\n" \
- "Reliability: 1.0\r\n" \
- "\r\n"
-
-#define MSN_MESSAGE_HEADERS MSN_BASE_HEADERS \
- "Messaging: 2.0\r\n" \
- "Message-Type: %s\r\n" \
- "Content-Length: %zd\r\n" \
- "Content-Type: text/plain; charset=UTF-8\r\n" \
- "X-MMS-IM-Format: FN=Segoe%%20UI; EF=; CO=0; CS=0; PF=0\r\n" \
- "\r\n" \
- "%s"
-
-#define MSN_PUT_HEADERS MSN_BASE_HEADERS \
- "Publication: 1.0\r\n" \
- "Uri: %s\r\n" \
- "Content-Type: %s\r\n" \
- "Content-Length: %zd\r\n" \
- "\r\n" \
- "%s"
-
-#define MSN_PUT_USER_BODY \
- "<user>" \
- "<s n=\"PE\"><UserTileLocation></UserTileLocation><FriendlyName>%s</FriendlyName><PSM>%s</PSM><DDP></DDP>" \
- "<Scene></Scene><ASN></ASN><ColorScheme>-3</ColorScheme><BDG></BDG><RUM>%s</RUM><RUL></RUL><RLT>0</RLT>" \
- "<RID></RID><SUL></SUL><MachineGuid>%s</MachineGuid></s>" \
- "<s n=\"IM\"><Status>%s</Status><CurrentMedia></CurrentMedia></s>" \
- "<sep n=\"PD\"><ClientType>1</ClientType><EpName>%s</EpName><Idle>%s</Idle><State>%s</State></sep>" \
- "<sep n=\"PE\"><VER>BitlBee:" BITLBEE_VERSION "</VER><TYP>1</TYP><Capabilities>%d:%d</Capabilities></sep>" \
- "<sep n=\"IM\"><Capabilities>%d:%d</Capabilities></sep>" \
- "</user>"
-
-#define PROFILE_URL "http://members.msn.com/"
-
-typedef enum {
- MSN_GOT_PROFILE = 1,
- MSN_GOT_PROFILE_DN = 2,
- MSN_DONE_ADL = 4,
- MSN_REAUTHING = 8,
- MSN_EMAIL_UNVERIFIED = 16,
-} msn_flags_t;
-
-struct msn_gw {
- char *last_host;
- int port;
- gboolean ssl;
-
- char *session_id;
-
- GByteArray *in;
- GByteArray *out;
-
- int poll_timeout;
- int write_timeout;
-
- b_event_handler callback;
-
- struct im_connection *ic;
- struct msn_data *md;
-
- gboolean open;
- gboolean waiting;
- gboolean polling;
-};
-
-struct msn_data {
- int fd, inpa;
- int rxlen;
- char *rxq;
-
- int msglen;
- char *cmd_text;
-
- struct im_connection *ic;
-
- msn_flags_t flags;
-
- int trId;
- char *tokens[4];
- char *lock_key, *pp_policy;
- char *uuid;
-
- GSList *msgq, *grpq, *soapq;
-
- const struct msn_away_state *away_state;
- GSList *groups;
- char *profile_rid;
-
- /* Mostly used for sending the ADL command; since MSNP13 the client
- is responsible for downloading the contact list and then sending
- it to the MSNP server. */
- GTree *domaintree;
- int adl_todo;
-
- gboolean is_http;
- struct msn_gw *gw;
-};
-
-struct msn_away_state {
- char code[4];
- char name[16];
-};
-
-struct msn_status_code {
- int number;
- char *text;
- int flags;
-};
-
-struct msn_message {
- char *who;
- char *text;
-};
-
-struct msn_groupadd {
- char *who;
- char *group;
-};
-
-typedef enum {
- MSN_BUDDY_FL = 1, /* Warning: FL,AL,BL *must* be 1,2,4. */
- MSN_BUDDY_AL = 2,
- MSN_BUDDY_BL = 4,
- MSN_BUDDY_RL = 8,
- MSN_BUDDY_PL = 16,
- MSN_BUDDY_ADL_SYNCED = 256,
- MSN_BUDDY_FED = 512,
-} msn_buddy_flags_t;
-
-struct msn_buddy_data {
- char *cid;
- msn_buddy_flags_t flags;
-};
-
-struct msn_group {
- char *name;
- char *id;
-};
-
-/* Bitfield values for msn_status_code.flags */
-#define STATUS_FATAL 1
-#define STATUS_SB_FATAL 2
-
-extern int msn_chat_id;
-extern const struct msn_away_state msn_away_state_list[];
-extern const struct msn_status_code msn_status_code_list[];
-
-/* Keep a list of all the active connections. We need these lists because
- "connected" callbacks might be called when the connection they belong too
- is down already (for example, when an impatient user disabled the
- connection), the callback should check whether it's still listed here
- before doing *anything* else. */
-extern GSList *msn_connections;
-
-/* ns.c */
-int msn_ns_write(struct im_connection *ic, int fd, const char *fmt, ...) G_GNUC_PRINTF(3, 4);
-gboolean msn_ns_connect(struct im_connection *ic, const char *host, int port);
-void msn_ns_close(struct msn_data *handler);
-void msn_auth_got_passport_token(struct im_connection *ic, const char *token, const char *error);
-void msn_auth_got_contact_list(struct im_connection *ic);
-int msn_ns_finish_login(struct im_connection *ic);
-int msn_ns_send_typing(struct im_connection *ic, struct bee_user *bu);
-int msn_ns_send_message(struct im_connection *ic, struct bee_user *bu, const char *text);
-int msn_ns_command(struct msn_data *md, char **cmd, int num_parts);
-int msn_ns_message(struct msn_data *md, char *msg, int msglen, char **cmd, int num_parts);
-
-/* msn_util.c */
-int msn_buddy_list_add(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname_,
- const char *group);
-int msn_buddy_list_remove(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group);
-void msn_buddy_ask(bee_user_t *bu);
-void msn_queue_feed(struct msn_data *h, char *bytes, int st);
-int msn_handler(struct msn_data *h);
-char *msn_p11_challenge(char *challenge);
-gint msn_domaintree_cmp(gconstpointer a_, gconstpointer b_);
-struct msn_group *msn_group_by_name(struct im_connection *ic, const char *name);
-struct msn_group *msn_group_by_id(struct im_connection *ic, const char *id);
-int msn_ns_set_display_name(struct im_connection *ic, const char *value);
-const char *msn_normalize_handle(const char *handle);
-
-/* tables.c */
-const struct msn_away_state *msn_away_state_by_number(int number);
-const struct msn_away_state *msn_away_state_by_code(char *code);
-const struct msn_away_state *msn_away_state_by_name(char *name);
-const struct msn_status_code *msn_status_by_number(int number);
-
-/* gw.c */
-struct msn_gw *msn_gw_new(struct im_connection *ic);
-void msn_gw_free(struct msn_gw *gw);
-void msn_gw_open(struct msn_gw *gw);
-ssize_t msn_gw_read(struct msn_gw *gw, char **buf);
-void msn_gw_write(struct msn_gw *gw, char *buf, size_t len);
-
-#endif //_MSN_H
diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c
deleted file mode 100644
index af00e461..00000000
--- a/protocols/msn/msn_util.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/********************************************************************\
- * BitlBee -- An IRC to other IM-networks gateway *
- * *
- * Copyright 2002-2012 Wilmer van der Gaast and others *
- \********************************************************************/
-
-/* MSN module - Miscellaneous utilities */
-
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT 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 with
- the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
- if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
- Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include "nogaim.h"
-#include "msn.h"
-#include "md5.h"
-#include "soap.h"
-#include <ctype.h>
-
-static char *adlrml_entry(const char *handle_, msn_buddy_flags_t list)
-{
- char *domain, handle[strlen(handle_) + 1];
-
- strcpy(handle, handle_);
- if ((domain = strchr(handle, '@'))) {
- *(domain++) = '\0';
- } else {
- return NULL;
- }
-
- return g_markup_printf_escaped("<ml><d n=\"%s\"><c n=\"%s\" t=\"1\"><s n=\"IM\" l=\"%d\" /></c></d></ml>",
- domain, handle, list);
-}
-
-int msn_buddy_list_add(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname,
- const char *group)
-{
- struct msn_data *md = ic->proto_data;
- char groupid[8];
- bee_user_t *bu;
- struct msn_buddy_data *bd;
- char *adl;
-
- *groupid = '\0';
-
- if (!((bu = bee_user_by_handle(ic->bee, ic, who)) ||
- (bu = bee_user_new(ic->bee, ic, who, 0))) ||
- !(bd = bu->data) || bd->flags & list) {
- return 1;
- }
-
- bd->flags |= list;
-
- if (list == MSN_BUDDY_FL) {
- msn_soap_ab_contact_add(ic, bu);
- } else {
- msn_soap_memlist_edit(ic, who, TRUE, list);
- }
-
- if ((adl = adlrml_entry(who, list))) {
- int st = msn_ns_write(ic, -1, "ADL %d %zd\r\n%s",
- ++md->trId, strlen(adl), adl);
- g_free(adl);
-
- return st;
- }
-
- return 1;
-}
-
-int msn_buddy_list_remove(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group)
-{
- struct msn_data *md = ic->proto_data;
- char groupid[8];
- bee_user_t *bu;
- struct msn_buddy_data *bd;
- char *adl;
-
- *groupid = '\0';
-
- if (!(bu = bee_user_by_handle(ic->bee, ic, who)) ||
- !(bd = bu->data) || !(bd->flags & list)) {
- return 1;
- }
-
- bd->flags &= ~list;
-
- if (list == MSN_BUDDY_FL) {
- msn_soap_ab_contact_del(ic, bu);
- } else {
- msn_soap_memlist_edit(ic, who, FALSE, list);
- }
-
- if ((adl = adlrml_entry(who, list))) {
- int st = msn_ns_write(ic, -1, "RML %d %zd\r\n%s",
- ++md->trId, strlen(adl), adl);
- g_free(adl);
-
- return st;
- }
-
- return 1;
-}
-
-struct msn_buddy_ask_data {
- struct im_connection *ic;
- char *handle;
- char *realname;
-};
-
-static void msn_buddy_ask_free(void *data)
-{
- struct msn_buddy_ask_data *bla = data;
-
- g_free(bla->handle);
- g_free(bla->realname);
- g_free(bla);
-}
-
-static void msn_buddy_ask_yes(void *data)
-{
- struct msn_buddy_ask_data *bla = data;
-
- msn_buddy_list_add(bla->ic, MSN_BUDDY_AL, bla->handle, bla->realname, NULL);
-
- imcb_ask_add(bla->ic, bla->handle, NULL);
-
- msn_buddy_ask_free(bla);
-}
-
-static void msn_buddy_ask_no(void *data)
-{
- struct msn_buddy_ask_data *bla = data;
-
- msn_buddy_list_add(bla->ic, MSN_BUDDY_BL, bla->handle, bla->realname, NULL);
-
- msn_buddy_ask_free(bla);
-}
-
-void msn_buddy_ask(bee_user_t *bu)
-{
- struct msn_buddy_ask_data *bla;
- struct msn_buddy_data *bd = bu->data;
- char buf[1024];
-
- if (!(bd->flags & MSN_BUDDY_PL)) {
- return;
- }
-
- bla = g_new0(struct msn_buddy_ask_data, 1);
- bla->ic = bu->ic;
- bla->handle = g_strdup(bu->handle);
- bla->realname = g_strdup(bu->fullname);
-
- g_snprintf(buf, sizeof(buf),
- "The user %s (%s) wants to add you to his/her buddy list.",
- bu->handle, bu->fullname);
-
- imcb_ask_with_free(bu->ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no, msn_buddy_ask_free);
-}
-
-void msn_queue_feed(struct msn_data *h, char *bytes, int st)
-{
- h->rxq = g_renew(char, h->rxq, h->rxlen + st);
- memcpy(h->rxq + h->rxlen, bytes, st);
- h->rxlen += st;
-
- if (getenv("BITLBEE_DEBUG")) {
- fprintf(stderr, "\n\x1b[92m<<< ");
- fwrite(bytes, st, 1, stderr);
- fprintf(stderr, "\x1b[97m");
- }
-}
-
-/* This one handles input from a MSN Messenger server. Both the NS and SB servers usually give
- commands, but sometimes they give additional data (payload). This function tries to handle
- this all in a nice way and send all data to the right places. */
-
-/* Return values: -1: Read error, abort connection.
- 0: Command reported error; Abort *immediately*. (The connection does not exist anymore)
- 1: OK */
-
-int msn_handler(struct msn_data *h)
-{
- int st = 1;
-
- while (st) {
- int i;
-
- if (h->msglen == 0) {
- for (i = 0; i < h->rxlen; i++) {
- if (h->rxq[i] == '\r' || h->rxq[i] == '\n') {
- char *cmd_text, **cmd;
- int count;
-
- cmd_text = g_strndup(h->rxq, i);
- cmd = g_strsplit_set(cmd_text, " ", -1);
- count = g_strv_length(cmd);
-
- st = msn_ns_command(h, cmd, count);
-
- g_strfreev(cmd);
- g_free(cmd_text);
-
- /* If the connection broke, don't continue. We don't even exist anymore. */
- if (!st) {
- return(0);
- }
-
- if (h->msglen) {
- h->cmd_text = g_strndup(h->rxq, i);
- }
-
- /* Skip to the next non-emptyline */
- while (i < h->rxlen && (h->rxq[i] == '\r' || h->rxq[i] == '\n')) {
- i++;
- }
-
- break;
- }
- }
-
- /* If we reached the end of the buffer, there's still an incomplete command there.
- Return and wait for more data. */
- if (i && i == h->rxlen && h->rxq[i - 1] != '\r' && h->rxq[i - 1] != '\n') {
- break;
- }
- } else {
- char *msg, **cmd;
- int count;
-
- /* Do we have the complete message already? */
- if (h->msglen > h->rxlen) {
- break;
- }
-
- msg = g_strndup(h->rxq, h->msglen);
-
- cmd = g_strsplit_set(h->cmd_text, " ", -1);
- count = g_strv_length(cmd);
-
- st = msn_ns_message(h, msg, h->msglen, cmd, count);
-
- g_strfreev(cmd);
- g_free(msg);
- g_free(h->cmd_text);
- h->cmd_text = NULL;
-
- if (!st) {
- return(0);
- }
-
- i = h->msglen;
- h->msglen = 0;
- }
-
- /* More data after this block? */
- if (i < h->rxlen) {
- char *tmp;
-
- tmp = g_memdup(h->rxq + i, h->rxlen - i);
- g_free(h->rxq);
- h->rxq = tmp;
- h->rxlen -= i;
- i = 0;
- } else {
- /* If not, reset the rx queue and get lost. */
- g_free(h->rxq);
- h->rxq = g_new0(char, 1);
- h->rxlen = 0;
- return(1);
- }
- }
-
- return(1);
-}
-
-/* Copied and heavily modified from http://tmsnc.sourceforge.net/chl.c */
-char *msn_p11_challenge(char *challenge)
-{
- char *output, buf[256];
- md5_state_t md5c;
- unsigned char md5Hash[16], *newHash;
- unsigned int *md5Parts, *chlStringParts, newHashParts[5];
- long long nHigh = 0, nLow = 0;
- int i, n;
-
- /* Create the MD5 hash */
- md5_init(&md5c);
- md5_append(&md5c, (unsigned char *) challenge, strlen(challenge));
- md5_append(&md5c, (unsigned char *) MSNP11_PROD_KEY, strlen(MSNP11_PROD_KEY));
- md5_finish(&md5c, md5Hash);
-
- /* Split it into four integers */
- md5Parts = (unsigned int *) md5Hash;
- for (i = 0; i < 4; i++) {
- md5Parts[i] = GUINT32_TO_LE(md5Parts[i]);
-
- /* & each integer with 0x7FFFFFFF */
- /* and save one unmodified array for later */
- newHashParts[i] = md5Parts[i];
- md5Parts[i] &= 0x7FFFFFFF;
- }
-
- /* make a new string and pad with '0' */
- n = g_snprintf(buf, sizeof(buf) - 5, "%s%s00000000", challenge, MSNP11_PROD_ID);
- /* truncate at an 8-byte boundary */
- buf[n &= ~7] = '\0';
-
- /* split into integers */
- chlStringParts = (unsigned int *) buf;
-
- /* this is magic */
- for (i = 0; i < (n / 4) - 1; i += 2) {
- long long temp;
-
- chlStringParts[i] = GUINT32_TO_LE(chlStringParts[i]);
- chlStringParts[i + 1] = GUINT32_TO_LE(chlStringParts[i + 1]);
-
- temp =
- (md5Parts[0] *
- (((0x0E79A9C1 *
- (long long) chlStringParts[i]) % 0x7FFFFFFF) + nHigh) + md5Parts[1]) % 0x7FFFFFFF;
- nHigh =
- (md5Parts[2] *
- (((long long) chlStringParts[i + 1] + temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF;
- nLow = nLow + nHigh + temp;
- }
- nHigh = (nHigh + md5Parts[1]) % 0x7FFFFFFF;
- nLow = (nLow + md5Parts[3]) % 0x7FFFFFFF;
-
- newHashParts[0] ^= nHigh;
- newHashParts[1] ^= nLow;
- newHashParts[2] ^= nHigh;
- newHashParts[3] ^= nLow;
-
- /* swap more bytes if big endian */
- for (i = 0; i < 4; i++) {
- newHashParts[i] = GUINT32_TO_LE(newHashParts[i]);
- }
-
- /* make a string of the parts */
- newHash = (unsigned char *) newHashParts;
-
- /* convert to hexadecimal */
- output = g_new(char, 33);
- for (i = 0; i < 16; i++) {
- sprintf(output + i * 2, "%02x", newHash[i]);
- }
-
- return output;
-}
-
-gint msn_domaintree_cmp(gconstpointer a_, gconstpointer b_)
-{
- const char *a = a_, *b = b_;
- gint ret;
-
- if (!(a = strchr(a, '@')) || !(b = strchr(b, '@')) ||
- (ret = strcmp(a, b)) == 0) {
- ret = strcmp(a_, b_);
- }
-
- return ret;
-}
-
-struct msn_group *msn_group_by_name(struct im_connection *ic, const char *name)
-{
- struct msn_data *md = ic->proto_data;
- GSList *l;
-
- for (l = md->groups; l; l = l->next) {
- struct msn_group *mg = l->data;
-
- if (g_strcasecmp(mg->name, name) == 0) {
- return mg;
- }
- }
-
- return NULL;
-}
-
-struct msn_group *msn_group_by_id(struct im_connection *ic, const char *id)
-{
- struct msn_data *md = ic->proto_data;
- GSList *l;
-
- for (l = md->groups; l; l = l->next) {
- struct msn_group *mg = l->data;
-
- if (g_strcasecmp(mg->id, id) == 0) {
- return mg;
- }
- }
-
- return NULL;
-}
-
-int msn_ns_set_display_name(struct im_connection *ic, const char *value)
-{
- // TODO, implement this through msn_set_away's method
- return 1;
-}
-
-const char *msn_normalize_handle(const char *handle)
-{
- if (strncmp(handle, "1:", 2) == 0) {
- return handle + 2;
- } else {
- return handle;
- }
-}
diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c
deleted file mode 100644
index d577b4b9..00000000
--- a/protocols/msn/ns.c
+++ /dev/null
@@ -1,779 +0,0 @@
-/********************************************************************\
- * BitlBee -- An IRC to other IM-networks gateway *
- * *
- * Copyright 2002-2012 Wilmer van der Gaast and others *
- \********************************************************************/
-
-/* MSN module - Notification server callbacks */
-
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT 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 with
- the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
- if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
- Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include <ctype.h>
-#include <sys/utsname.h>
-#include "nogaim.h"
-#include "msn.h"
-#include "md5.h"
-#include "sha1.h"
-#include "soap.h"
-#include "xmltree.h"
-
-static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition cond);
-static gboolean msn_ns_callback(gpointer data, gint source, b_input_condition cond);
-
-static void msn_ns_send_adl_start(struct im_connection *ic);
-static void msn_ns_send_adl(struct im_connection *ic);
-static void msn_ns_structured_message(struct msn_data *md, char *msg, int msglen, char **cmd);
-static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action, gboolean selfmessage);
-static void msn_ns_nfy(struct msn_data *md, char *who, char **parts, char *action, gboolean is_put);
-
-int msn_ns_write(struct im_connection *ic, int fd, const char *fmt, ...)
-{
- struct msn_data *md = ic->proto_data;
- va_list params;
- char *out;
- size_t len;
- int st;
-
- va_start(params, fmt);
- out = g_strdup_vprintf(fmt, params);
- va_end(params);
-
- if (fd < 0) {
- fd = md->fd;
- }
-
- if (getenv("BITLBEE_DEBUG")) {
- fprintf(stderr, "\x1b[91m>>>[NS%d] %s\n\x1b[97m", fd, out);
- }
-
- len = strlen(out);
-
- if (md->is_http) {
- st = len;
- msn_gw_write(md->gw, out, len);
- } else {
- st = write(fd, out, len);
- }
-
- g_free(out);
- if (st != len) {
- imcb_error(ic, "Short write() to main server");
- imc_logout(ic, TRUE);
- return 0;
- }
-
- return 1;
-}
-
-gboolean msn_ns_connect(struct im_connection *ic, const char *host, int port)
-{
- struct msn_data *md = ic->proto_data;
-
- if (md->fd >= 0) {
- closesocket(md->fd);
- }
-
- if (md->is_http) {
- md->gw = msn_gw_new(ic);
- md->gw->callback = msn_ns_callback;
- msn_ns_connected(md, -1, B_EV_IO_READ);
- } else {
- md->fd = proxy_connect(host, port, msn_ns_connected, md);
- if (md->fd < 0) {
- imcb_error(ic, "Could not connect to server");
- imc_logout(ic, TRUE);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition cond)
-{
- struct msn_data *md = data;
- struct im_connection *ic = md->ic;
-
- /* this should be taken from XFR, but hardcoding it for now. it also prevents more redirects. */
- const char *redir_data = "VmVyc2lvbjogMQ0KWGZyQ291bnQ6IDINCklzR2VvWGZyOiB0cnVlDQo=";
-
- if (source == -1 && !md->is_http) {
- imcb_error(ic, "Could not connect to server");
- imc_logout(ic, TRUE);
- return FALSE;
- }
-
- g_free(md->rxq);
- md->rxlen = 0;
- md->rxq = g_new0(char, 1);
-
- if (md->uuid == NULL) {
- struct utsname name;
- sha1_state_t sha[1];
-
- /* UUID == SHA1("BitlBee" + my hostname + MSN username) */
- sha1_init(sha);
- sha1_append(sha, (void *) "BitlBee", 7);
- if (uname(&name) == 0) {
- sha1_append(sha, (void *) name.nodename, strlen(name.nodename));
- }
- sha1_append(sha, (void *) ic->acc->user, strlen(ic->acc->user));
- md->uuid = sha1_random_uuid(sha);
- memcpy(md->uuid, "b171be3e", 8); /* :-P */
- }
-
- /* Having to handle potential errors in each write sure makes these ifs awkward...*/
-
- if (msn_ns_write(ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER) &&
- msn_ns_write(ic, source, "CVR %d 0x0409 mac 10.2.0 ppc macmsgs 3.5.1 macmsgs %s %s\r\n",
- ++md->trId, ic->acc->user, redir_data) &&
- msn_ns_write(ic, md->fd, "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user)) {
-
- if (!md->is_http) {
- md->inpa = b_input_add(md->fd, B_EV_IO_READ, msn_ns_callback, md);
- }
- imcb_log(ic, "Connected to server, waiting for reply");
- }
-
- return FALSE;
-}
-
-void msn_ns_close(struct msn_data *md)
-{
- if (md->gw) {
- msn_gw_free(md->gw);
- }
- if (md->fd >= 0) {
- closesocket(md->fd);
- b_event_remove(md->inpa);
- }
-
- md->fd = md->inpa = -1;
- g_free(md->rxq);
- g_free(md->cmd_text);
-
- md->rxlen = 0;
- md->rxq = NULL;
- md->cmd_text = NULL;
-}
-
-static gboolean msn_ns_callback(gpointer data, gint source, b_input_condition cond)
-{
- struct msn_data *md = data;
- struct im_connection *ic = md->ic;
- char *bytes;
- int st;
-
- if (md->is_http) {
- st = msn_gw_read(md->gw, &bytes);
- } else {
- bytes = g_malloc(1024);
- st = read(md->fd, bytes, 1024);
- }
-
- if (st <= 0) {
- imcb_error(ic, "Error while reading from server");
- imc_logout(ic, TRUE);
- g_free(bytes);
- return FALSE;
- }
-
- msn_queue_feed(md, bytes, st);
-
- g_free(bytes);
-
- return msn_handler(md);
-}
-
-int msn_ns_command(struct msn_data *md, char **cmd, int num_parts)
-{
- struct im_connection *ic = md->ic;
-
- if (num_parts == 0) {
- /* Hrrm... Empty command...? Ignore? */
- return(1);
- }
-
- if (strcmp(cmd[0], "VER") == 0) {
- if (cmd[2] && strncmp(cmd[2], MSNP_VER, 5) != 0) {
- imcb_error(ic, "Unsupported protocol");
- imc_logout(ic, FALSE);
- return(0);
- }
-
- } else if (strcmp(cmd[0], "CVR") == 0) {
- /* We don't give a damn about the information we just received */
- } else if (strcmp(cmd[0], "XFR") == 0) {
- char *server;
- int port;
-
- if (num_parts >= 6 && strcmp(cmd[2], "NS") == 0) {
- b_event_remove(md->inpa);
- md->inpa = -1;
-
- server = strchr(cmd[3], ':');
- if (!server) {
- imcb_error(ic, "Syntax error");
- imc_logout(ic, TRUE);
- return(0);
- }
- *server = 0;
- port = atoi(server + 1);
- server = cmd[3];
-
- imcb_log(ic, "Transferring to other server");
- return msn_ns_connect(ic, server, port);
- } else {
- imcb_error(ic, "Syntax error");
- imc_logout(ic, TRUE);
- return(0);
- }
- } else if (strcmp(cmd[0], "USR") == 0) {
- if (num_parts >= 6 && strcmp(cmd[2], "SSO") == 0 &&
- strcmp(cmd[3], "S") == 0) {
- g_free(md->pp_policy);
- md->pp_policy = g_strdup(cmd[4]);
- msn_soap_passport_sso_request(ic, cmd[5]);
- } else if (strcmp(cmd[2], "OK") == 0) {
- /* If the number after the handle is 0, the e-mail
- address is unverified, which means we can't change
- the display name. */
- if (cmd[4][0] == '0') {
- md->flags |= MSN_EMAIL_UNVERIFIED;
- }
-
- imcb_log(ic, "Authenticated, getting buddy list");
- msn_soap_memlist_request(ic);
- } else {
- imcb_error(ic, "Unknown authentication type");
- imc_logout(ic, FALSE);
- return(0);
- }
- } else if (strcmp(cmd[0], "MSG") == 0) {
- if (num_parts < 4) {
- imcb_error(ic, "Syntax error");
- imc_logout(ic, TRUE);
- return(0);
- }
-
- md->msglen = atoi(cmd[3]);
-
- if (md->msglen <= 0) {
- imcb_error(ic, "Syntax error");
- imc_logout(ic, TRUE);
- return(0);
- }
- } else if (strcmp(cmd[0], "ADL") == 0) {
- if (num_parts >= 3 && strcmp(cmd[2], "OK") == 0) {
- msn_ns_send_adl(ic);
- return msn_ns_finish_login(ic);
- } else if (num_parts >= 3) {
- md->msglen = atoi(cmd[2]);
- }
- } else if (strcmp(cmd[0], "RML") == 0) {
- /* Move along, nothing to see here */
- } else if (strcmp(cmd[0], "CHL") == 0) {
- char *resp;
- int st;
-
- if (num_parts < 3) {
- imcb_error(ic, "Syntax error");
- imc_logout(ic, TRUE);
- return(0);
- }
-
- resp = msn_p11_challenge(cmd[2]);
-
- st = msn_ns_write(ic, -1, "QRY %d %s %zd\r\n%s",
- ++md->trId, MSNP11_PROD_ID,
- strlen(resp), resp);
- g_free(resp);
- return st;
- } else if (strcmp(cmd[0], "QRY") == 0) {
- /* CONGRATULATIONS */
- } else if (strcmp(cmd[0], "OUT") == 0) {
- imcb_error(ic, "Session terminated by remote server (%s)", cmd[1] ? cmd[1] : "reason unknown");
- imc_logout(ic, TRUE);
- return(0);
- } else if (strcmp(cmd[0], "GCF") == 0) {
- /* Coming up is cmd[2] bytes of stuff we're supposed to
- censore. Meh. */
- md->msglen = atoi(cmd[2]);
- } else if ((strcmp(cmd[0], "NFY") == 0) || (strcmp(cmd[0], "SDG") == 0)) {
- if (num_parts >= 3) {
- md->msglen = atoi(cmd[2]);
- }
- } else if (strcmp(cmd[0], "PUT") == 0) {
- if (num_parts >= 4) {
- md->msglen = atoi(cmd[3]);
- }
- } else if (strcmp(cmd[0], "NOT") == 0) {
- if (num_parts >= 2) {
- md->msglen = atoi(cmd[1]);
- }
- } else if (strcmp(cmd[0], "QNG") == 0) {
- ic->flags |= OPT_PONGED;
- } else if (g_ascii_isdigit(cmd[0][0])) {
- int num = atoi(cmd[0]);
- const struct msn_status_code *err = msn_status_by_number(num);
-
- imcb_error(ic, "Error reported by MSN server: %s", err->text);
-
- if (err->flags & STATUS_FATAL) {
- imc_logout(ic, TRUE);
- return(0);
- }
-
- /* Oh yes, errors can have payloads too now. Discard them for now. */
- if (num_parts >= 3) {
- md->msglen = atoi(cmd[2]);
- }
- } else {
- imcb_error(ic, "Received unknown command from main server: %s", cmd[0]);
- }
-
- return(1);
-}
-
-int msn_ns_message(struct msn_data *md, char *msg, int msglen, char **cmd, int num_parts)
-{
- struct im_connection *ic = md->ic;
- char *body;
- int blen = 0;
-
- if (!num_parts) {
- return(1);
- }
-
- if ((body = strstr(msg, "\r\n\r\n"))) {
- body += 4;
- blen = msglen - (body - msg);
- }
-
- if (strcmp(cmd[0], "MSG") == 0) {
- if (g_strcasecmp(cmd[1], "Hotmail") == 0) {
- char *ct = get_rfc822_header(msg, "Content-Type:", msglen);
-
- if (!ct) {
- return(1);
- }
-
- if (g_strncasecmp(ct, "application/x-msmsgssystemmessage", 33) == 0) {
- char *mtype;
- char *arg1;
-
- if (!body) {
- return(1);
- }
-
- mtype = get_rfc822_header(body, "Type:", blen);
- arg1 = get_rfc822_header(body, "Arg1:", blen);
-
- if (mtype && strcmp(mtype, "1") == 0) {
- if (arg1) {
- imcb_log(ic, "The server is going down for maintenance in %s minutes.",
- arg1);
- }
- }
-
- g_free(arg1);
- g_free(mtype);
- } else if (g_strncasecmp(ct, "text/x-msmsgsprofile", 20) == 0) {
- /* We don't care about this profile for now... */
- } else if (g_strncasecmp(ct, "text/x-msmsgsinitialemailnotification", 37) == 0) {
- if (set_getbool(&ic->acc->set, "mail_notifications")) {
- char *inbox = get_rfc822_header(body, "Inbox-Unread:", blen);
- char *folders = get_rfc822_header(body, "Folders-Unread:", blen);
-
- if (inbox && folders) {
- imcb_notify_email(ic,
- "INBOX contains %s new messages, plus %s messages in other folders.", inbox,
- folders);
- }
-
- g_free(inbox);
- g_free(folders);
- }
- } else if (g_strncasecmp(ct, "text/x-msmsgsemailnotification", 30) == 0) {
- if (set_getbool(&ic->acc->set, "mail_notifications")) {
- char *from = get_rfc822_header(body, "From-Addr:", blen);
- char *fromname = get_rfc822_header(body, "From:", blen);
-
- if (from && fromname) {
- imcb_notify_email(ic, "Received an e-mail message from %s <%s>.", fromname, from);
- }
-
- g_free(from);
- g_free(fromname);
- }
- } else if (g_strncasecmp(ct, "text/x-msmsgsactivemailnotification", 35) == 0) {
- /* Notification that a message has been read... Ignore it */
- }
-
- g_free(ct);
- }
- } else if (strcmp(cmd[0], "ADL") == 0) {
- struct xt_node *adl, *d, *c;
-
- if (!(adl = xt_from_string(msg, msglen))) {
- return 1;
- }
-
- for (d = adl->children; d; d = d->next) {
- char *dn;
- if (strcmp(d->name, "d") != 0 ||
- (dn = xt_find_attr(d, "n")) == NULL) {
- continue;
- }
- for (c = d->children; c; c = c->next) {
- bee_user_t *bu;
- struct msn_buddy_data *bd;
- char *cn, *handle, *f, *l;
- int flags;
-
- if (strcmp(c->name, "c") != 0 ||
- (l = xt_find_attr(c, "l")) == NULL ||
- (cn = xt_find_attr(c, "n")) == NULL) {
- continue;
- }
-
- /* FIXME: Use "t" here, guess I should just add it
- as a prefix like elsewhere in the protocol. */
- handle = g_strdup_printf("%s@%s", cn, dn);
- if (!((bu = bee_user_by_handle(ic->bee, ic, handle)) ||
- (bu = bee_user_new(ic->bee, ic, handle, 0)))) {
- g_free(handle);
- continue;
- }
- g_free(handle);
- bd = bu->data;
-
- if ((f = xt_find_attr(c, "f"))) {
- http_decode(f);
- imcb_rename_buddy(ic, bu->handle, f);
- }
-
- flags = atoi(l) & 15;
- if (bd->flags != flags) {
- bd->flags = flags;
- msn_buddy_ask(bu);
- }
- }
- }
- } else if ((strcmp(cmd[0], "SDG") == 0) || (strcmp(cmd[0], "NFY") == 0)) {
- msn_ns_structured_message(md, msg, msglen, cmd);
- }
-
- return 1;
-}
-
-/* returns newly allocated string */
-static char *msn_ns_parse_header_address(struct msn_data *md, char *headers, char *header_name)
-{
- char *semicolon = NULL;
- char *header = NULL;
- char *address = NULL;
-
- if (!(header = get_rfc822_header(headers, header_name, 0))) {
- return NULL;
- }
-
- /* either the semicolon or the end of the string */
- semicolon = strchr(header, ';') ? : (header + strlen(header));
-
- address = g_strndup(header + 2, semicolon - header - 2);
-
- g_free(header);
- return address;
-}
-
-static void msn_ns_structured_message(struct msn_data *md, char *msg, int msglen, char **cmd)
-{
- char **parts = NULL;
- char *action = NULL;
- char *who = NULL;
- gboolean selfmessage = FALSE;
-
- parts = g_strsplit(msg, "\r\n\r\n", 4);
-
- if (!(who = msn_ns_parse_header_address(md, parts[0], "From"))) {
- goto cleanup;
- }
-
- if (strcmp(who, md->ic->acc->user) == 0) {
- selfmessage = TRUE;
- g_free(who);
- if (!(who = msn_ns_parse_header_address(md, parts[0], "To"))) {
- goto cleanup;
- }
- }
-
- if ((strcmp(cmd[0], "SDG") == 0) && (action = get_rfc822_header(parts[2], "Message-Type", 0))) {
- msn_ns_sdg(md, who, parts, action, selfmessage);
-
- } else if ((strcmp(cmd[0], "NFY") == 0) && (action = get_rfc822_header(parts[2], "Uri", 0))) {
- gboolean is_put = (strcmp(cmd[1], "PUT") == 0);
- msn_ns_nfy(md, who, parts, action, is_put);
- }
-
-cleanup:
- g_strfreev(parts);
- g_free(action);
- g_free(who);
-}
-
-static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action, gboolean selfmessage)
-{
- struct im_connection *ic = md->ic;
-
- if (strcmp(action, "Control/Typing") == 0 && !selfmessage) {
- imcb_buddy_typing(ic, who, OPT_TYPING);
- } else if (strcmp(action, "Text") == 0) {
- imcb_buddy_msg(ic, who, parts[3], selfmessage ? OPT_SELFMESSAGE : 0, 0);
- }
-}
-
-static void msn_ns_nfy(struct msn_data *md, char *who, char **parts, char *action, gboolean is_put)
-{
- struct im_connection *ic = md->ic;
- struct xt_node *body = NULL;
- struct xt_node *s = NULL;
- const char *state = NULL;
- char *nick = NULL;
- char *psm = NULL;
- int flags = OPT_LOGGED_IN;
-
- if (strcmp(action, "/user") != 0) {
- return;
- }
-
- if (!(body = xt_from_string(parts[3], 0))) {
- goto cleanup;
- }
-
- s = body->children;
- while ((s = xt_find_node(s, "s"))) {
- struct xt_node *s2;
- char *n = xt_find_attr(s, "n"); /* service name: IM, PE, etc */
-
- if (strcmp(n, "IM") == 0) {
- /* IM has basic presence information */
- if (!is_put) {
- /* NFY DEL with a <s> usually means log out from the last endpoint */
- flags &= ~OPT_LOGGED_IN;
- break;
- }
-
- s2 = xt_find_node(s->children, "Status");
- if (s2 && s2->text_len) {
- const struct msn_away_state *msn_state = msn_away_state_by_code(s2->text);
- state = msn_state->name;
- if (msn_state != msn_away_state_list) {
- flags |= OPT_AWAY;
- }
- }
- } else if (strcmp(n, "PE") == 0) {
- if ((s2 = xt_find_node(s->children, "PSM")) && s2->text_len) {
- psm = s2->text;
- }
- if ((s2 = xt_find_node(s->children, "FriendlyName")) && s2->text_len) {
- nick = s2->text;
- }
- }
- s = s->next;
- }
-
- imcb_buddy_status(ic, who, flags, state, psm);
-
- if (nick) {
- imcb_rename_buddy(ic, who, nick);
- }
-
-cleanup:
- xt_free_node(body);
-}
-
-void msn_auth_got_passport_token(struct im_connection *ic, const char *token, const char *error)
-{
- struct msn_data *md;
-
- /* Dead connection? */
- if (g_slist_find(msn_connections, ic) == NULL) {
- return;
- }
-
- md = ic->proto_data;
-
- if (token) {
- msn_ns_write(ic, -1, "USR %d SSO S %s %s {%s}\r\n", ++md->trId, md->tokens[0], token, md->uuid);
- } else {
- imcb_error(ic, "Error during Passport authentication: %s", error);
-
- /* don't reconnect with auth errors */
- if (error && g_str_has_prefix(error, "wsse:FailedAuthentication")) {
- imc_logout(ic, FALSE);
- } else {
- imc_logout(ic, TRUE);
- }
- }
-}
-
-void msn_auth_got_contact_list(struct im_connection *ic)
-{
- /* Dead connection? */
- if (g_slist_find(msn_connections, ic) == NULL) {
- return;
- }
-
- msn_ns_send_adl_start(ic);
- msn_ns_finish_login(ic);
-}
-
-static gboolean msn_ns_send_adl_1(gpointer key, gpointer value, gpointer data)
-{
- struct xt_node *adl = data, *d, *c, *s;
- struct bee_user *bu = value;
- struct msn_buddy_data *bd = bu->data;
- struct msn_data *md = bu->ic->proto_data;
- char handle[strlen(bu->handle) + 1];
- char *domain;
- char l[4];
-
- if ((bd->flags & (MSN_BUDDY_FL | MSN_BUDDY_AL)) == 0 || (bd->flags & MSN_BUDDY_ADL_SYNCED)) {
- return FALSE;
- }
-
- strcpy(handle, bu->handle);
- if ((domain = strchr(handle, '@')) == NULL) { /* WTF */
- return FALSE;
- }
- *domain = '\0';
- domain++;
-
- if ((d = adl->children) == NULL ||
- g_strcasecmp(xt_find_attr(d, "n"), domain) != 0) {
- d = xt_new_node("d", NULL, NULL);
- xt_add_attr(d, "n", domain);
- xt_insert_child(adl, d);
- }
-
- g_snprintf(l, sizeof(l), "%d", bd->flags & (MSN_BUDDY_FL | MSN_BUDDY_AL));
- c = xt_new_node("c", NULL, NULL);
- xt_add_attr(c, "n", handle);
- xt_add_attr(c, "t", "1"); /* FIXME: Network type, i.e. 32 for Y!MSG */
- s = xt_new_node("s", NULL, NULL);
- xt_add_attr(s, "n", "IM");
- xt_add_attr(s, "l", l);
- xt_insert_child(c, s);
- xt_insert_child(d, c);
-
- /* Do this in batches of 100. */
- bd->flags |= MSN_BUDDY_ADL_SYNCED;
- return (--md->adl_todo % 140) == 0;
-}
-
-static void msn_ns_send_adl(struct im_connection *ic)
-{
- struct xt_node *adl;
- struct msn_data *md = ic->proto_data;
- char *adls;
-
- adl = xt_new_node("ml", NULL, NULL);
- xt_add_attr(adl, "l", "1");
- g_tree_foreach(md->domaintree, msn_ns_send_adl_1, adl);
- if (adl->children == NULL) {
- /* This tells the caller that we're done now. */
- md->adl_todo = -1;
- xt_free_node(adl);
- return;
- }
-
- adls = xt_to_string(adl);
- xt_free_node(adl);
- msn_ns_write(ic, -1, "ADL %d %zd\r\n%s", ++md->trId, strlen(adls), adls);
- g_free(adls);
-}
-
-static void msn_ns_send_adl_start(struct im_connection *ic)
-{
- struct msn_data *md;
- GSList *l;
-
- /* Dead connection? */
- if (g_slist_find(msn_connections, ic) == NULL) {
- return;
- }
-
- md = ic->proto_data;
- md->adl_todo = 0;
- for (l = ic->bee->users; l; l = l->next) {
- bee_user_t *bu = l->data;
- struct msn_buddy_data *bd = bu->data;
-
- if (bu->ic != ic || (bd->flags & (MSN_BUDDY_FL | MSN_BUDDY_AL)) == 0) {
- continue;
- }
-
- bd->flags &= ~MSN_BUDDY_ADL_SYNCED;
- md->adl_todo++;
- }
-
- msn_ns_send_adl(ic);
-}
-
-int msn_ns_finish_login(struct im_connection *ic)
-{
- struct msn_data *md = ic->proto_data;
-
- if (ic->flags & OPT_LOGGED_IN) {
- return 1;
- }
-
- if (md->adl_todo < 0) {
- md->flags |= MSN_DONE_ADL;
- }
-
- if ((md->flags & MSN_DONE_ADL) && (md->flags & MSN_GOT_PROFILE)) {
- imcb_connected(ic);
- }
-
- return 1;
-}
-
-static int msn_ns_send_sdg(struct im_connection *ic, bee_user_t *bu, const char *message_type, const char *text)
-{
- struct msn_data *md = ic->proto_data;
- int retval = 0;
- char *buf;
-
- buf = g_strdup_printf(MSN_MESSAGE_HEADERS, bu->handle, ic->acc->user, md->uuid, message_type, strlen(text), text);
- retval = msn_ns_write(ic, -1, "SDG %d %zd\r\n%s", ++md->trId, strlen(buf), buf);
- g_free(buf);
- return retval;
-}
-
-int msn_ns_send_typing(struct im_connection *ic, bee_user_t *bu)
-{
- return msn_ns_send_sdg(ic, bu, "Control/Typing", "");
-}
-
-int msn_ns_send_message(struct im_connection *ic, bee_user_t *bu, const char *text)
-{
- return msn_ns_send_sdg(ic, bu, "Text", text);
-}
-
diff --git a/protocols/msn/soap.c b/protocols/msn/soap.c
deleted file mode 100644
index 14aaed11..00000000
--- a/protocols/msn/soap.c
+++ /dev/null
@@ -1,1032 +0,0 @@
-/********************************************************************\
- * BitlBee -- An IRC to other IM-networks gateway *
- * *
- * Copyright 2002-2012 Wilmer van der Gaast and others *
- \********************************************************************/
-
-/* MSN module - All the SOAPy XML stuff.
- Some manager at Microsoft apparently thought MSNP wasn't XMLy enough so
- someone stepped up and changed that. This is the result. Kilobytes and
- more kilobytes of XML vomit to transfer tiny bits of informaiton. */
-
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT 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 with
- the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
- if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
- Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include "http_client.h"
-#include "soap.h"
-#include "msn.h"
-#include "bitlbee.h"
-#include "url.h"
-#include "misc.h"
-#include "sha1.h"
-#include "base64.h"
-#include "xmltree.h"
-#include <ctype.h>
-#include <errno.h>
-
-/* This file tries to make SOAP stuff pretty simple to do by letting you just
- provide a function to build a request, a few functions to parse various
- parts of the response, and a function to run when the full response was
- received and parsed. See the various examples below. */
-
-typedef enum {
- MSN_SOAP_OK,
- MSN_SOAP_RETRY,
- MSN_SOAP_REAUTH,
- 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 *error;
-
- 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;
-};
-
-static int msn_soap_send_request(struct msn_soap_req_data *req);
-static void msn_soap_free(struct msn_soap_req_data *soap_req);
-static void msn_soap_debug_print(const char *headers, const char *payload);
-
-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;
- char *soap_action = NULL;
- url_t url;
-
- soap_req->build_request(soap_req);
-
- if (soap_req->action) {
- soap_action = g_strdup_printf("SOAPAction: \"%s\"\r\n", soap_req->action);
- }
-
- url_set(&url, soap_req->url);
- http_req = g_strdup_printf(SOAP_HTTP_REQUEST, url.file, url.host,
- soap_action ? soap_action : "",
- strlen(soap_req->payload), soap_req->payload);
-
- msn_soap_debug_print(http_req, 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);
-
- g_free(http_req);
- g_free(soap_action);
-
- 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 (g_slist_find(msn_connections, soap_req->ic) == NULL) {
- msn_soap_free(soap_req);
- return;
- }
-
- msn_soap_debug_print(http_req->reply_headers, http_req->reply_body);
-
- if (http_req->body_size > 0) {
- struct xt_parser *parser;
- struct xt_node *err;
-
- parser = xt_new(soap_req->xml_parser, soap_req);
- xt_feed(parser, http_req->reply_body, http_req->body_size);
- if (http_req->status_code == 500 &&
- (err = xt_find_path(parser->root, "soap:Body/soap:Fault/detail/errorcode")) &&
- err->text_len > 0) {
- if (strcmp(err->text, "PassportAuthFail") == 0) {
- xt_free(parser);
- st = MSN_SOAP_REAUTH;
- goto fail;
- }
- /* TODO: Handle/report other errors. */
- }
-
- xt_handle(parser, NULL, -1);
- xt_free(parser);
- }
-
- if (http_req->status_code != 200) {
- soap_req->error = g_strdup(http_req->status_string);
- }
-
- st = soap_req->handle_response(soap_req);
-
-fail:
- g_free(soap_req->url);
- g_free(soap_req->action);
- g_free(soap_req->payload);
- g_free(soap_req->error);
- soap_req->url = soap_req->action = soap_req->payload = soap_req->error = NULL;
-
- 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 {
- soap_req->free_data(soap_req);
- g_free(soap_req);
- }
-}
-
-static char *msn_soap_abservice_build(const char *body_fmt, const char *scenario, const char *ticket, ...)
-{
- va_list params;
- char *ret, *format, *body;
-
- format = g_markup_printf_escaped(SOAP_ABSERVICE_PAYLOAD, scenario, ticket);
-
- va_start(params, ticket);
- body = g_strdup_vprintf(body_fmt, params);
- va_end(params);
-
- ret = g_strdup_printf(format, body);
- g_free(body);
- g_free(format);
-
- return ret;
-}
-
-static void msn_soap_debug_print(const char *headers, const char *payload)
-{
- char *s;
-
- if (!getenv("BITLBEE_DEBUG")) {
- return;
- }
- fprintf(stderr, "\n\x1b[90mSOAP:\n");
-
- if (headers) {
- if ((s = strstr(headers, "\r\n\r\n"))) {
- fwrite(headers, s - headers + 4, 1, stderr);
- } else {
- fwrite(headers, strlen(headers), 1, stderr);
- }
- }
-
- if (payload) {
- struct xt_node *xt = xt_from_string(payload, 0);
- if (xt) {
- xt_print(xt);
- }
- xt_free_node(xt);
- }
- fprintf(stderr, "\n\x1b[97m\n");
-}
-
-int msn_soapq_flush(struct im_connection *ic, gboolean resend)
-{
- struct msn_data *md = ic->proto_data;
-
- while (md->soapq) {
- if (resend) {
- msn_soap_send_request((struct msn_soap_req_data*) md->soapq->data);
- } else {
- msn_soap_free((struct msn_soap_req_data*) md->soapq->data);
- }
- md->soapq = g_slist_remove(md->soapq, md->soapq->data);
- }
-
- return MSN_SOAP_OK;
-}
-
-static void msn_soap_free(struct msn_soap_req_data *soap_req)
-{
- 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->error);
- g_free(soap_req);
-}
-
-
-/* passport_sso: Authentication MSNP15+ */
-
-struct msn_soap_passport_sso_data {
- char *nonce;
- char *secret;
- char *error;
- char *redirect;
-};
-
-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;
-
- if (sd->redirect) {
- soap_req->url = sd->redirect;
- sd->redirect = NULL;
- }
- /* MS changed this URL and broke the old MSN-specific one. The generic
- one works, forwarding us to a msn.com URL that works. Takes an extra
- second, but that's better than not being able to log in at all. :-/
- else if( g_str_has_suffix( ic->acc->user, "@msn.com" ) )
- soap_req->url = g_strdup( SOAP_PASSPORT_SSO_URL_MSN );
- */
- else {
- soap_req->url = g_strdup(SOAP_PASSPORT_SSO_URL);
- }
-
- soap_req->payload = g_markup_printf_escaped(SOAP_PASSPORT_SSO_PAYLOAD,
- ic->acc->user, ic->acc->pass, md->pp_policy);
-
- return MSN_SOAP_OK;
-}
-
-static xt_status msn_soap_passport_sso_token(struct xt_node *node, gpointer data)
-{
- struct msn_soap_req_data *soap_req = data;
- struct msn_soap_passport_sso_data *sd = soap_req->data;
- struct msn_data *md = soap_req->ic->proto_data;
- struct xt_node *p;
- char *id;
-
- if ((id = xt_find_attr(node, "Id")) == NULL) {
- return XT_HANDLED;
- }
- id += strlen(id) - 1;
- if (*id == '1' &&
- (p = xt_find_path(node, "../../wst:RequestedProofToken/wst:BinarySecret")) &&
- p->text) {
- sd->secret = g_strdup(p->text);
- }
-
- *id -= '1';
- if (*id >= 0 && *id < sizeof(md->tokens) / sizeof(md->tokens[0])) {
- g_free(md->tokens[(int) *id]);
- md->tokens[(int) *id] = g_strdup(node->text);
- }
-
- return XT_HANDLED;
-}
-
-static xt_status msn_soap_passport_failure(struct xt_node *node, gpointer data)
-{
- struct msn_soap_req_data *soap_req = data;
- struct msn_soap_passport_sso_data *sd = soap_req->data;
- struct xt_node *code = xt_find_node(node->children, "faultcode");
- struct xt_node *string = xt_find_node(node->children, "faultstring");
- struct xt_node *reqstatus = xt_find_path(node, "psf:pp/psf:reqstatus");
- struct xt_node *url;
-
- if (code == NULL || code->text_len == 0) {
- sd->error = g_strdup("Unknown error");
- } else if (strcmp(code->text, "psf:Redirect") == 0 &&
- (url = xt_find_node(node->children, "psf:redirectUrl")) &&
- url->text_len > 0) {
- sd->redirect = g_strdup(url->text);
- } else if (reqstatus && strcmp(reqstatus->text, "0x800488fe") == 0) {
- char *msg = "Location blocked. Log in to live.com, go to recent activity and click 'this was me'";
- sd->error = g_strdup_printf("%s (%s)", code->text, msg);
- } else {
- sd->error = g_strdup_printf("%s (%s)", code->text, string && string->text_len ?
- string->text : "no description available");
- }
-
- return XT_HANDLED;
-}
-
-static const struct xt_handler_entry msn_soap_passport_sso_parser[] = {
- { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", msn_soap_passport_sso_token },
- { "S:Fault", "S:Envelope", msn_soap_passport_failure },
- { "S:Fault", "wst:RequestSecurityTokenResponse", msn_soap_passport_failure },
- { NULL, NULL, NULL }
-};
-
-static char *msn_key_fuckery(char *key, int key_len, char *type)
-{
- unsigned char hash1[20 + strlen(type) + 1];
- unsigned char hash2[20];
- char *ret;
-
- sha1_hmac(key, key_len, type, 0, hash1);
- strcpy((char *) hash1 + 20, type);
- sha1_hmac(key, key_len, (char *) hash1, sizeof(hash1) - 1, hash2);
-
- /* This is okay as hash1 is read completely before it's overwritten. */
- sha1_hmac(key, key_len, (char *) hash1, 20, hash1);
- sha1_hmac(key, key_len, (char *) hash1, sizeof(hash1) - 1, hash1);
-
- ret = g_malloc(24);
- memcpy(ret, hash2, 20);
- memcpy(ret + 20, hash1, 4);
- return ret;
-}
-
-static int msn_soap_passport_sso_handle_response(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;
- char *key1, *key2, *key3, *blurb64;
- int key1_len;
- unsigned char *padnonce, *des3res;
-
- struct {
- unsigned int uStructHeaderSize; // 28. Does not count data
- unsigned int uCryptMode; // CRYPT_MODE_CBC (1)
- unsigned int uCipherType; // TripleDES (0x6603)
- unsigned int uHashType; // SHA1 (0x8004)
- unsigned int uIVLen; // 8
- unsigned int uHashLen; // 20
- unsigned int uCipherLen; // 72
- unsigned char iv[8];
- unsigned char hash[20];
- unsigned char cipherbytes[72];
- } blurb = {
- GUINT32_TO_LE(28),
- GUINT32_TO_LE(1),
- GUINT32_TO_LE(0x6603),
- GUINT32_TO_LE(0x8004),
- GUINT32_TO_LE(8),
- GUINT32_TO_LE(20),
- GUINT32_TO_LE(72),
- };
-
- if (sd->redirect) {
- return MSN_SOAP_RETRY;
- }
-
- if (md->soapq) {
- md->flags &= ~MSN_REAUTHING;
- return msn_soapq_flush(ic, TRUE);
- }
-
- if (sd->secret == NULL) {
- msn_auth_got_passport_token(ic, NULL, sd->error ? sd->error : soap_req->error);
- return MSN_SOAP_OK;
- }
-
- key1_len = base64_decode(sd->secret, (unsigned char **) &key1);
-
- key2 = msn_key_fuckery(key1, key1_len, "WS-SecureConversationSESSION KEY HASH");
- key3 = msn_key_fuckery(key1, key1_len, "WS-SecureConversationSESSION KEY ENCRYPTION");
-
- sha1_hmac(key2, 24, sd->nonce, 0, blurb.hash);
- padnonce = g_malloc(strlen(sd->nonce) + 8);
- strcpy((char *) padnonce, sd->nonce);
- memset(padnonce + strlen(sd->nonce), 8, 8);
-
- random_bytes(blurb.iv, 8);
-
- ssl_des3_encrypt((unsigned char *) key3, 24, padnonce, strlen(sd->nonce) + 8, blurb.iv, &des3res);
- memcpy(blurb.cipherbytes, des3res, 72);
-
- blurb64 = base64_encode((unsigned char *) &blurb, sizeof(blurb));
- msn_auth_got_passport_token(ic, blurb64, NULL);
-
- g_free(padnonce);
- g_free(blurb64);
- g_free(des3res);
- g_free(key1);
- g_free(key2);
- g_free(key3);
-
- return MSN_SOAP_OK;
-}
-
-static int msn_soap_passport_sso_free_data(struct msn_soap_req_data *soap_req)
-{
- struct msn_soap_passport_sso_data *sd = soap_req->data;
-
- g_free(sd->nonce);
- g_free(sd->secret);
- g_free(sd->error);
- g_free(sd->redirect);
- g_free(sd);
-
- return MSN_SOAP_OK;
-}
-
-int msn_soap_passport_sso_request(struct im_connection *ic, const char *nonce)
-{
- struct msn_soap_passport_sso_data *sd = g_new0(struct msn_soap_passport_sso_data, 1);
-
- sd->nonce = g_strdup(nonce);
-
- return msn_soap_start(ic, sd, msn_soap_passport_sso_build_request,
- msn_soap_passport_sso_parser,
- msn_soap_passport_sso_handle_response,
- msn_soap_passport_sso_free_data);
-}
-
-
-/* memlist: Fetching the membership list (NOT address book) */
-
-static int msn_soap_memlist_build_request(struct msn_soap_req_data *soap_req)
-{
- struct msn_data *md = soap_req->ic->proto_data;
-
- soap_req->url = g_strdup(SOAP_MEMLIST_URL);
- soap_req->action = g_strdup(SOAP_MEMLIST_ACTION);
- soap_req->payload = msn_soap_abservice_build(SOAP_MEMLIST_PAYLOAD, "Initial", md->tokens[1]);
-
- return 1;
-}
-
-static xt_status msn_soap_memlist_member(struct xt_node *node, gpointer data)
-{
- bee_user_t *bu;
- struct msn_buddy_data *bd;
- struct xt_node *p;
- char *role = NULL, *handle = NULL;
- struct msn_soap_req_data *soap_req = data;
- struct im_connection *ic = soap_req->ic;
-
- if ((p = xt_find_path(node, "../../MemberRole"))) {
- role = p->text;
- }
-
- if ((p = xt_find_node(node->children, "PassportName"))) {
- handle = p->text;
- }
-
- if (!role || !handle ||
- !((bu = bee_user_by_handle(ic->bee, ic, handle)) ||
- (bu = bee_user_new(ic->bee, ic, handle, 0)))) {
- return XT_HANDLED;
- }
-
- bd = bu->data;
- if (strcmp(role, "Allow") == 0) {
- bd->flags |= MSN_BUDDY_AL;
- ic->permit = g_slist_prepend(ic->permit, g_strdup(handle));
- } else if (strcmp(role, "Block") == 0) {
- bd->flags |= MSN_BUDDY_BL;
- ic->deny = g_slist_prepend(ic->deny, g_strdup(handle));
- } else if (strcmp(role, "Reverse") == 0) {
- bd->flags |= MSN_BUDDY_RL;
- } else if (strcmp(role, "Pending") == 0) {
- bd->flags |= MSN_BUDDY_PL;
- }
-
- if (getenv("BITLBEE_DEBUG")) {
- fprintf(stderr, "%p %s %d\n", bu, handle, bd->flags);
- }
-
- return XT_HANDLED;
-}
-
-static const struct xt_handler_entry msn_soap_memlist_parser[] = {
- { "Member", "Members", msn_soap_memlist_member },
- { NULL, NULL, NULL }
-};
-
-static int msn_soap_memlist_handle_response(struct msn_soap_req_data *soap_req)
-{
- msn_soap_addressbook_request(soap_req->ic);
-
- return MSN_SOAP_OK;
-}
-
-static int msn_soap_memlist_free_data(struct msn_soap_req_data *soap_req)
-{
- return 0;
-}
-
-int msn_soap_memlist_request(struct im_connection *ic)
-{
- return msn_soap_start(ic, NULL, msn_soap_memlist_build_request,
- msn_soap_memlist_parser,
- msn_soap_memlist_handle_response,
- msn_soap_memlist_free_data);
-}
-
-/* Variant: Adding/Removing people */
-struct msn_soap_memlist_edit_data {
- char *handle;
- gboolean add;
- msn_buddy_flags_t list;
-};
-
-static int msn_soap_memlist_edit_build_request(struct msn_soap_req_data *soap_req)
-{
- struct msn_data *md = soap_req->ic->proto_data;
- struct msn_soap_memlist_edit_data *med = soap_req->data;
- char *add, *scenario, *list;
-
- soap_req->url = g_strdup(SOAP_MEMLIST_URL);
- if (med->add) {
- soap_req->action = g_strdup(SOAP_MEMLIST_ADD_ACTION);
- add = "Add";
- } else {
- soap_req->action = g_strdup(SOAP_MEMLIST_DEL_ACTION);
- add = "Delete";
- }
- switch (med->list) {
- case MSN_BUDDY_AL:
- scenario = "BlockUnblock";
- list = "Allow";
- break;
- case MSN_BUDDY_BL:
- scenario = "BlockUnblock";
- list = "Block";
- break;
- case MSN_BUDDY_RL:
- scenario = "Timer";
- list = "Reverse";
- break;
- case MSN_BUDDY_PL:
- default:
- scenario = "Timer";
- list = "Pending";
- break;
- }
- soap_req->payload = msn_soap_abservice_build(SOAP_MEMLIST_EDIT_PAYLOAD,
- scenario, md->tokens[1], add, list, med->handle, add);
-
- return 1;
-}
-
-static int msn_soap_memlist_edit_handle_response(struct msn_soap_req_data *soap_req)
-{
- return MSN_SOAP_OK;
-}
-
-static int msn_soap_memlist_edit_free_data(struct msn_soap_req_data *soap_req)
-{
- struct msn_soap_memlist_edit_data *med = soap_req->data;
-
- g_free(med->handle);
- g_free(med);
-
- return 0;
-}
-
-int msn_soap_memlist_edit(struct im_connection *ic, const char *handle, gboolean add, int list)
-{
- struct msn_soap_memlist_edit_data *med;
-
- med = g_new0(struct msn_soap_memlist_edit_data, 1);
- med->handle = g_strdup(handle);
- med->add = add;
- med->list = list;
-
- return msn_soap_start(ic, med, msn_soap_memlist_edit_build_request,
- NULL,
- msn_soap_memlist_edit_handle_response,
- msn_soap_memlist_edit_free_data);
-}
-
-
-/* addressbook: Fetching the membership list (NOT address book) */
-
-static int msn_soap_addressbook_build_request(struct msn_soap_req_data *soap_req)
-{
- struct msn_data *md = soap_req->ic->proto_data;
-
- soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL);
- soap_req->action = g_strdup(SOAP_ADDRESSBOOK_ACTION);
- soap_req->payload = msn_soap_abservice_build(SOAP_ADDRESSBOOK_PAYLOAD, "Initial", md->tokens[1]);
-
- return 1;
-}
-
-static xt_status msn_soap_addressbook_group(struct xt_node *node, gpointer data)
-{
- struct xt_node *p;
- char *id = NULL, *name = NULL;
- struct msn_soap_req_data *soap_req = data;
- struct msn_data *md = soap_req->ic->proto_data;
-
- if ((p = xt_find_path(node, "../groupId"))) {
- id = p->text;
- }
-
- if ((p = xt_find_node(node->children, "name"))) {
- name = p->text;
- }
-
- if (id && name) {
- struct msn_group *mg = g_new0(struct msn_group, 1);
- mg->id = g_strdup(id);
- mg->name = g_strdup(name);
- md->groups = g_slist_prepend(md->groups, mg);
- }
-
- if (getenv("BITLBEE_DEBUG")) {
- fprintf(stderr, "%s %s\n", id, name);
- }
-
- return XT_HANDLED;
-}
-
-static xt_status msn_soap_addressbook_contact(struct xt_node *node, gpointer data)
-{
- bee_user_t *bu;
- struct msn_buddy_data *bd;
- struct xt_node *p;
- char *id = NULL, *type = NULL, *handle = NULL, *is_msgr = "false",
- *display_name = NULL, *group_id = NULL;
- struct msn_soap_req_data *soap_req = data;
- struct im_connection *ic = soap_req->ic;
- struct msn_group *group;
-
- if ((p = xt_find_path(node, "../contactId"))) {
- id = p->text;
- }
- if ((p = xt_find_node(node->children, "contactType"))) {
- type = p->text;
- }
- if ((p = xt_find_node(node->children, "passportName"))) {
- handle = p->text;
- }
- if ((p = xt_find_node(node->children, "displayName"))) {
- display_name = p->text;
- }
- if ((p = xt_find_node(node->children, "isMessengerUser"))) {
- is_msgr = p->text;
- }
- if ((p = xt_find_path(node, "groupIds/guid"))) {
- group_id = p->text;
- }
-
- if (type && g_strcasecmp(type, "me") == 0) {
- set_t *set = set_find(&ic->acc->set, "display_name");
- g_free(set->value);
- set->value = g_strdup(display_name);
-
- /* Try to fetch the profile; if the user has one, that's where
- we can find the persistent display_name. */
- if ((p = xt_find_node(node->children, "CID")) && p->text) {
- msn_soap_profile_get(ic, p->text);
- }
-
- return XT_HANDLED;
- }
-
- if (!bool2int(is_msgr) || handle == NULL) {
- return XT_HANDLED;
- }
-
- if (!(bu = bee_user_by_handle(ic->bee, ic, handle)) &&
- !(bu = bee_user_new(ic->bee, ic, handle, 0))) {
- return XT_HANDLED;
- }
-
- bd = bu->data;
- bd->flags |= MSN_BUDDY_FL;
- g_free(bd->cid);
- bd->cid = g_strdup(id);
-
- imcb_rename_buddy(ic, handle, display_name);
-
- if (group_id && (group = msn_group_by_id(ic, group_id))) {
- imcb_add_buddy(ic, handle, group->name);
- }
-
- if (getenv("BITLBEE_DEBUG")) {
- fprintf(stderr, "%s %s %s %s\n", id, type, handle, display_name);
- }
-
- return XT_HANDLED;
-}
-
-static const struct xt_handler_entry msn_soap_addressbook_parser[] = {
- { "contactInfo", "Contact", msn_soap_addressbook_contact },
- { "groupInfo", "Group", msn_soap_addressbook_group },
- { NULL, NULL, NULL }
-};
-
-static int msn_soap_addressbook_handle_response(struct msn_soap_req_data *soap_req)
-{
- GSList *l;
- int wtf = 0;
-
- for (l = soap_req->ic->bee->users; l; l = l->next) {
- struct bee_user *bu = l->data;
- struct msn_buddy_data *bd = bu->data;
-
- if (bu->ic == soap_req->ic && bd) {
- msn_buddy_ask(bu);
-
- if ((bd->flags & (MSN_BUDDY_AL | MSN_BUDDY_BL)) ==
- (MSN_BUDDY_AL | MSN_BUDDY_BL)) {
- /* both allow and block, delete block, add wtf */
- bd->flags &= ~MSN_BUDDY_BL;
- wtf++;
- }
-
-
- if ((bd->flags & (MSN_BUDDY_AL | MSN_BUDDY_BL)) == 0) {
- /* neither allow or block, add allow */
- bd->flags |= MSN_BUDDY_AL;
- }
- }
- }
-
- if (wtf) {
- imcb_log(soap_req->ic, "Warning: %d contacts were in both your "
- "block and your allow list. Assuming they're all "
- "allowed.", wtf);
- }
-
- msn_auth_got_contact_list(soap_req->ic);
-
- return MSN_SOAP_OK;
-}
-
-static int msn_soap_addressbook_free_data(struct msn_soap_req_data *soap_req)
-{
- return 0;
-}
-
-int msn_soap_addressbook_request(struct im_connection *ic)
-{
- return msn_soap_start(ic, NULL, msn_soap_addressbook_build_request,
- msn_soap_addressbook_parser,
- msn_soap_addressbook_handle_response,
- msn_soap_addressbook_free_data);
-}
-
-/* Variant: Change our display name. */
-static int msn_soap_ab_namechange_build_request(struct msn_soap_req_data *soap_req)
-{
- struct msn_data *md = soap_req->ic->proto_data;
-
- soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL);
- soap_req->action = g_strdup(SOAP_AB_NAMECHANGE_ACTION);
- soap_req->payload = msn_soap_abservice_build(SOAP_AB_NAMECHANGE_PAYLOAD,
- "Timer", md->tokens[1], (char *) soap_req->data);
-
- return 1;
-}
-
-static int msn_soap_ab_namechange_handle_response(struct msn_soap_req_data *soap_req)
-{
- /* TODO: Ack the change? Not sure what the NAKs look like.. */
- return MSN_SOAP_OK;
-}
-
-static int msn_soap_ab_namechange_free_data(struct msn_soap_req_data *soap_req)
-{
- g_free(soap_req->data);
- return 0;
-}
-
-int msn_soap_addressbook_set_display_name(struct im_connection *ic, const char *new)
-{
- return msn_soap_start(ic, g_strdup(new),
- msn_soap_ab_namechange_build_request,
- NULL,
- msn_soap_ab_namechange_handle_response,
- msn_soap_ab_namechange_free_data);
-}
-
-/* Add a contact. */
-static int msn_soap_ab_contact_add_build_request(struct msn_soap_req_data *soap_req)
-{
- struct msn_data *md = soap_req->ic->proto_data;
- bee_user_t *bu = soap_req->data;
-
- soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL);
- soap_req->action = g_strdup(SOAP_AB_CONTACT_ADD_ACTION);
- soap_req->payload = msn_soap_abservice_build(SOAP_AB_CONTACT_ADD_PAYLOAD,
- "ContactSave", md->tokens[1], bu->handle,
- bu->fullname ? bu->fullname : bu->handle);
-
- return 1;
-}
-
-static xt_status msn_soap_ab_contact_add_cid(struct xt_node *node, gpointer data)
-{
- struct msn_soap_req_data *soap_req = data;
- bee_user_t *bu = soap_req->data;
- struct msn_buddy_data *bd = bu->data;
-
- g_free(bd->cid);
- bd->cid = g_strdup(node->text);
-
- return XT_HANDLED;
-}
-
-static const struct xt_handler_entry msn_soap_ab_contact_add_parser[] = {
- { "guid", "ABContactAddResult", msn_soap_ab_contact_add_cid },
- { NULL, NULL, NULL }
-};
-
-static int msn_soap_ab_contact_add_handle_response(struct msn_soap_req_data *soap_req)
-{
- /* TODO: Ack the change? Not sure what the NAKs look like.. */
- return MSN_SOAP_OK;
-}
-
-static int msn_soap_ab_contact_add_free_data(struct msn_soap_req_data *soap_req)
-{
- return 0;
-}
-
-int msn_soap_ab_contact_add(struct im_connection *ic, bee_user_t *bu)
-{
- return msn_soap_start(ic, bu,
- msn_soap_ab_contact_add_build_request,
- msn_soap_ab_contact_add_parser,
- msn_soap_ab_contact_add_handle_response,
- msn_soap_ab_contact_add_free_data);
-}
-
-/* Remove a contact. */
-static int msn_soap_ab_contact_del_build_request(struct msn_soap_req_data *soap_req)
-{
- struct msn_data *md = soap_req->ic->proto_data;
- const char *cid = soap_req->data;
-
- soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL);
- soap_req->action = g_strdup(SOAP_AB_CONTACT_DEL_ACTION);
- soap_req->payload = msn_soap_abservice_build(SOAP_AB_CONTACT_DEL_PAYLOAD,
- "Timer", md->tokens[1], cid);
-
- return 1;
-}
-
-static int msn_soap_ab_contact_del_handle_response(struct msn_soap_req_data *soap_req)
-{
- /* TODO: Ack the change? Not sure what the NAKs look like.. */
- return MSN_SOAP_OK;
-}
-
-static int msn_soap_ab_contact_del_free_data(struct msn_soap_req_data *soap_req)
-{
- g_free(soap_req->data);
- return 0;
-}
-
-int msn_soap_ab_contact_del(struct im_connection *ic, bee_user_t *bu)
-{
- struct msn_buddy_data *bd = bu->data;
-
- return msn_soap_start(ic, g_strdup(bd->cid),
- msn_soap_ab_contact_del_build_request,
- NULL,
- msn_soap_ab_contact_del_handle_response,
- msn_soap_ab_contact_del_free_data);
-}
-
-
-
-/* Storage stuff: Fetch profile. */
-static int msn_soap_profile_get_build_request(struct msn_soap_req_data *soap_req)
-{
- struct msn_data *md = soap_req->ic->proto_data;
-
- soap_req->url = g_strdup(SOAP_STORAGE_URL);
- soap_req->action = g_strdup(SOAP_PROFILE_GET_ACTION);
- soap_req->payload = g_markup_printf_escaped(SOAP_PROFILE_GET_PAYLOAD,
- md->tokens[3], (char *) soap_req->data);
-
- return 1;
-}
-
-static xt_status msn_soap_profile_get_result(struct xt_node *node, gpointer data)
-{
- struct msn_soap_req_data *soap_req = data;
- struct im_connection *ic = soap_req->ic;
- struct msn_data *md = soap_req->ic->proto_data;
- struct xt_node *dn;
-
- if ((dn = xt_find_node(node->children, "DisplayName")) && dn->text) {
- set_t *set = set_find(&ic->acc->set, "display_name");
- g_free(set->value);
- set->value = g_strdup(dn->text);
-
- md->flags |= MSN_GOT_PROFILE_DN;
- }
-
- return XT_HANDLED;
-}
-
-static xt_status msn_soap_profile_get_rid(struct xt_node *node, gpointer data)
-{
- struct msn_soap_req_data *soap_req = data;
- struct msn_data *md = soap_req->ic->proto_data;
-
- g_free(md->profile_rid);
- md->profile_rid = g_strdup(node->text);
-
- return XT_HANDLED;
-}
-
-static const struct xt_handler_entry msn_soap_profile_get_parser[] = {
- { "ExpressionProfile", "GetProfileResult", msn_soap_profile_get_result },
- { "ResourceID", "GetProfileResult", msn_soap_profile_get_rid },
- { NULL, NULL, NULL }
-};
-
-static int msn_soap_profile_get_handle_response(struct msn_soap_req_data *soap_req)
-{
- struct msn_data *md = soap_req->ic->proto_data;
-
- md->flags |= MSN_GOT_PROFILE;
- msn_ns_finish_login(soap_req->ic);
-
- return MSN_SOAP_OK;
-}
-
-static int msn_soap_profile_get_free_data(struct msn_soap_req_data *soap_req)
-{
- g_free(soap_req->data);
- return 0;
-}
-
-int msn_soap_profile_get(struct im_connection *ic, const char *cid)
-{
- return msn_soap_start(ic, g_strdup(cid),
- msn_soap_profile_get_build_request,
- msn_soap_profile_get_parser,
- msn_soap_profile_get_handle_response,
- msn_soap_profile_get_free_data);
-}
-
-/* Update profile (display name). */
-static int msn_soap_profile_set_dn_build_request(struct msn_soap_req_data *soap_req)
-{
- struct msn_data *md = soap_req->ic->proto_data;
-
- soap_req->url = g_strdup(SOAP_STORAGE_URL);
- soap_req->action = g_strdup(SOAP_PROFILE_SET_DN_ACTION);
- soap_req->payload = g_markup_printf_escaped(SOAP_PROFILE_SET_DN_PAYLOAD,
- md->tokens[3], md->profile_rid, (char *) soap_req->data);
-
- return 1;
-}
-
-static const struct xt_handler_entry msn_soap_profile_set_dn_parser[] = {
- { NULL, NULL, NULL }
-};
-
-static int msn_soap_profile_set_dn_handle_response(struct msn_soap_req_data *soap_req)
-{
- return MSN_SOAP_OK;
-}
-
-static int msn_soap_profile_set_dn_free_data(struct msn_soap_req_data *soap_req)
-{
- g_free(soap_req->data);
- return 0;
-}
-
-int msn_soap_profile_set_dn(struct im_connection *ic, const char *dn)
-{
- return msn_soap_start(ic, g_strdup(dn),
- msn_soap_profile_set_dn_build_request,
- msn_soap_profile_set_dn_parser,
- msn_soap_profile_set_dn_handle_response,
- msn_soap_profile_set_dn_free_data);
-}
diff --git a/protocols/msn/soap.h b/protocols/msn/soap.h
deleted file mode 100644
index 27cfa0cb..00000000
--- a/protocols/msn/soap.h
+++ /dev/null
@@ -1,341 +0,0 @@
-/********************************************************************\
- * BitlBee -- An IRC to other IM-networks gateway *
- * *
- * Copyright 2002-2012 Wilmer van der Gaast and others *
- \********************************************************************/
-
-/* MSN module - All the SOAPy XML stuff.
- Some manager at Microsoft apparently thought MSNP wasn't XMLy enough so
- someone stepped up and changed that. This is the result. Kilobytes and
- more kilobytes of XML vomit to transfer tiny bits of informaiton. */
-
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT 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 with
- the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
- if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
- Fifth Floor, Boston, MA 02110-1301 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>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include "nogaim.h"
-
-
-int msn_soapq_flush(struct im_connection *ic, gboolean resend);
-
-
-#define SOAP_HTTP_REQUEST \
- "POST %s HTTP/1.0\r\n" \
- "Host: %s\r\n" \
- "Accept: */*\r\n" \
- "User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \
- "Content-Type: text/xml; charset=utf-8\r\n" \
- "%s" \
- "Content-Length: %zd\r\n" \
- "Cache-Control: no-cache\r\n" \
- "\r\n" \
- "%s"
-
-
-#define SOAP_PASSPORT_SSO_URL "https://login.live.com/RST.srf"
-#define SOAP_PASSPORT_SSO_URL_MSN "https://msnia.login.live.com/pp900/RST.srf"
-
-#define SOAP_PASSPORT_SSO_PAYLOAD \
- "<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\" " \
- "xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" " \
- "xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" " \
- "xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\" " \
- "xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" " \
- "xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\" " \
- "xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2004/04/sc\" " \
- "xmlns:wst=\"http://schemas.xmlsoap.org/ws/2004/04/trust\">" \
- "<Header>" \
- "<ps:AuthInfo " \
- "xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" " \
- "Id=\"PPAuthInfo\">" \
- "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>" \
- "<ps:BinaryVersion>4</ps:BinaryVersion>" \
- "<ps:UIVersion>1</ps:UIVersion>" \
- "<ps:Cookies></ps:Cookies>" \
- "<ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>" \
- "</ps:AuthInfo>" \
- "<wsse:Security>" \
- "<wsse:UsernameToken Id=\"user\">" \
- "<wsse:Username>%s</wsse:Username>" \
- "<wsse:Password>%s</wsse:Password>" \
- "</wsse:UsernameToken>" \
- "</wsse:Security>" \
- "</Header>" \
- "<Body>" \
- "<ps:RequestMultipleSecurityTokens " \
- "xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" " \
- "Id=\"RSTS\">" \
- "<wst:RequestSecurityToken Id=\"RST0\">" \
- "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \
- "<wsp:AppliesTo>" \
- "<wsa:EndpointReference>" \
- "<wsa:Address>http://Passport.NET/tb</wsa:Address>" \
- "</wsa:EndpointReference>" \
- "</wsp:AppliesTo>" \
- "</wst:RequestSecurityToken>" \
- "<wst:RequestSecurityToken Id=\"RST1\">" \
- "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \
- "<wsp:AppliesTo>" \
- "<wsa:EndpointReference>" \
- "<wsa:Address>messengerclear.live.com</wsa:Address>" \
- "</wsa:EndpointReference>" \
- "</wsp:AppliesTo>" \
- "<wsse:PolicyReference URI=\"%s\"></wsse:PolicyReference>" \
- "</wst:RequestSecurityToken>" \
- "<wst:RequestSecurityToken Id=\"RST2\">" \
- "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \
- "<wsp:AppliesTo>" \
- "<wsa:EndpointReference>" \
- "<wsa:Address>contacts.msn.com</wsa:Address>" \
- "</wsa:EndpointReference>" \
- "</wsp:AppliesTo>" \
- "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI\"></wsse:PolicyReference>" \
- "</wst:RequestSecurityToken>" \
- "<wst:RequestSecurityToken Id=\"RST3\">" \
- "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \
- "<wsp:AppliesTo>" \
- "<wsa:EndpointReference>" \
- "<wsa:Address>messengersecure.live.com</wsa:Address>" \
- "</wsa:EndpointReference>" \
- "</wsp:AppliesTo>" \
- "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI_SSL\"></wsse:PolicyReference>" \
- "</wst:RequestSecurityToken>" \
- "<wst:RequestSecurityToken Id=\"RST4\">" \
- "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \
- "<wsp:AppliesTo>" \
- "<wsa:EndpointReference>" \
- "<wsa:Address>storage.msn.com</wsa:Address>" \
- "</wsa:EndpointReference>" \
- "</wsp:AppliesTo>" \
- "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI_SSL\"></wsse:PolicyReference>" \
- "</wst:RequestSecurityToken>" \
- "</ps:RequestMultipleSecurityTokens>" \
- "</Body>" \
- "</Envelope>"
-
-int msn_soap_passport_sso_request(struct im_connection *ic, const char *nonce);
-
-
-#define SOAP_ABSERVICE_PAYLOAD \
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>" \
- "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
- "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<ApplicationId xmlns=\"http://www.msn.com/webservices/AddressBook\">F6D2794D-501F-443A-ADBE-8F1490FF30FD</ApplicationId>" \
- "<IsMigration xmlns=\"http://www.msn.com/webservices/AddressBook\">false</IsMigration>" \
- "<PartnerScenario xmlns=\"http://www.msn.com/webservices/AddressBook\">%s</PartnerScenario>" \
- "</ABApplicationHeader>" \
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<ManagedGroupRequest xmlns=\"http://www.msn.com/webservices/AddressBook\">false</ManagedGroupRequest>" \
- "<TicketToken>%s</TicketToken>" \
- "</ABAuthHeader>" \
- "</soap:Header>" \
- "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
- "%%s" \
- "</soap:Body>" \
- "</soap:Envelope>"
-
-#define SOAP_MEMLIST_URL "http://contacts.msn.com/abservice/SharingService.asmx"
-#define SOAP_MEMLIST_ACTION "http://www.msn.com/webservices/AddressBook/FindMembership"
-
-#define SOAP_MEMLIST_PAYLOAD \
- "<FindMembership xmlns=\"http://www.msn.com/webservices/AddressBook\"><serviceFilter><Types><ServiceType>Messenger</ServiceType><ServiceType>IMAvailability</ServiceType></Types></serviceFilter><expandMembership>true</expandMembership>" \
- "</FindMembership>"
-
-#define SOAP_MEMLIST_ADD_ACTION "http://www.msn.com/webservices/AddressBook/AddMember"
-#define SOAP_MEMLIST_DEL_ACTION "http://www.msn.com/webservices/AddressBook/DeleteMember"
-
-#define SOAP_MEMLIST_EDIT_PAYLOAD \
- "<%sMember xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<serviceHandle>" \
- "<Id>0</Id>" \
- "<Type>Messenger</Type>" \
- "<ForeignId></ForeignId>" \
- "</serviceHandle>" \
- "<memberships>" \
- "<Membership>" \
- "<MemberRole>%s</MemberRole>" \
- "<Members>" \
- "<Member xsi:type=\"PassportMember\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" \
- "<Type>Passport</Type>" \
- "<State>Accepted</State>" \
- "<PassportName>%s</PassportName>" \
- "</Member>" \
- "</Members>" \
- "</Membership>" \
- "</memberships>" \
- "</%sMember>"
-
-int msn_soap_memlist_request(struct im_connection *ic);
-int msn_soap_memlist_edit(struct im_connection *ic, const char *handle, gboolean add, int list);
-
-
-#define SOAP_ADDRESSBOOK_URL "http://contacts.msn.com/abservice/abservice.asmx"
-#define SOAP_ADDRESSBOOK_ACTION "http://www.msn.com/webservices/AddressBook/ABFindAll"
-
-#define SOAP_ADDRESSBOOK_PAYLOAD \
- "<ABFindAll xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<abId>00000000-0000-0000-0000-000000000000</abId>" \
- "<abView>Full</abView>" \
- "<deltasOnly>false</deltasOnly>" \
- "<lastChange>0001-01-01T00:00:00.0000000-08:00</lastChange>" \
- "</ABFindAll>"
-
-#define SOAP_AB_NAMECHANGE_ACTION "http://www.msn.com/webservices/AddressBook/ABContactUpdate"
-
-#define SOAP_AB_NAMECHANGE_PAYLOAD \
- "<ABContactUpdate xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<abId>00000000-0000-0000-0000-000000000000</abId>" \
- "<contacts>" \
- "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<contactInfo>" \
- "<contactType>Me</contactType>" \
- "<displayName>%s</displayName>" \
- "</contactInfo>" \
- "<propertiesChanged>DisplayName</propertiesChanged>" \
- "</Contact>" \
- "</contacts>" \
- "</ABContactUpdate>"
-
-#define SOAP_AB_CONTACT_ADD_ACTION "http://www.msn.com/webservices/AddressBook/ABContactAdd"
-
-#define SOAP_AB_CONTACT_ADD_PAYLOAD \
- "<ABContactAdd xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<abId>00000000-0000-0000-0000-000000000000</abId>" \
- "<contacts>" \
- "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<contactInfo>" \
- "<contactType>LivePending</contactType>" \
- "<passportName>%s</passportName>" \
- "<isMessengerUser>true</isMessengerUser>" \
- "<MessengerMemberInfo>" \
- "<DisplayName>%s</DisplayName>" \
- "</MessengerMemberInfo>" \
- "</contactInfo>" \
- "</Contact>" \
- "</contacts>" \
- "<options>" \
- "<EnableAllowListManagement>true</EnableAllowListManagement>" \
- "</options>" \
- "</ABContactAdd>"
-
-#define SOAP_AB_CONTACT_DEL_ACTION "http://www.msn.com/webservices/AddressBook/ABContactDelete"
-
-#define SOAP_AB_CONTACT_DEL_PAYLOAD \
- "<ABContactDelete xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<abId>00000000-0000-0000-0000-000000000000</abId>" \
- "<contacts>" \
- "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \
- "<contactId>%s</contactId>" \
- "</Contact>" \
- "</contacts>" \
- "</ABContactDelete>"
-
-int msn_soap_addressbook_request(struct im_connection *ic);
-int msn_soap_addressbook_set_display_name(struct im_connection *ic, const char *new);
-int msn_soap_ab_contact_add(struct im_connection *ic, bee_user_t *bu);
-int msn_soap_ab_contact_del(struct im_connection *ic, bee_user_t *bu);
-
-
-#define SOAP_STORAGE_URL "https://storage.msn.com/storageservice/SchematizedStore.asmx"
-#define SOAP_PROFILE_GET_ACTION "http://www.msn.com/webservices/storage/w10/GetProfile"
-#define SOAP_PROFILE_SET_DN_ACTION "http://www.msn.com/webservices/storage/w10/UpdateProfile"
-
-#define SOAP_PROFILE_GET_PAYLOAD \
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>" \
- "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
- "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
- "<StorageApplicationHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \
- "<ApplicationID>Messenger Client 9.0</ApplicationID>" \
- "<Scenario>Initial</Scenario>" \
- "</StorageApplicationHeader>" \
- "<StorageUserHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \
- "<Puid>0</Puid>" \
- "<TicketToken>%s</TicketToken>" \
- "</StorageUserHeader>" \
- "</soap:Header>" \
- "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
- "<GetProfile xmlns=\"http://www.msn.com/webservices/storage/w10\">" \
- "<profileHandle>" \
- "<Alias>" \
- "<Name>%s</Name>" \
- "<NameSpace>MyCidStuff</NameSpace>" \
- "</Alias>" \
- "<RelationshipName>MyProfile</RelationshipName>" \
- "</profileHandle>" \
- "<profileAttributes>" \
- "<ResourceID>true</ResourceID>" \
- "<DateModified>true</DateModified>" \
- "<ExpressionProfileAttributes>" \
- "<ResourceID>true</ResourceID>" \
- "<DateModified>true</DateModified>" \
- "<DisplayName>true</DisplayName>" \
- "<DisplayNameLastModified>true</DisplayNameLastModified>" \
- "<PersonalStatus>true</PersonalStatus>" \
- "<PersonalStatusLastModified>true</PersonalStatusLastModified>" \
- "<StaticUserTilePublicURL>true</StaticUserTilePublicURL>" \
- "<Photo>true</Photo>" \
- "<Flags>true</Flags>" \
- "</ExpressionProfileAttributes>" \
- "</profileAttributes>" \
- "</GetProfile>" \
- "</soap:Body>" \
- "</soap:Envelope>"
-
-#define SOAP_PROFILE_SET_DN_PAYLOAD \
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>" \
- "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
- "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
- "<StorageApplicationHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \
- "<ApplicationID>Messenger Client 9.0</ApplicationID>" \
- "<Scenario>Initial</Scenario>" \
- "</StorageApplicationHeader>" \
- "<StorageUserHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \
- "<Puid>0</Puid>" \
- "<TicketToken>%s</TicketToken>" \
- "</StorageUserHeader>" \
- "</soap:Header>" \
- "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
- "<UpdateProfile xmlns=\"http://www.msn.com/webservices/storage/w10\">" \
- "<profile>" \
- "<ResourceID>%s</ResourceID>" \
- "<ExpressionProfile>" \
- "<FreeText>Update</FreeText>" \
- "<DisplayName>%s</DisplayName>" \
- "<Flags>0</Flags>" \
- "</ExpressionProfile>" \
- "</profile>" \
- "</UpdateProfile>" \
- "</soap:Body>" \
- "</soap:Envelope>"
-
-int msn_soap_profile_get(struct im_connection *ic, const char *cid);
-int msn_soap_profile_set_dn(struct im_connection *ic, const char *dn);
-
-#endif /* __SOAP_H__ */
diff --git a/protocols/msn/tables.c b/protocols/msn/tables.c
deleted file mode 100644
index 712116e5..00000000
--- a/protocols/msn/tables.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/********************************************************************\
- * BitlBee -- An IRC to other IM-networks gateway *
- * *
- * Copyright 2002-2010 Wilmer van der Gaast and others *
- \********************************************************************/
-
-/* MSN module - Some tables with useful data */
-
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT 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 with
- the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
- if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
- Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include "nogaim.h"
-#include "msn.h"
-
-const struct msn_away_state msn_away_state_list[] =
-{
- { "NLN", "" },
- { "AWY", "Away" },
- { "BSY", "Busy" },
- { "IDL", "Idle" },
- { "BRB", "Be Right Back" },
- { "PHN", "On the Phone" },
- { "LUN", "Out to Lunch" },
- { "HDN", "Hidden" },
- { "", "" }
-};
-
-const struct msn_away_state *msn_away_state_by_code(char *code)
-{
- int i;
-
- for (i = 0; *msn_away_state_list[i].code; i++) {
- if (g_strcasecmp(msn_away_state_list[i].code, code) == 0) {
- return(msn_away_state_list + i);
- }
- }
-
- return NULL;
-}
-
-const struct msn_away_state *msn_away_state_by_name(char *name)
-{
- int i;
-
- for (i = 0; *msn_away_state_list[i].code; i++) {
- if (g_strcasecmp(msn_away_state_list[i].name, name) == 0) {
- return(msn_away_state_list + i);
- }
- }
-
- return NULL;
-}
-
-const struct msn_status_code msn_status_code_list[] =
-{
- { 200, "Invalid syntax", 0 },
- { 201, "Invalid parameter", 0 },
- { 205, "Invalid (non-existent) handle", 0 },
- { 206, "Domain name missing", 0 },
- { 207, "Already logged in", 0 },
- { 208, "Invalid handle", 0 },
- { 209, "Forbidden nickname", 0 },
- { 210, "Buddy list too long", 0 },
- { 215, "Handle is already in list", 0 },
- { 216, "Handle is not in list", 0 },
- { 217, "Person is off-line or non-existent", 0 },
- { 218, "Already in that mode", 0 },
- { 219, "Handle is already in opposite list", 0 },
- { 223, "Too many groups", 0 },
- { 224, "Invalid group or already in list", 0 },
- { 225, "Handle is not in that group", 0 },
- { 229, "Group name too long", 0 },
- { 230, "Cannot remove that group", 0 },
- { 231, "Invalid group", 0 },
- { 240, "ADL/RML command with corrupted payload", STATUS_FATAL },
- { 241, "ADL/RML command with invalid modification", 0 },
- { 280, "Switchboard failed", STATUS_SB_FATAL },
- { 281, "Transfer to switchboard failed", 0 },
-
- { 300, "Required field missing", 0 },
- { 302, "Not logged in", 0 },
-
- { 500, "Internal server error/Account banned", STATUS_FATAL },
- { 501, "Database server error", STATUS_FATAL },
- { 502, "Command disabled", 0 },
- { 510, "File operation failed", STATUS_FATAL },
- { 520, "Memory allocation failed", STATUS_FATAL },
- { 540, "Challenge response invalid", STATUS_FATAL },
-
- { 600, "Server is busy", STATUS_FATAL },
- { 601, "Server is unavailable", STATUS_FATAL },
- { 602, "Peer nameserver is down", STATUS_FATAL },
- { 603, "Database connection failed", STATUS_FATAL },
- { 604, "Server is going down", STATUS_FATAL },
- { 605, "Server is unavailable", STATUS_FATAL },
-
- { 700, "Could not create connection", STATUS_FATAL },
- { 710, "Invalid CVR parameters", STATUS_FATAL },
- { 711, "Write is blocking", STATUS_FATAL },
- { 712, "Session is overloaded", STATUS_FATAL },
- { 713, "Calling too rapidly", 0 },
- { 714, "Too many sessions", STATUS_FATAL },
- { 715, "Not expected/Invalid argument/action", 0 },
- { 717, "Bad friend file", STATUS_FATAL },
- { 731, "Not expected/Invalid argument", 0 },
-
- { 800, "Changing too rapidly", 0 },
-
- { 910, "Server is busy", STATUS_FATAL },
- { 911, "Authentication failed", STATUS_SB_FATAL | STATUS_FATAL },
- { 912, "Server is busy", STATUS_FATAL },
- { 913, "Not allowed when hiding", 0 },
- { 914, "Server is unavailable", STATUS_FATAL },
- { 915, "Server is unavailable", STATUS_FATAL },
- { 916, "Server is unavailable", STATUS_FATAL },
- { 917, "Authentication failed", STATUS_FATAL },
- { 918, "Server is busy", STATUS_FATAL },
- { 919, "Server is busy", STATUS_FATAL },
- { 920, "Not accepting new principals", 0 }, /* When a sb is full? */
- { 922, "Server is busy", STATUS_FATAL },
- { 923, "Kids Passport without parental consent", STATUS_FATAL },
- { 924, "Passport account not yet verified", STATUS_FATAL },
- { 928, "Bad ticket", STATUS_FATAL },
- { -1, NULL, 0 }
-};
-
-const struct msn_status_code *msn_status_by_number(int number)
-{
- static struct msn_status_code *unknown = NULL;
- int i;
-
- for (i = 0; msn_status_code_list[i].number >= 0; i++) {
- if (msn_status_code_list[i].number == number) {
- return(msn_status_code_list + i);
- }
- }
-
- if (unknown == NULL) {
- unknown = g_new0(struct msn_status_code, 1);
- unknown->text = g_new0(char, 128);
- }
-
- unknown->number = number;
- unknown->flags = 0;
- g_snprintf(unknown->text, 128, "Unknown error (%d)", number);
-
- return(unknown);
-}
diff --git a/protocols/nogaim.c b/protocols/nogaim.c
index 58f74f8b..cb2d62a9 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -253,16 +253,11 @@ char *explain_unknown_protocol(const char *name)
void nogaim_init()
{
- extern void msn_initmodule();
extern void oscar_initmodule();
extern void jabber_initmodule();
extern void twitter_initmodule();
extern void purple_initmodule();
-#ifdef WITH_MSN
- msn_initmodule();
-#endif
-
#ifdef WITH_OSCAR
oscar_initmodule();
#endif