aboutsummaryrefslogtreecommitdiffstats
path: root/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Makefile2
-rw-r--r--protocols/jabber/Makefile4
-rw-r--r--protocols/jabber/io.c12
-rw-r--r--protocols/jabber/iq.c27
-rw-r--r--protocols/jabber/jabber.c1
-rw-r--r--protocols/jabber/jabber_util.c8
-rw-r--r--protocols/jabber/sasl.c27
-rw-r--r--protocols/jabber/xmltree.c589
-rw-r--r--protocols/jabber/xmltree.h97
-rw-r--r--protocols/msn/Makefile2
-rw-r--r--protocols/msn/msn.h2
-rw-r--r--protocols/msn/msn_util.c8
-rw-r--r--protocols/msn/ns.c30
-rw-r--r--protocols/msn/passport.c280
-rw-r--r--protocols/msn/passport.h93
-rw-r--r--protocols/nogaim.c17
-rw-r--r--protocols/nogaim.h3
-rw-r--r--protocols/oscar/Makefile2
-rw-r--r--protocols/oscar/oscar.c18
-rw-r--r--protocols/yahoo/Makefile2
-rw-r--r--protocols/yahoo/libyahoo2.c4
-rw-r--r--protocols/yahoo/yahoo.c10
22 files changed, 314 insertions, 924 deletions
diff --git a/protocols/Makefile b/protocols/Makefile
index f7d76e0f..18d79e8d 100644
--- a/protocols/Makefile
+++ b/protocols/Makefile
@@ -26,7 +26,7 @@ LFLAGS += -r
# [SH] Phony targets
all: protocols.o
check: all
-lcov:
+lcov: check
gcov:
gcov *.c
diff --git a/protocols/jabber/Makefile b/protocols/jabber/Makefile
index 21d7ef07..891df5eb 100644
--- a/protocols/jabber/Makefile
+++ b/protocols/jabber/Makefile
@@ -9,7 +9,7 @@
-include ../../Makefile.settings
# [SH] Program variables
-objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o si.o s5bytestream.o
+objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o si.o s5bytestream.o
CFLAGS += -Wall
LFLAGS += -r
@@ -17,7 +17,7 @@ LFLAGS += -r
# [SH] Phony targets
all: jabber_mod.o
check: all
-lcov:
+lcov: check
gcov:
gcov *.c
diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c
index 86c216ef..10efad37 100644
--- a/protocols/jabber/io.c
+++ b/protocols/jabber/io.c
@@ -240,8 +240,13 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition
return FALSE;
}
- /* EAGAIN/etc or a successful read. */
- return TRUE;
+ if( ssl_pending( jd->ssl ) )
+ /* OpenSSL empties the TCP buffers completely but may keep some
+ data in its internap buffers. select() won't see that, but
+ ssl_pending() does. */
+ return jabber_read_callback( data, fd, cond );
+ else
+ return TRUE;
}
gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition cond )
@@ -520,8 +525,7 @@ gboolean jabber_start_stream( struct im_connection *ic )
/* We'll start our stream now, so prepare everything to receive one
from the server too. */
xt_free( jd->xt ); /* In case we're RE-starting. */
- jd->xt = xt_new( ic );
- jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers;
+ jd->xt = xt_new( jabber_handlers, ic );
if( jd->r_inpa <= 0 )
jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, ic );
diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c
index d45b7625..22aa3e7c 100644
--- a/protocols/jabber/iq.c
+++ b/protocols/jabber/iq.c
@@ -533,6 +533,8 @@ static xt_status jabber_iq_display_vcard( struct im_connection *ic, struct xt_no
return XT_HANDLED;
}
+static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
+
int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name )
{
struct xt_node *node;
@@ -548,13 +550,36 @@ int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name )
node = xt_new_node( "query", NULL, node );
xt_add_attr( node, "xmlns", XMLNS_ROSTER );
node = jabber_make_packet( "iq", "set", NULL, node );
+ jabber_cache_add( ic, node, jabber_add_to_roster_callback );
st = jabber_write_packet( ic, node );
- xt_free_node( node );
return st;
}
+static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
+{
+ char *s, *jid = NULL;
+ struct xt_node *c;
+
+ if( ( c = xt_find_node( orig->children, "query" ) ) &&
+ ( c = xt_find_node( c->children, "item" ) ) &&
+ ( jid = xt_find_attr( c, "jid" ) ) &&
+ ( s = xt_find_attr( node, "type" ) ) &&
+ strcmp( s, "result" ) == 0 )
+ {
+ if( imcb_find_buddy( ic, jid ) == NULL )
+ imcb_add_buddy( ic, jid, NULL );
+ }
+ else
+ {
+ imcb_log( ic, "Error while adding `%s' to your contact list.",
+ jid ? jid : "(unknown handle)" );
+ }
+
+ return XT_HANDLED;
+}
+
int jabber_remove_from_roster( struct im_connection *ic, char *handle )
{
struct xt_node *node;
diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c
index 07d760a5..04d6f906 100644
--- a/protocols/jabber/jabber.c
+++ b/protocols/jabber/jabber.c
@@ -266,6 +266,7 @@ static void jabber_logout( struct im_connection *ic )
xt_free( jd->xt );
+ g_free( jd->cached_id_prefix );
g_free( jd->away_message );
g_free( jd->username );
g_free( jd );
diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c
index c8470b57..23a3010f 100644
--- a/protocols/jabber/jabber_util.c
+++ b/protocols/jabber/jabber_util.c
@@ -249,8 +249,10 @@ struct jabber_buddy_ask_data
char *realname;
};
-static void jabber_buddy_ask_yes( gpointer w, struct jabber_buddy_ask_data *bla )
+static void jabber_buddy_ask_yes( void *data )
{
+ struct jabber_buddy_ask_data *bla = data;
+
presence_send_request( bla->ic, bla->handle, "subscribed" );
if( imcb_find_buddy( bla->ic, bla->handle ) == NULL )
@@ -260,8 +262,10 @@ static void jabber_buddy_ask_yes( gpointer w, struct jabber_buddy_ask_data *bla
g_free( bla );
}
-static void jabber_buddy_ask_no( gpointer w, struct jabber_buddy_ask_data *bla )
+static void jabber_buddy_ask_no( void *data )
{
+ struct jabber_buddy_ask_data *bla = data;
+
presence_send_request( bla->ic, bla->handle, "subscribed" );
g_free( bla->handle );
diff --git a/protocols/jabber/sasl.c b/protocols/jabber/sasl.c
index 87059051..53248ef3 100644
--- a/protocols/jabber/sasl.c
+++ b/protocols/jabber/sasl.c
@@ -21,6 +21,8 @@
* *
\***************************************************************************/
+#include <ctype.h>
+
#include "jabber.h"
#include "base64.h"
@@ -106,12 +108,17 @@ xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data )
return XT_HANDLED;
}
-static char *sasl_get_part( char *data, char *field )
+/* Non-static function, but not mentioned in jabber.h because it's for internal
+ use, just that the unittest should be able to reach it... */
+char *sasl_get_part( char *data, char *field )
{
int i, len;
len = strlen( field );
+ while( isspace( *data ) || *data == ',' )
+ data ++;
+
if( g_strncasecmp( data, field, len ) == 0 && data[len] == '=' )
{
i = strlen( field ) + 1;
@@ -128,13 +135,19 @@ static char *sasl_get_part( char *data, char *field )
i ++;
}
- /* If we got a comma, we got a new field. Check it. */
- if( data[i] == ',' &&
- g_strncasecmp( data + i + 1, field, len ) == 0 &&
- data[i+len+1] == '=' )
+ /* If we got a comma, we got a new field. Check it,
+ find the next key after it. */
+ if( data[i] == ',' )
{
- i += len + 2;
- break;
+ while( isspace( data[i] ) || data[i] == ',' )
+ i ++;
+
+ if( g_strncasecmp( data + i, field, len ) == 0 &&
+ data[i+len] == '=' )
+ {
+ i += len + 1;
+ break;
+ }
}
}
}
diff --git a/protocols/jabber/xmltree.c b/protocols/jabber/xmltree.c
deleted file mode 100644
index 62549eb5..00000000
--- a/protocols/jabber/xmltree.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/***************************************************************************\
-* *
-* BitlBee - An IRC to IM gateway *
-* Simple XML (stream) parse tree handling code (Jabber/XMPP, mainly) *
-* *
-* Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net> *
-* *
-* This library is free software; you can redistribute it and/or *
-* modify it under the terms of the GNU Lesser General Public *
-* License as published by the Free Software Foundation, version *
-* 2.1. *
-* *
-* This library 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 *
-* Lesser General Public License for more details. *
-* *
-* You should have received a copy of the GNU Lesser General Public License *
-* along with this library; if not, write to the Free Software Foundation, *
-* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
-* *
-****************************************************************************/
-
-#include <glib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <stdio.h>
-
-#include "xmltree.h"
-
-static void xt_start_element( GMarkupParseContext *ctx, const gchar *element_name, const gchar **attr_names, const gchar **attr_values, gpointer data, GError **error )
-{
- struct xt_parser *xt = data;
- struct xt_node *node = g_new0( struct xt_node, 1 ), *nt;
- int i;
-
- node->parent = xt->cur;
- node->name = g_strdup( element_name );
-
- /* First count the number of attributes */
- for( i = 0; attr_names[i]; i ++ );
-
- /* Then allocate a NULL-terminated array. */
- node->attr = g_new0( struct xt_attr, i + 1 );
-
- /* And fill it, saving one variable by starting at the end. */
- for( i --; i >= 0; i -- )
- {
- node->attr[i].key = g_strdup( attr_names[i] );
- node->attr[i].value = g_strdup( attr_values[i] );
- }
-
- /* Add it to the linked list of children nodes, if we have a current
- node yet. */
- if( xt->cur )
- {
- if( xt->cur->children )
- {
- for( nt = xt->cur->children; nt->next; nt = nt->next );
- nt->next = node;
- }
- else
- {
- xt->cur->children = node;
- }
- }
- else if( xt->root )
- {
- /* ERROR situation: A second root-element??? */
- }
-
- /* Now this node will be the new current node. */
- xt->cur = node;
- /* And maybe this is the root? */
- if( xt->root == NULL )
- xt->root = node;
-}
-
-static void xt_text( GMarkupParseContext *ctx, const gchar *text, gsize text_len, gpointer data, GError **error )
-{
- struct xt_parser *xt = data;
- struct xt_node *node = xt->cur;
-
- if( node == NULL )
- return;
-
- /* FIXME: Does g_renew also OFFICIALLY accept NULL arguments? */
- node->text = g_renew( char, node->text, node->text_len + text_len + 1 );
- memcpy( node->text + node->text_len, text, text_len );
- node->text_len += text_len;
- /* Zero termination is always nice to have. */
- node->text[node->text_len] = 0;
-}
-
-static void xt_end_element( GMarkupParseContext *ctx, const gchar *element_name, gpointer data, GError **error )
-{
- struct xt_parser *xt = data;
-
- xt->cur->flags |= XT_COMPLETE;
- xt->cur = xt->cur->parent;
-}
-
-GMarkupParser xt_parser_funcs =
-{
- xt_start_element,
- xt_end_element,
- xt_text,
- NULL,
- NULL
-};
-
-struct xt_parser *xt_new( gpointer data )
-{
- struct xt_parser *xt = g_new0( struct xt_parser, 1 );
-
- xt->data = data;
- xt_reset( xt );
-
- return xt;
-}
-
-/* Reset the parser, flush everything we have so far. For example, we need
- this for XMPP when doing TLS/SASL to restart the stream. */
-void xt_reset( struct xt_parser *xt )
-{
- if( xt->parser )
- g_markup_parse_context_free( xt->parser );
-
- xt->parser = g_markup_parse_context_new( &xt_parser_funcs, 0, xt, NULL );
-
- if( xt->root )
- {
- xt_free_node( xt->root );
- xt->root = NULL;
- xt->cur = NULL;
- }
-}
-
-/* Feed the parser, don't execute any handler. Returns -1 on errors, 0 on
- end-of-stream and 1 otherwise. */
-int xt_feed( struct xt_parser *xt, char *text, int text_len )
-{
- if( !g_markup_parse_context_parse( xt->parser, text, text_len, &xt->gerr ) )
- {
- return -1;
- }
-
- return !( xt->root && xt->root->flags & XT_COMPLETE );
-}
-
-/* Find completed nodes and see if a handler has to be called. Passing
- a node isn't necessary if you want to start at the root, just pass
- NULL. This second argument is needed for recursive calls. */
-int xt_handle( struct xt_parser *xt, struct xt_node *node, int depth )
-{
- struct xt_node *c;
- xt_status st;
- int i;
-
- /* Just in case someone likes infinite loops... */
- if( xt->root == NULL )
- return 0;
-
- if( node == NULL )
- return xt_handle( xt, xt->root, depth );
-
- if( depth != 0 )
- for( c = node->children; c; c = c->next )
- if( !xt_handle( xt, c, depth > 0 ? depth - 1 : depth ) )
- return 0;
-
- if( node->flags & XT_COMPLETE && !( node->flags & XT_SEEN ) )
- {
- for( i = 0; xt->handlers[i].func; i ++ )
- {
- /* This one is fun! \o/ */
-
- /* If handler.name == NULL it means it should always match. */
- if( ( xt->handlers[i].name == NULL ||
- /* If it's not, compare. There should always be a name. */
- g_strcasecmp( xt->handlers[i].name, node->name ) == 0 ) &&
- /* If handler.parent == NULL, it's a match. */
- ( xt->handlers[i].parent == NULL ||
- /* If there's a parent node, see if the name matches. */
- ( node->parent ? g_strcasecmp( xt->handlers[i].parent, node->parent->name ) == 0 :
- /* If there's no parent, the handler should mention <root> as a parent. */
- g_strcasecmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) )
- {
- st = xt->handlers[i].func( node, xt->data );
-
- if( st == XT_ABORT )
- return 0;
- else if( st != XT_NEXT )
- break;
- }
- }
-
- node->flags |= XT_SEEN;
- }
-
- return 1;
-}
-
-/* Garbage collection: Cleans up all nodes that are handled. Useful for
- streams because there's no reason to keep a complete packet history
- in memory. */
-void xt_cleanup( struct xt_parser *xt, struct xt_node *node, int depth )
-{
- struct xt_node *c, *prev;
-
- if( !xt || !xt->root )
- return;
-
- if( node == NULL )
- return xt_cleanup( xt, xt->root, depth );
-
- if( node->flags & XT_SEEN && node == xt->root )
- {
- xt_free_node( xt->root );
- xt->root = xt->cur = NULL;
- /* xt->cur should be NULL already, BTW... */
-
- return;
- }
-
- /* c contains the current node, prev the previous node (or NULL).
- I admit, this one's pretty horrible. */
- for( c = node->children, prev = NULL; c; prev = c, c = c ? c->next : node->children )
- {
- if( c->flags & XT_SEEN )
- {
- /* Remove the node from the linked list. */
- if( prev )
- prev->next = c->next;
- else
- node->children = c->next;
-
- xt_free_node( c );
-
- /* Since the for loop wants to get c->next, make sure
- c points at something that exists (and that c->next
- will actually be the next item we should check). c
- can be NULL now, if we just removed the first item.
- That explains the ? thing in for(). */
- c = prev;
- }
- else
- {
- /* This node can't be cleaned up yet, but maybe a
- subnode can. */
- if( depth != 0 )
- xt_cleanup( xt, c, depth > 0 ? depth - 1 : depth );
- }
- }
-}
-
-static void xt_to_string_real( struct xt_node *node, GString *str )
-{
- char *buf;
- struct xt_node *c;
- int i;
-
- g_string_append_printf( str, "<%s", node->name );
-
- for( i = 0; node->attr[i].key; i ++ )
- {
- buf = g_markup_printf_escaped( " %s=\"%s\"", node->attr[i].key, node->attr[i].value );
- g_string_append( str, buf );
- g_free( buf );
- }
-
- if( node->text == NULL && node->children == NULL )
- {
- g_string_append( str, "/>" );
- return;
- }
-
- g_string_append( str, ">" );
- if( node->text_len > 0 )
- {
- buf = g_markup_escape_text( node->text, node->text_len );
- g_string_append( str, buf );
- g_free( buf );
- }
-
- for( c = node->children; c; c = c->next )
- xt_to_string_real( c, str );
-
- g_string_append_printf( str, "</%s>", node->name );
-}
-
-char *xt_to_string( struct xt_node *node )
-{
- GString *ret;
- char *real;
-
- ret = g_string_new( "" );
- xt_to_string_real( node, ret );
-
- real = ret->str;
- g_string_free( ret, FALSE );
-
- return real;
-}
-
-#ifdef DEBUG
-void xt_print( struct xt_node *node )
-{
- int i;
- struct xt_node *c;
-
- /* Indentation */
- for( c = node; c->parent; c = c->parent )
- printf( "\t" );
-
- /* Start the tag */
- printf( "<%s", node->name );
-
- /* Print the attributes */
- for( i = 0; node->attr[i].key; i ++ )
- printf( " %s=\"%s\"", node->attr[i].key, g_markup_escape_text( node->attr[i].value, -1 ) );
-
- /* /> in case there's really *nothing* inside this tag, otherwise
- just >. */
- /* If this tag doesn't have any content at all... */
- if( node->text == NULL && node->children == NULL )
- {
- printf( "/>\n" );
- return;
- /* Then we're finished! */
- }
-
- /* Otherwise... */
- printf( ">" );
-
- /* Only print the text if it contains more than whitespace (TEST). */
- if( node->text_len > 0 )
- {
- for( i = 0; node->text[i] && isspace( node->text[i] ); i ++ );
- if( node->text[i] )
- printf( "%s", g_markup_escape_text( node->text, -1 ) );
- }
-
- if( node->children )
- printf( "\n" );
-
- for( c = node->children; c; c = c->next )
- xt_print( c );
-
- if( node->children )
- for( c = node; c->parent; c = c->parent )
- printf( "\t" );
-
- /* Non-empty tag is now finished. */
- printf( "</%s>\n", node->name );
-}
-#endif
-
-struct xt_node *xt_dup( struct xt_node *node )
-{
- struct xt_node *dup = g_new0( struct xt_node, 1 );
- struct xt_node *c, *dc = NULL;
- int i;
-
- /* Let's NOT copy the parent element here BTW! Only do it for children. */
-
- dup->name = g_strdup( node->name );
- dup->flags = node->flags;
- if( node->text )
- {
- dup->text = g_memdup( node->text, node->text_len + 1 );
- dup->text_len = node->text_len;
- }
-
- /* Count the number of attributes and allocate the new array. */
- for( i = 0; node->attr[i].key; i ++ );
- dup->attr = g_new0( struct xt_attr, i + 1 );
-
- /* Copy them all! */
- for( i --; i >= 0; i -- )
- {
- dup->attr[i].key = g_strdup( node->attr[i].key );
- dup->attr[i].value = g_strdup( node->attr[i].value );
- }
-
- /* This nice mysterious loop takes care of the children. */
- for( c = node->children; c; c = c->next )
- {
- if( dc == NULL )
- dc = dup->children = xt_dup( c );
- else
- dc = ( dc->next = xt_dup( c ) );
-
- dc->parent = dup;
- }
-
- return dup;
-}
-
-/* Frees a node. This doesn't clean up references to itself from parents! */
-void xt_free_node( struct xt_node *node )
-{
- int i;
-
- if( !node )
- return;
-
- g_free( node->name );
- g_free( node->text );
-
- for( i = 0; node->attr[i].key; i ++ )
- {
- g_free( node->attr[i].key );
- g_free( node->attr[i].value );
- }
- g_free( node->attr );
-
- while( node->children )
- {
- struct xt_node *next = node->children->next;
-
- xt_free_node( node->children );
- node->children = next;
- }
-
- g_free( node );
-}
-
-void xt_free( struct xt_parser *xt )
-{
- if( !xt )
- return;
-
- if( xt->root )
- xt_free_node( xt->root );
-
- g_markup_parse_context_free( xt->parser );
-
- g_free( xt );
-}
-
-/* To find a node's child with a specific name, pass the node's children
- list, not the node itself! The reason you have to do this by hand: So
- that you can also use this function as a find-next. */
-struct xt_node *xt_find_node( struct xt_node *node, const char *name )
-{
- while( node )
- {
- if( g_strcasecmp( node->name, name ) == 0 )
- break;
-
- node = node->next;
- }
-
- return node;
-}
-
-char *xt_find_attr( struct xt_node *node, const char *key )
-{
- int i;
-
- if( !node )
- return NULL;
-
- for( i = 0; node->attr[i].key; i ++ )
- if( g_strcasecmp( node->attr[i].key, key ) == 0 )
- break;
-
- return node->attr[i].value;
-}
-
-struct xt_node *xt_new_node( char *name, char *text, struct xt_node *children )
-{
- struct xt_node *node, *c;
-
- node = g_new0( struct xt_node, 1 );
- node->name = g_strdup( name );
- node->children = children;
- node->attr = g_new0( struct xt_attr, 1 );
-
- if( text )
- {
- node->text_len = strlen( text );
- node->text = g_memdup( text, node->text_len + 1 );
- }
-
- for( c = children; c; c = c->next )
- {
- if( c->parent != NULL )
- {
- /* ERROR CONDITION: They seem to have a parent already??? */
- }
-
- c->parent = node;
- }
-
- return node;
-}
-
-void xt_add_child( struct xt_node *parent, struct xt_node *child )
-{
- struct xt_node *node;
-
- /* This function can actually be used to add more than one child, so
- do handle this properly. */
- for( node = child; node; node = node->next )
- {
- if( node->parent != NULL )
- {
- /* ERROR CONDITION: They seem to have a parent already??? */
- }
-
- node->parent = parent;
- }
-
- if( parent->children == NULL )
- {
- parent->children = child;
- }
- else
- {
- for( node = parent->children; node->next; node = node->next );
- node->next = child;
- }
-}
-
-void xt_add_attr( struct xt_node *node, const char *key, const char *value )
-{
- int i;
-
- /* Now actually it'd be nice if we can also change existing attributes
- (which actually means this function doesn't have the right name).
- So let's find out if we have this attribute already... */
- for( i = 0; node->attr[i].key; i ++ )
- if( strcmp( node->attr[i].key, key ) == 0 )
- break;
-
- if( node->attr[i].key == NULL )
- {
- /* If not, allocate space for a new attribute. */
- node->attr = g_renew( struct xt_attr, node->attr, i + 2 );
- node->attr[i].key = g_strdup( key );
- node->attr[i+1].key = NULL;
- }
- else
- {
- /* Otherwise, free the old value before setting the new one. */
- g_free( node->attr[i].value );
- }
-
- node->attr[i].value = g_strdup( value );
-}
-
-int xt_remove_attr( struct xt_node *node, const char *key )
-{
- int i, last;
-
- for( i = 0; node->attr[i].key; i ++ )
- if( strcmp( node->attr[i].key, key ) == 0 )
- break;
-
- /* If we didn't find the attribute... */
- if( node->attr[i].key == NULL )
- return 0;
-
- g_free( node->attr[i].key );
- g_free( node->attr[i].value );
-
- /* If it's the last, this is easy: */
- if( node->attr[i+1].key == NULL )
- {
- node->attr[i].key = node->attr[i].value = NULL;
- }
- else /* It's also pretty easy, actually. */
- {
- /* Find the last item. */
- for( last = i + 1; node->attr[last+1].key; last ++ );
-
- node->attr[i] = node->attr[last];
- node->attr[last].key = NULL;
- node->attr[last].value = NULL;
- }
-
- /* Let's not bother with reallocating memory here. It takes time and
- most packets don't stay in memory for long anyway. */
-
- return 1;
-}
diff --git a/protocols/jabber/xmltree.h b/protocols/jabber/xmltree.h
deleted file mode 100644
index b8b61641..00000000
--- a/protocols/jabber/xmltree.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/***************************************************************************\
-* *
-* BitlBee - An IRC to IM gateway *
-* Simple XML (stream) parse tree handling code (Jabber/XMPP, mainly) *
-* *
-* Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net> *
-* *
-* This library is free software; you can redistribute it and/or *
-* modify it under the terms of the GNU Lesser General Public *
-* License as published by the Free Software Foundation, version *
-* 2.1. *
-* *
-* This library 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 *
-* Lesser General Public License for more details. *
-* *
-* You should have received a copy of the GNU Lesser General Public License *
-* along with this library; if not, write to the Free Software Foundation, *
-* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
-* *
-****************************************************************************/
-
-#ifndef _XMLTREE_H
-#define _XMLTREE_H
-
-typedef enum
-{
- XT_COMPLETE = 1, /* </tag> reached */
- XT_SEEN = 2, /* Handler called (or not defined) */
-} xt_flags;
-
-typedef enum
-{
- XT_ABORT, /* Abort, don't handle the rest anymore */
- XT_HANDLED, /* Handled this tag properly, go to the next one */
- XT_NEXT /* Try if there's another matching handler */
-} xt_status;
-
-struct xt_attr
-{
- char *key, *value;
-};
-
-struct xt_node
-{
- struct xt_node *parent;
- struct xt_node *children;
-
- char *name;
- struct xt_attr *attr;
- char *text;
- int text_len;
-
- struct xt_node *next;
- xt_flags flags;
-};
-
-typedef xt_status (*xt_handler_func) ( struct xt_node *node, gpointer data );
-
-struct xt_handler_entry
-{
- char *name, *parent;
- xt_handler_func func;
-};
-
-struct xt_parser
-{
- GMarkupParseContext *parser;
- struct xt_node *root;
- struct xt_node *cur;
-
- struct xt_handler_entry *handlers;
- gpointer data;
-
- GError *gerr;
-};
-
-struct xt_parser *xt_new( gpointer data );
-void xt_reset( struct xt_parser *xt );
-int xt_feed( struct xt_parser *xt, char *text, int text_len );
-int xt_handle( struct xt_parser *xt, struct xt_node *node, int depth );
-void xt_cleanup( struct xt_parser *xt, struct xt_node *node, int depth );
-char *xt_to_string( struct xt_node *node );
-void xt_print( struct xt_node *node );
-struct xt_node *xt_dup( struct xt_node *node );
-void xt_free_node( struct xt_node *node );
-void xt_free( struct xt_parser *xt );
-struct xt_node *xt_find_node( struct xt_node *node, const char *name );
-char *xt_find_attr( struct xt_node *node, const char *key );
-
-struct xt_node *xt_new_node( char *name, char *text, struct xt_node *children );
-void xt_add_child( struct xt_node *parent, struct xt_node *child );
-void xt_add_attr( struct xt_node *node, const char *key, const char *value );
-int xt_remove_attr( struct xt_node *node, const char *key );
-
-#endif
diff --git a/protocols/msn/Makefile b/protocols/msn/Makefile
index 3440658d..6a588613 100644
--- a/protocols/msn/Makefile
+++ b/protocols/msn/Makefile
@@ -17,7 +17,7 @@ LFLAGS += -r
# [SH] Phony targets
all: msn_mod.o
check: all
-lcov:
+lcov: check
gcov:
gcov *.c
diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h
index c8f4f4c6..63759303 100644
--- a/protocols/msn/msn.h
+++ b/protocols/msn/msn.h
@@ -28,7 +28,7 @@
#define TYPING_NOTIFICATION_MESSAGE "\r\r\rBEWARE, ME R TYPINK MESSAGE!!!!\r\r\r"
#define GROUPCHAT_SWITCHBOARD_MESSAGE "\r\r\rME WANT TALK TO MANY PEOPLE\r\r\r"
-#ifdef DEBUG
+#ifdef DEBUG_MSN
#define debug( text... ) imcb_log( ic, text );
#else
#define debug( text... )
diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c
index fae2877d..58ad22f8 100644
--- a/protocols/msn/msn_util.c
+++ b/protocols/msn/msn_util.c
@@ -89,8 +89,10 @@ struct msn_buddy_ask_data
char *realname;
};
-static void msn_buddy_ask_yes( gpointer w, struct msn_buddy_ask_data *bla )
+static void msn_buddy_ask_yes( void *data )
{
+ struct msn_buddy_ask_data *bla = data;
+
msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname );
if( imcb_find_buddy( bla->ic, bla->handle ) == NULL )
@@ -101,8 +103,10 @@ static void msn_buddy_ask_yes( gpointer w, struct msn_buddy_ask_data *bla )
g_free( bla );
}
-static void msn_buddy_ask_no( gpointer w, struct msn_buddy_ask_data *bla )
+static void msn_buddy_ask_no( void *data )
{
+ struct msn_buddy_ask_data *bla = data;
+
msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname );
g_free( bla->handle );
diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c
index 0bb84a74..ff7da6ed 100644
--- a/protocols/msn/ns.c
+++ b/protocols/msn/ns.c
@@ -33,7 +33,7 @@ static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition c
static int msn_ns_command( gpointer data, char **cmd, int num_parts );
static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
-static void msn_auth_got_passport_id( struct passport_reply *rep );
+static void msn_auth_got_passport_token( struct msn_auth_data *mad );
gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
{
@@ -213,7 +213,7 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts )
if( num_parts == 5 && strcmp( cmd[2], "TWN" ) == 0 && strcmp( cmd[3], "S" ) == 0 )
{
/* Time for some Passport black magic... */
- if( !passport_get_id( msn_auth_got_passport_id, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )
+ if( !passport_get_token( msn_auth_got_passport_token, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )
{
imcb_error( ic, "Error while contacting Passport server" );
imc_logout( ic, TRUE );
@@ -673,22 +673,26 @@ static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int
return( 1 );
}
-static void msn_auth_got_passport_id( struct passport_reply *rep )
+static void msn_auth_got_passport_token( struct msn_auth_data *mad )
{
- struct im_connection *ic = rep->data;
- struct msn_data *md = ic->proto_data;
- char *key = rep->result;
- char buf[1024];
+ struct im_connection *ic = mad->data;
+ struct msn_data *md;
- if( key == NULL )
+ /* Dead connection? */
+ if( g_slist_find( msn_connections, ic ) == NULL )
+ return;
+
+ md = ic->proto_data;
+ if( mad->token )
{
- imcb_error( ic, "Error during Passport authentication (%s)",
- rep->error_string ? rep->error_string : "Unknown error" );
- imc_logout( ic, TRUE );
+ char buf[1024];
+
+ g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, mad->token );
+ msn_write( ic, buf, strlen( buf ) );
}
else
{
- g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, key );
- msn_write( ic, buf, strlen( buf ) );
+ imcb_error( ic, "Error during Passport authentication: %s", mad->error );
+ imc_logout( ic, TRUE );
}
}
diff --git a/protocols/msn/passport.c b/protocols/msn/passport.c
index 9fe6a174..565d15f3 100644
--- a/protocols/msn/passport.c
+++ b/protocols/msn/passport.c
@@ -1,8 +1,7 @@
-/* passport.c
+/** passport.c
*
- * Functions to login to microsoft passport service for Messenger
- * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be>
- * Copyright (C) 2004 Wilmer van der Gaast <wilmer@gaast.net>
+ * Functions to login to Microsoft Passport service for Messenger
+ * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -23,208 +22,149 @@
#include "passport.h"
#include "msn.h"
#include "bitlbee.h"
+#include "url.h"
+#include "misc.h"
+#include "xmltree.h"
#include <ctype.h>
#include <errno.h>
-#define MSN_BUF_LEN 8192
+static int passport_get_token_real( struct msn_auth_data *mad );
+static void passport_get_token_ready( struct http_request *req );
-static char *prd_cached = NULL;
-
-static int passport_get_id_real( gpointer func, gpointer data, char *header );
-static void passport_get_id_ready( struct http_request *req );
-
-static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header );
-static void passport_retrieve_dalogin_ready( struct http_request *req );
-
-static char *passport_create_header( char *cookie, char *email, char *pwd );
-static void destroy_reply( struct passport_reply *rep );
-
-int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie )
-{
- char *header = passport_create_header( cookie, username, password );
-
- if( prd_cached == NULL )
- return passport_retrieve_dalogin( func, data, header );
- else
- return passport_get_id_real( func, data, header );
-}
-
-static int passport_get_id_real( gpointer func, gpointer data, char *header )
+int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie )
{
- struct passport_reply *rep;
- char *server, *dummy, *reqs;
- struct http_request *req;
-
- rep = g_new0( struct passport_reply, 1 );
- rep->data = data;
- rep->func = func;
- rep->header = header;
-
- server = g_strdup( prd_cached );
- dummy = strchr( server, '/' );
-
- if( dummy == NULL )
- {
- destroy_reply( rep );
- return( 0 );
- }
-
- reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header );
+ struct msn_auth_data *mad = g_new0( struct msn_auth_data, 1 );
+ int i;
- *dummy = 0;
- req = http_dorequest( server, 443, 1, reqs, passport_get_id_ready, rep );
+ mad->username = g_strdup( username );
+ mad->password = g_strdup( password );
+ mad->cookie = g_strdup( cookie );
- g_free( server );
- g_free( reqs );
+ mad->callback = func;
+ mad->data = data;
- if( req == NULL )
- destroy_reply( rep );
+ mad->url = g_strdup( SOAP_AUTHENTICATION_URL );
+ mad->ttl = 3; /* Max. # of redirects. */
- return( req != NULL );
-}
-
-static void passport_get_id_ready( struct http_request *req )
-{
- struct passport_reply *rep = req->data;
-
- if( !g_slist_find( msn_connections, rep->data ) )
- {
- destroy_reply( rep );
- return;
- }
+ /* HTTP-escape stuff and s/,/&/ */
+ http_decode( mad->cookie );
+ for( i = 0; mad->cookie[i]; i ++ )
+ if( mad->cookie[i] == ',' )
+ mad->cookie[i] = '&';
- if( req->finished && req->reply_headers && req->status_code == 200 )
- {
- char *dummy;
-
- if( ( dummy = strstr( req->reply_headers, "from-PP='" ) ) )
- {
- char *responseend;
-
- dummy += strlen( "from-PP='" );
- responseend = strchr( dummy, '\'' );
- if( responseend )
- *responseend = 0;
-
- rep->result = g_strdup( dummy );
- }
- else
- {
- rep->error_string = g_strdup( "Could not parse Passport server response" );
- }
- }
- else
- {
- rep->error_string = g_strdup_printf( "HTTP error: %s",
- req->status_string ? req->status_string : "Unknown error" );
- }
+ /* Microsoft doesn't allow password longer than 16 chars and silently
+ fails authentication if you give the "full version" of your passwd. */
+ if( strlen( mad->password ) > MAX_PASSPORT_PWLEN )
+ mad->password[MAX_PASSPORT_PWLEN] = 0;
- rep->func( rep );
- destroy_reply( rep );
+ return passport_get_token_real( mad );
}
-static char *passport_create_header( char *cookie, char *email, char *pwd )
+static int passport_get_token_real( struct msn_auth_data *mad )
{
- char *buffer;
- char *currenttoken;
- char *email_enc, *pwd_enc;
-
- currenttoken = strstr( cookie, "lc=" );
- if( currenttoken == NULL )
- return NULL;
+ char *post_payload, *post_request;
+ struct http_request *req;
+ url_t url;
- email_enc = g_new0( char, strlen( email ) * 3 + 1 );
- strcpy( email_enc, email );
- http_encode( email_enc );
+ url_set( &url, mad->url );
- pwd_enc = g_new0( char, strlen( pwd ) * 3 + 1 );
- strcpy( pwd_enc, pwd );
- http_encode( pwd_enc );
+ post_payload = g_markup_printf_escaped( SOAP_AUTHENTICATION_PAYLOAD,
+ mad->username,
+ mad->password,
+ mad->cookie );
- buffer = g_strdup_printf( "Authorization: Passport1.4 OrgVerb=GET,"
- "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,"
- "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc,
- currenttoken );
+ post_request = g_strdup_printf( SOAP_AUTHENTICATION_REQUEST,
+ url.file, url.host,
+ (int) strlen( post_payload ),
+ post_payload );
+
+ req = http_dorequest( url.host, url.port, 1, post_request,
+ passport_get_token_ready, mad );
- g_free( email_enc );
- g_free( pwd_enc );
+ g_free( post_request );
+ g_free( post_payload );
- return buffer;
+ return req != NULL;
}
-static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header )
-{
- struct passport_reply *rep = g_new0( struct passport_reply, 1 );
- struct http_request *req;
-
- rep->data = data;
- rep->func = func;
- rep->header = header;
-
- req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep );
-
- if( !req )
- destroy_reply( rep );
-
- return( req != NULL );
-}
+static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data );
+static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data );
-static void passport_retrieve_dalogin_ready( struct http_request *req )
+static const struct xt_handler_entry passport_xt_handlers[] = {
+ { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", passport_xt_extract_token },
+ { "S:Fault", "S:Envelope", passport_xt_handle_fault },
+ { NULL, NULL, NULL }
+};
+
+static void passport_get_token_ready( struct http_request *req )
{
- struct passport_reply *rep = req->data;
- char *dalogin;
- char *urlend;
+ struct msn_auth_data *mad = req->data;
+ struct xt_parser *parser;
+
+ g_free( mad->url );
+ g_free( mad->error );
+ mad->url = mad->error = NULL;
- if( !g_slist_find( msn_connections, rep->data ) )
+ if( req->status_code == 200 )
{
- destroy_reply( rep );
- return;
+ parser = xt_new( passport_xt_handlers, mad );
+ xt_feed( parser, req->reply_body, req->body_size );
+ xt_handle( parser, NULL, -1 );
+ xt_free( parser );
}
-
- if( !req->finished || !req->reply_headers || req->status_code != 200 )
+ else
{
- rep->error_string = g_strdup_printf( "HTTP error while fetching DALogin: %s",
- req->status_string ? req->status_string : "Unknown error" );
- goto failure;
+ mad->error = g_strdup_printf( "HTTP error %d (%s)", req->status_code,
+ req->status_string ? req->status_string : "unknown" );
}
- dalogin = strstr( req->reply_headers, "DALogin=" );
+ if( mad->error == NULL && mad->token == NULL )
+ mad->error = g_strdup( "Could not parse Passport server response" );
- if( !dalogin )
+ if( mad->url && mad->token == NULL )
{
- rep->error_string = g_strdup( "Parse error while fetching DALogin" );
- goto failure;
+ passport_get_token_real( mad );
}
-
- dalogin += strlen( "DALogin=" );
- urlend = strchr( dalogin, ',' );
- if( urlend )
- *urlend = 0;
-
- /* strip the http(s):// part from the url */
- urlend = strstr( urlend, "://" );
- if( urlend )
- dalogin = urlend + strlen( "://" );
-
- if( prd_cached == NULL )
- prd_cached = g_strdup( dalogin );
-
- if( passport_get_id_real( rep->func, rep->data, rep->header ) )
+ else
{
- rep->header = NULL;
- destroy_reply( rep );
- return;
+ mad->callback( mad );
+
+ g_free( mad->url );
+ g_free( mad->username );
+ g_free( mad->password );
+ g_free( mad->cookie );
+ g_free( mad->token );
+ g_free( mad->error );
+ g_free( mad );
}
+}
+
+static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data )
+{
+ struct msn_auth_data *mad = data;
+ char *s;
+
+ if( ( s = xt_find_attr( node, "Id" ) ) && strcmp( s, "PPToken1" ) == 0 )
+ mad->token = g_memdup( node->text, node->text_len + 1 );
-failure:
- rep->func( rep );
- destroy_reply( rep );
+ return XT_HANDLED;
}
-static void destroy_reply( struct passport_reply *rep )
+static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data )
{
- g_free( rep->result );
- g_free( rep->header );
- g_free( rep->error_string );
- g_free( rep );
+ struct msn_auth_data *mad = data;
+ struct xt_node *code = xt_find_node( node->children, "faultcode" );
+ struct xt_node *string = xt_find_node( node->children, "faultstring" );
+ struct xt_node *redirect = xt_find_node( node->children, "psf:redirectUrl" );
+
+ if( redirect && redirect->text_len && mad->ttl-- > 0 )
+ mad->url = g_memdup( redirect->text, redirect->text_len + 1 );
+
+ if( code == NULL || code->text_len == 0 )
+ mad->error = g_strdup( "Unknown error" );
+ else
+ mad->error = g_strdup_printf( "%s (%s)", code->text, string && string->text_len ?
+ string->text : "no description available" );
+
+ return XT_HANDLED;
}
diff --git a/protocols/msn/passport.h b/protocols/msn/passport.h
index 9fd81a82..517d2e91 100644
--- a/protocols/msn/passport.h
+++ b/protocols/msn/passport.h
@@ -1,10 +1,7 @@
-#ifndef __PASSPORT_H__
-#define __PASSPORT_H__
/* passport.h
*
- * Functions to login to Microsoft Passport Service for Messenger
- * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be>,
- * Wilmer van der Gaast <wilmer@gaast.net>
+ * Functions to login to Microsoft Passport service for Messenger
+ * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -17,9 +14,15 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+/* Thanks to http://msnpiki.msnfanatic.com/index.php/MSNP13:SOAPTweener
+ for the specs! */
+
+#ifndef __PASSPORT_H__
+#define __PASSPORT_H__
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -32,15 +35,79 @@
#endif
#include "nogaim.h"
-struct passport_reply
+#define MAX_PASSPORT_PWLEN 16
+
+struct msn_auth_data
{
- void (*func)( struct passport_reply * );
- void *data;
- char *result;
- char *header;
- char *error_string;
+ char *url;
+ int ttl;
+
+ char *username;
+ char *password;
+ char *cookie;
+
+ /* The end result, the only thing we'll really be interested in
+ once finished. */
+ char *token;
+ char *error; /* Yeah, or that... */
+
+ void (*callback)( struct msn_auth_data *mad );
+ gpointer data;
};
-int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie );
+#define SOAP_AUTHENTICATION_URL "https://loginnet.passport.com/RST.srf"
+
+#define SOAP_AUTHENTICATION_REQUEST \
+"POST %s HTTP/1.0\r\n" \
+"Accept: text/*\r\n" \
+"User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \
+"Host: %s\r\n" \
+"Content-Length: %d\r\n" \
+"Cache-Control: no-cache\r\n" \
+"\r\n" \
+"%s"
+
+#define SOAP_AUTHENTICATION_PAYLOAD \
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
+"<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>AQAAAAIAAABsYwQAAAAzMDg0</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>messenger.msn.com</wsa:Address>" \
+ "</wsa:EndpointReference>" \
+ "</wsp:AppliesTo>" \
+ "<wsse:PolicyReference URI=\"?%s\"></wsse:PolicyReference>" \
+ "</wst:RequestSecurityToken>" \
+ "</ps:RequestMultipleSecurityTokens>" \
+ "</Body>" \
+"</Envelope>"
+
+int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie );
#endif /* __PASSPORT_H__ */
diff --git a/protocols/nogaim.c b/protocols/nogaim.c
index 3ce15166..7466e93a 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -342,7 +342,8 @@ void imc_logout( struct im_connection *ic, int allow_reconnect )
/* dialogs.c */
-void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont )
+void imcb_ask( struct im_connection *ic, char *msg, void *data,
+ query_callback doit, query_callback dont )
{
query_add( ic->irc, ic, msg, doit, dont, data );
}
@@ -494,18 +495,20 @@ struct show_got_added_data
char *handle;
};
-void show_got_added_no( gpointer w, struct show_got_added_data *data )
+void show_got_added_no( void *data )
{
- g_free( data->handle );
+ g_free( ((struct show_got_added_data*)data)->handle );
g_free( data );
}
-void show_got_added_yes( gpointer w, struct show_got_added_data *data )
+void show_got_added_yes( void *data )
{
- data->ic->acc->prpl->add_buddy( data->ic, data->handle, NULL );
- /* imcb_add_buddy( data->ic, NULL, data->handle, data->handle ); */
+ struct show_got_added_data *sga = data;
- return show_got_added_no( w, data );
+ sga->ic->acc->prpl->add_buddy( sga->ic, sga->handle, NULL );
+ /* imcb_add_buddy( sga->ic, NULL, sga->handle, sga->handle ); */
+
+ return show_got_added_no( data );
}
void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname )
diff --git a/protocols/nogaim.h b/protocols/nogaim.h
index 37232493..17da2b36 100644
--- a/protocols/nogaim.h
+++ b/protocols/nogaim.h
@@ -41,6 +41,7 @@
#include "bitlbee.h"
#include "account.h"
#include "proxy.h"
+#include "query.h"
#include "md5.h"
#include "ft.h"
@@ -264,7 +265,7 @@ G_MODULE_EXPORT void imcb_error( struct im_connection *ic, char *format, ... ) G
* - 'data' can be your custom struct - it will be passed to the callbacks.
* - 'doit' or 'dont' will be called depending of the answer of the user.
*/
-G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont );
+G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, query_callback doit, query_callback dont );
G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname );
/* Buddy management */
diff --git a/protocols/oscar/Makefile b/protocols/oscar/Makefile
index 95e85ec2..2792f22a 100644
--- a/protocols/oscar/Makefile
+++ b/protocols/oscar/Makefile
@@ -17,7 +17,7 @@ LFLAGS += -r
# [SH] Phony targets
all: oscar_mod.o
check: all
-lcov:
+lcov: check
gcov:
gcov *.c
diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c
index 9e5de70a..7738c31f 100644
--- a/protocols/oscar/oscar.c
+++ b/protocols/oscar/oscar.c
@@ -1083,8 +1083,8 @@ static int incomingim_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_
return 1;
}
-void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv);
-void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv);
+void oscar_accept_chat(void *data);
+void oscar_reject_chat(void *data);
static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) {
struct im_connection *ic = sess->aux_data;
@@ -1118,7 +1118,8 @@ static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_
return 1;
}
-static void gaim_icq_authgrant(gpointer w, struct icq_auth *data) {
+static void gaim_icq_authgrant(void *data_) {
+ struct icq_auth *data = data_;
char *uin, message;
struct oscar_data *od = (struct oscar_data *)data->ic->proto_data;
@@ -1133,7 +1134,8 @@ static void gaim_icq_authgrant(gpointer w, struct icq_auth *data) {
g_free(data);
}
-static void gaim_icq_authdeny(gpointer w, struct icq_auth *data) {
+static void gaim_icq_authdeny(void *data_) {
+ struct icq_auth *data = data_;
char *uin, *message;
struct oscar_data *od = (struct oscar_data *)data->ic->proto_data;
@@ -2587,15 +2589,19 @@ struct groupchat *oscar_chat_with(struct im_connection * ic, char *who)
return NULL;
}
-void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv)
+void oscar_accept_chat(void *data)
{
+ struct aim_chat_invitation * inv = data;
+
oscar_chat_join(inv->ic, inv->name, NULL, NULL);
g_free(inv->name);
g_free(inv);
}
-void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv)
+void oscar_reject_chat(void *data)
{
+ struct aim_chat_invitation * inv = data;
+
g_free(inv->name);
g_free(inv);
}
diff --git a/protocols/yahoo/Makefile b/protocols/yahoo/Makefile
index 2cfd147b..b4fe56e2 100644
--- a/protocols/yahoo/Makefile
+++ b/protocols/yahoo/Makefile
@@ -17,7 +17,7 @@ LFLAGS += -r
# [SH] Phony targets
all: yahoo_mod.o
check: all
-lcov:
+lcov: check
gcov:
gcov *.c
diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c
index ce38bc73..80d88a85 100644
--- a/protocols/yahoo/libyahoo2.c
+++ b/protocols/yahoo/libyahoo2.c
@@ -736,7 +736,7 @@ static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet
data = y_new0(unsigned char, len + 1);
memcpy(data + pos, "YMSG", 4); pos += 4;
- pos += yahoo_put16(data + pos, 0x0a00);
+ pos += yahoo_put16(data + pos, 0x000c);
pos += yahoo_put16(data + pos, 0x0000);
pos += yahoo_put16(data + pos, pktlen + extra_pad);
pos += yahoo_put16(data + pos, pkt->service);
@@ -3350,7 +3350,7 @@ static void yahoo_process_search_connection(struct yahoo_input_data *yid, int ov
yct->age = atoi(cp);
break;
case 5:
- if(cp != "\005")
+ if(strcmp(cp, "5") != 0)
yct->location = cp;
k = 0;
break;
diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c
index 9f9ffcf7..ab30df4d 100644
--- a/protocols/yahoo/yahoo.c
+++ b/protocols/yahoo/yahoo.c
@@ -314,7 +314,7 @@ static void byahoo_chat_invite( struct groupchat *c, char *who, char *msg )
{
struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
- yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );
+ yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" );
}
static void byahoo_chat_leave( struct groupchat *c )
@@ -796,16 +796,20 @@ int ext_yahoo_connect(const char *host, int port)
return -1;
}
-static void byahoo_accept_conf( gpointer w, struct byahoo_conf_invitation *inv )
+static void byahoo_accept_conf( void *data )
{
+ struct byahoo_conf_invitation *inv = data;
+
yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
g_free( inv->name );
g_free( inv );
}
-static void byahoo_reject_conf( gpointer w, struct byahoo_conf_invitation *inv )
+static void byahoo_reject_conf( void *data )
{
+ struct byahoo_conf_invitation *inv = data;
+
yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
imcb_chat_free( inv->c );
g_free( inv->name );