source: protocols/msn/ns.c @ 523fb23

Last change on this file since 523fb23 was 523fb23, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-08-11T08:08:39Z

Implement MSNP15 SSO (Sadistic Sign-On).

  • Property mode set to 100644
File size: 19.9 KB
Line 
1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* MSN module - Notification server callbacks                           */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23  Suite 330, Boston, MA  02111-1307  USA
24*/
25
26#include <ctype.h>
27#include "nogaim.h"
28#include "msn.h"
29#include "passport.h"
30#include "md5.h"
31#include "soap.h"
32
33static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond );
34static int msn_ns_command( gpointer data, char **cmd, int num_parts );
35static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
36
37static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name );
38
39gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
40{
41        struct im_connection *ic = data;
42        struct msn_data *md;
43        char s[1024];
44       
45        if( !g_slist_find( msn_connections, ic ) )
46                return FALSE;
47       
48        if( source == -1 )
49        {
50                imcb_error( ic, "Could not connect to server" );
51                imc_logout( ic, TRUE );
52                return FALSE;
53        }
54       
55        md = ic->proto_data;
56       
57        if( !md->handler )
58        {
59                md->handler = g_new0( struct msn_handler_data, 1 );
60                md->handler->data = ic;
61                md->handler->exec_command = msn_ns_command;
62                md->handler->exec_message = msn_ns_message;
63        }
64        else
65        {
66                if( md->handler->rxq )
67                        g_free( md->handler->rxq );
68               
69                md->handler->rxlen = 0;
70        }
71       
72        md->handler->fd = md->fd;
73        md->handler->rxq = g_new0( char, 1 );
74       
75        g_snprintf( s, sizeof( s ), "VER %d MSNP15 CVR0\r\n", ++md->trId );
76        if( msn_write( ic, s, strlen( s ) ) )
77        {
78                ic->inpa = b_input_add( md->fd, B_EV_IO_READ, msn_ns_callback, ic );
79                imcb_log( ic, "Connected to server, waiting for reply" );
80        }
81       
82        return FALSE;
83}
84
85static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond )
86{
87        struct im_connection *ic = data;
88        struct msn_data *md = ic->proto_data;
89       
90        if( msn_handler( md->handler ) == -1 ) /* Don't do this on ret == 0, it's already done then. */
91        {
92                imcb_error( ic, "Error while reading from server" );
93                imc_logout( ic, TRUE );
94               
95                return FALSE;
96        }
97        else
98                return TRUE;
99}
100
101static int msn_ns_command( gpointer data, char **cmd, int num_parts )
102{
103        struct im_connection *ic = data;
104        struct msn_data *md = ic->proto_data;
105        char buf[1024];
106       
107        if( num_parts == 0 )
108        {
109                /* Hrrm... Empty command...? Ignore? */
110                return( 1 );
111        }
112       
113        if( strcmp( cmd[0], "VER" ) == 0 )
114        {
115                if( cmd[2] && strncmp( cmd[2], "MSNP15", 5 ) != 0 )
116                {
117                        imcb_error( ic, "Unsupported protocol" );
118                        imc_logout( ic, FALSE );
119                        return( 0 );
120                }
121               
122                g_snprintf( buf, sizeof( buf ), "CVR %d 0x0409 mac 10.2.0 ppc macmsgs 3.5.1 macmsgs %s\r\n",
123                                                ++md->trId, ic->acc->user );
124                return( msn_write( ic, buf, strlen( buf ) ) );
125        }
126        else if( strcmp( cmd[0], "CVR" ) == 0 )
127        {
128                /* We don't give a damn about the information we just received */
129                g_snprintf( buf, sizeof( buf ), "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user );
130                return( msn_write( ic, buf, strlen( buf ) ) );
131        }
132        else if( strcmp( cmd[0], "XFR" ) == 0 )
133        {
134                char *server;
135                int port;
136               
137                if( num_parts == 6 && strcmp( cmd[2], "NS" ) == 0 )
138                {
139                        b_event_remove( ic->inpa );
140                        ic->inpa = 0;
141                        closesocket( md->fd );
142                       
143                        server = strchr( cmd[3], ':' );
144                        if( !server )
145                        {
146                                imcb_error( ic, "Syntax error" );
147                                imc_logout( ic, TRUE );
148                                return( 0 );
149                        }
150                        *server = 0;
151                        port = atoi( server + 1 );
152                        server = cmd[3];
153                       
154                        imcb_log( ic, "Transferring to other server" );
155                       
156                        md->fd = proxy_connect( server, port, msn_ns_connected, ic );
157                }
158                else if( num_parts == 6 && strcmp( cmd[2], "SB" ) == 0 )
159                {
160                        struct msn_switchboard *sb;
161                       
162                        server = strchr( cmd[3], ':' );
163                        if( !server )
164                        {
165                                imcb_error( ic, "Syntax error" );
166                                imc_logout( ic, TRUE );
167                                return( 0 );
168                        }
169                        *server = 0;
170                        port = atoi( server + 1 );
171                        server = cmd[3];
172                       
173                        if( strcmp( cmd[4], "CKI" ) != 0 )
174                        {
175                                imcb_error( ic, "Unknown authentication method for switchboard" );
176                                imc_logout( ic, TRUE );
177                                return( 0 );
178                        }
179                       
180                        debug( "Connecting to a new switchboard with key %s", cmd[5] );
181
182                        if( ( sb = msn_sb_create( ic, server, port, cmd[5], MSN_SB_NEW ) ) == NULL )
183                        {
184                                /* Although this isn't strictly fatal for the NS connection, it's
185                                   definitely something serious (we ran out of file descriptors?). */
186                                imcb_error( ic, "Could not create new switchboard" );
187                                imc_logout( ic, TRUE );
188                                return( 0 );
189                        }
190                       
191                        if( md->msgq )
192                        {
193                                struct msn_message *m = md->msgq->data;
194                                GSList *l;
195                               
196                                sb->who = g_strdup( m->who );
197                               
198                                /* Move all the messages to the first user in the message
199                                   queue to the switchboard message queue. */
200                                l = md->msgq;
201                                while( l )
202                                {
203                                        m = l->data;
204                                        l = l->next;
205                                        if( strcmp( m->who, sb->who ) == 0 )
206                                        {
207                                                sb->msgq = g_slist_append( sb->msgq, m );
208                                                md->msgq = g_slist_remove( md->msgq, m );
209                                        }
210                                }
211                        }
212                }
213                else
214                {
215                        imcb_error( ic, "Syntax error" );
216                        imc_logout( ic, TRUE );
217                        return( 0 );
218                }
219        }
220        else if( strcmp( cmd[0], "USR" ) == 0 )
221        {
222                if( num_parts >= 6 && strcmp( cmd[2], "SSO" ) == 0 &&
223                    strcmp( cmd[3], "S" ) == 0 )
224                {
225                        msn_soap_passport_sso_request( ic, cmd[4], cmd[5] );
226                }
227                else if( strcmp( cmd[2], "OK" ) == 0 )
228                {
229                        if( num_parts == 7 )
230                                msn_ns_got_display_name( ic, cmd[4] );
231                        else
232                                imcb_log( ic, "Warning: Friendly name in server response was corrupted" );
233                       
234                        imcb_log( ic, "Authenticated, getting buddy list" );
235                       
236                        msn_soap_memlist_request( ic );
237                }
238                else
239                {
240                        imcb_error( ic, "Unknown authentication type" );
241                        imc_logout( ic, FALSE );
242                        return( 0 );
243                }
244        }
245        else if( strcmp( cmd[0], "MSG" ) == 0 )
246        {
247                if( num_parts != 4 )
248                {
249                        imcb_error( ic, "Syntax error" );
250                        imc_logout( ic, TRUE );
251                        return( 0 );
252                }
253               
254                md->handler->msglen = atoi( cmd[3] );
255               
256                if( md->handler->msglen <= 0 )
257                {
258                        imcb_error( ic, "Syntax error" );
259                        imc_logout( ic, TRUE );
260                        return( 0 );
261                }
262        }
263        else if( strcmp( cmd[0], "SYN" ) == 0 )
264        {
265                if( num_parts == 5 )
266                {
267                        int i, groupcount;
268                       
269                        groupcount = atoi( cmd[4] );
270                        if( groupcount > 0 )
271                        {
272                                /* valgrind says this is leaking memory, I'm guessing
273                                   that this happens during server redirects. */
274                                if( md->grouplist )
275                                {
276                                        for( i = 0; i < md->groupcount; i ++ )
277                                                g_free( md->grouplist[i] );
278                                        g_free( md->grouplist );
279                                }
280                               
281                                md->groupcount = groupcount;
282                                md->grouplist = g_new0( char *, md->groupcount );
283                        }
284                       
285                        md->buddycount = atoi( cmd[3] );
286                        if( !*cmd[3] || md->buddycount == 0 )
287                                msn_logged_in( ic );
288                }
289                else
290                {
291                        /* Hrrm... This SYN reply doesn't really look like something we expected.
292                           Let's assume everything is okay. */
293                       
294                        msn_logged_in( ic );
295                }
296        }
297        else if( strcmp( cmd[0], "LST" ) == 0 )
298        {
299                int list;
300               
301                if( num_parts != 4 && num_parts != 5 )
302                {
303                        imcb_error( ic, "Syntax error" );
304                        imc_logout( ic, TRUE );
305                        return( 0 );
306                }
307               
308                http_decode( cmd[2] );
309                list = atoi( cmd[3] );
310               
311                if( list & 1 ) /* FL */
312                {
313                        char *group = NULL;
314                        int num;
315                       
316                        if( cmd[4] != NULL && sscanf( cmd[4], "%d", &num ) == 1 && num < md->groupcount )
317                                group = md->grouplist[num];
318                       
319                        imcb_add_buddy( ic, cmd[1], group );
320                        imcb_rename_buddy( ic, cmd[1], cmd[2] );
321                }
322                if( list & 2 ) /* AL */
323                {
324                        ic->permit = g_slist_append( ic->permit, g_strdup( cmd[1] ) );
325                }
326                if( list & 4 ) /* BL */
327                {
328                        ic->deny = g_slist_append( ic->deny, g_strdup( cmd[1] ) );
329                }
330                if( list & 8 ) /* RL */
331                {
332                        if( ( list & 6 ) == 0 )
333                                msn_buddy_ask( ic, cmd[1], cmd[2] );
334                }
335               
336                if( --md->buddycount == 0 )
337                {
338                        if( ic->flags & OPT_LOGGED_IN )
339                        {
340                                imcb_log( ic, "Successfully transferred to different server" );
341                                g_snprintf( buf, sizeof( buf ), "CHG %d %s %d\r\n", ++md->trId, md->away_state->code, 0 );
342                                return( msn_write( ic, buf, strlen( buf ) ) );
343                        }
344                        else
345                        {
346                                msn_logged_in( ic );
347                        }
348                }
349        }
350        else if( strcmp( cmd[0], "LSG" ) == 0 )
351        {
352                int num;
353               
354                if( num_parts != 4 )
355                {
356                        imcb_error( ic, "Syntax error" );
357                        imc_logout( ic, TRUE );
358                        return( 0 );
359                }
360               
361                http_decode( cmd[2] );
362                num = atoi( cmd[1] );
363               
364                if( num < md->groupcount )
365                        md->grouplist[num] = g_strdup( cmd[2] );
366        }
367        else if( strcmp( cmd[0], "CHL" ) == 0 )
368        {
369                md5_state_t state;
370                md5_byte_t digest[16];
371                int i;
372               
373                if( num_parts != 3 )
374                {
375                        imcb_error( ic, "Syntax error" );
376                        imc_logout( ic, TRUE );
377                        return( 0 );
378                }
379               
380                md5_init( &state );
381                md5_append( &state, (const md5_byte_t *) cmd[2], strlen( cmd[2] ) );
382                md5_append( &state, (const md5_byte_t *) QRY_CODE, strlen( QRY_CODE ) );
383                md5_finish( &state, digest );
384               
385                g_snprintf( buf, sizeof( buf ), "QRY %d %s %d\r\n", ++md->trId, QRY_NAME, 32 );
386                for( i = 0; i < 16; i ++ )
387                        g_snprintf( buf + strlen( buf ), 3, "%02x", digest[i] );
388               
389                return( msn_write( ic, buf, strlen( buf ) ) );
390        }
391        else if( strcmp( cmd[0], "ILN" ) == 0 )
392        {
393                const struct msn_away_state *st;
394               
395                if( num_parts != 6 )
396                {
397                        imcb_error( ic, "Syntax error" );
398                        imc_logout( ic, TRUE );
399                        return( 0 );
400                }
401               
402                http_decode( cmd[4] );
403                imcb_rename_buddy( ic, cmd[3], cmd[4] );
404               
405                st = msn_away_state_by_code( cmd[2] );
406                if( !st )
407                {
408                        /* FIXME: Warn/Bomb about unknown away state? */
409                        st = msn_away_state_list + 1;
410                }
411               
412                imcb_buddy_status( ic, cmd[3], OPT_LOGGED_IN | 
413                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ),
414                                   st->name, NULL );
415        }
416        else if( strcmp( cmd[0], "FLN" ) == 0 )
417        {
418                if( cmd[1] == NULL )
419                        return 1;
420               
421                imcb_buddy_status( ic, cmd[1], 0, NULL, NULL );
422               
423                msn_sb_start_keepalives( msn_sb_by_handle( ic, cmd[1] ), TRUE );
424        }
425        else if( strcmp( cmd[0], "NLN" ) == 0 )
426        {
427                const struct msn_away_state *st;
428               
429                if( num_parts != 5 )
430                {
431                        imcb_error( ic, "Syntax error" );
432                        imc_logout( ic, TRUE );
433                        return( 0 );
434                }
435               
436                http_decode( cmd[3] );
437                imcb_rename_buddy( ic, cmd[2], cmd[3] );
438               
439                st = msn_away_state_by_code( cmd[1] );
440                if( !st )
441                {
442                        /* FIXME: Warn/Bomb about unknown away state? */
443                        st = msn_away_state_list + 1;
444                }
445               
446                imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN | 
447                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ),
448                                   st->name, NULL );
449               
450                msn_sb_stop_keepalives( msn_sb_by_handle( ic, cmd[2] ) );
451        }
452        else if( strcmp( cmd[0], "RNG" ) == 0 )
453        {
454                struct msn_switchboard *sb;
455                char *server;
456                int session, port;
457               
458                if( num_parts != 7 )
459                {
460                        imcb_error( ic, "Syntax error" );
461                        imc_logout( ic, TRUE );
462                        return( 0 );
463                }
464               
465                session = atoi( cmd[1] );
466               
467                server = strchr( cmd[2], ':' );
468                if( !server )
469                {
470                        imcb_error( ic, "Syntax error" );
471                        imc_logout( ic, TRUE );
472                        return( 0 );
473                }
474                *server = 0;
475                port = atoi( server + 1 );
476                server = cmd[2];
477               
478                if( strcmp( cmd[3], "CKI" ) != 0 )
479                {
480                        imcb_error( ic, "Unknown authentication method for switchboard" );
481                        imc_logout( ic, TRUE );
482                        return( 0 );
483                }
484               
485                debug( "Got a call from %s (session %d). Key = %s", cmd[5], session, cmd[4] );
486               
487                if( ( sb = msn_sb_create( ic, server, port, cmd[4], session ) ) == NULL )
488                {
489                        /* Although this isn't strictly fatal for the NS connection, it's
490                           definitely something serious (we ran out of file descriptors?). */
491                        imcb_error( ic, "Could not create new switchboard" );
492                        imc_logout( ic, TRUE );
493                        return( 0 );
494                }
495                else
496                {
497                        sb->who = g_strdup( cmd[5] );
498                }
499        }
500        else if( strcmp( cmd[0], "ADD" ) == 0 )
501        {
502                if( num_parts == 6 && strcmp( cmd[2], "RL" ) == 0 )
503                {
504                        GSList *l;
505                       
506                        http_decode( cmd[5] );
507                       
508                        if( strchr( cmd[4], '@' ) == NULL )
509                        {
510                                imcb_error( ic, "Syntax error" );
511                                imc_logout( ic, TRUE );
512                                return 0;
513                        }
514                       
515                        /* We got added by someone. If we don't have this
516                           person in permit/deny yet, inform the user. */
517                        for( l = ic->permit; l; l = l->next )
518                                if( g_strcasecmp( l->data, cmd[4] ) == 0 )
519                                        return 1;
520                       
521                        for( l = ic->deny; l; l = l->next )
522                                if( g_strcasecmp( l->data, cmd[4] ) == 0 )
523                                        return 1;
524                       
525                        msn_buddy_ask( ic, cmd[4], cmd[5] );
526                }
527                else if( num_parts >= 6 && strcmp( cmd[2], "FL" ) == 0 )
528                {
529                        const char *group = NULL;
530                        int num;
531                       
532                        if( cmd[6] != NULL && sscanf( cmd[6], "%d", &num ) == 1 && num < md->groupcount )
533                                group = md->grouplist[num];
534                       
535                        http_decode( cmd[5] );
536                        imcb_add_buddy( ic, cmd[4], group );
537                        imcb_rename_buddy( ic, cmd[4], cmd[5] );
538                }
539        }
540        else if( strcmp( cmd[0], "OUT" ) == 0 )
541        {
542                int allow_reconnect = TRUE;
543               
544                if( cmd[1] && strcmp( cmd[1], "OTH" ) == 0 )
545                {
546                        imcb_error( ic, "Someone else logged in with your account" );
547                        allow_reconnect = FALSE;
548                }
549                else if( cmd[1] && strcmp( cmd[1], "SSD" ) == 0 )
550                {
551                        imcb_error( ic, "Terminating session because of server shutdown" );
552                }
553                else
554                {
555                        imcb_error( ic, "Session terminated by remote server (reason unknown)" );
556                }
557               
558                imc_logout( ic, allow_reconnect );
559                return( 0 );
560        }
561#if 0
562        /* Discard this one completely for now since I don't care about the ack
563           and since MSN servers can apparently screw up the formatting. */
564        else if( strcmp( cmd[0], "REA" ) == 0 )
565        {
566                if( num_parts != 5 )
567                {
568                        imcb_error( ic, "Syntax error" );
569                        imc_logout( ic, TRUE );
570                        return( 0 );
571                }
572               
573                if( g_strcasecmp( cmd[3], ic->acc->user ) == 0 )
574                {
575                        set_t *s;
576                       
577                        http_decode( cmd[4] );
578                        strncpy( ic->displayname, cmd[4], sizeof( ic->displayname ) );
579                        ic->displayname[sizeof(ic->displayname)-1] = 0;
580                       
581                        if( ( s = set_find( &ic->acc->set, "display_name" ) ) )
582                        {
583                                g_free( s->value );
584                                s->value = g_strdup( cmd[4] );
585                        }
586                }
587                else
588                {
589                        /* This is not supposed to happen, but let's handle it anyway... */
590                        http_decode( cmd[4] );
591                        imcb_rename_buddy( ic, cmd[3], cmd[4] );
592                }
593        }
594#endif
595        else if( strcmp( cmd[0], "IPG" ) == 0 )
596        {
597                imcb_error( ic, "Received IPG command, we don't handle them yet." );
598               
599                md->handler->msglen = atoi( cmd[1] );
600               
601                if( md->handler->msglen <= 0 )
602                {
603                        imcb_error( ic, "Syntax error" );
604                        imc_logout( ic, TRUE );
605                        return( 0 );
606                }
607        }
608        else if( strcmp( cmd[0], "ADG" ) == 0 )
609        {
610                char *group = g_strdup( cmd[3] );
611                int groupnum, i;
612                GSList *l, *next;
613               
614                http_decode( group );
615                if( sscanf( cmd[4], "%d", &groupnum ) == 1 )
616                {
617                        if( groupnum >= md->groupcount )
618                        {
619                                md->grouplist = g_renew( char *, md->grouplist, groupnum + 1 );
620                                for( i = md->groupcount; i <= groupnum; i ++ )
621                                        md->grouplist[i] = NULL;
622                                md->groupcount = groupnum + 1;
623                        }
624                        g_free( md->grouplist[groupnum] );
625                        md->grouplist[groupnum] = group;
626                }
627                else
628                {
629                        /* Shouldn't happen, but if it does, give up on the group. */
630                        g_free( group );
631                        imcb_error( ic, "Syntax error" );
632                        imc_logout( ic, TRUE );
633                        return 0;
634                }
635               
636                for( l = md->grpq; l; l = next )
637                {
638                        struct msn_groupadd *ga = l->data;
639                        next = l->next;
640                        if( g_strcasecmp( ga->group, group ) == 0 )
641                        {
642                                if( !msn_buddy_list_add( ic, "FL", ga->who, ga->who, group ) )
643                                        return 0;
644                               
645                                g_free( ga->group );
646                                g_free( ga->who );
647                                g_free( ga );
648                                md->grpq = g_slist_remove( md->grpq, ga );
649                        }
650                }
651        }
652        else if( strcmp( cmd[0], "GCF" ) == 0 )
653        {
654                /* Coming up is cmd[2] bytes of stuff we're supposed to
655                   censore. Meh. */
656                md->handler->msglen = atoi( cmd[2] );
657        }
658        else if( isdigit( cmd[0][0] ) )
659        {
660                int num = atoi( cmd[0] );
661                const struct msn_status_code *err = msn_status_by_number( num );
662               
663                imcb_error( ic, "Error reported by MSN server: %s", err->text );
664               
665                if( err->flags & STATUS_FATAL )
666                {
667                        imc_logout( ic, TRUE );
668                        return( 0 );
669                }
670        }
671        else
672        {
673                /* debug( "Received unknown command from main server: %s", cmd[0] ); */
674        }
675       
676        return( 1 );
677}
678
679static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts )
680{
681        struct im_connection *ic = data;
682        char *body;
683        int blen = 0;
684       
685        if( !num_parts )
686                return( 1 );
687       
688        if( ( body = strstr( msg, "\r\n\r\n" ) ) )
689        {
690                body += 4;
691                blen = msglen - ( body - msg );
692        }
693       
694        if( strcmp( cmd[0], "MSG" ) == 0 )
695        {
696                if( g_strcasecmp( cmd[1], "Hotmail" ) == 0 )
697                {
698                        char *ct = msn_findheader( msg, "Content-Type:", msglen );
699                       
700                        if( !ct )
701                                return( 1 );
702                       
703                        if( g_strncasecmp( ct, "application/x-msmsgssystemmessage", 33 ) == 0 )
704                        {
705                                char *mtype;
706                                char *arg1;
707                               
708                                if( !body )
709                                        return( 1 );
710                               
711                                mtype = msn_findheader( body, "Type:", blen );
712                                arg1 = msn_findheader( body, "Arg1:", blen );
713                               
714                                if( mtype && strcmp( mtype, "1" ) == 0 )
715                                {
716                                        if( arg1 )
717                                                imcb_log( ic, "The server is going down for maintenance in %s minutes.", arg1 );
718                                }
719                               
720                                g_free( arg1 );
721                                g_free( mtype );
722                        }
723                        else if( g_strncasecmp( ct, "text/x-msmsgsprofile", 20 ) == 0 )
724                        {
725                                /* We don't care about this profile for now... */
726                        }
727                        else if( g_strncasecmp( ct, "text/x-msmsgsinitialemailnotification", 37 ) == 0 )
728                        {
729                                if( set_getbool( &ic->acc->set, "mail_notifications" ) )
730                                {
731                                        char *inbox = msn_findheader( body, "Inbox-Unread:", blen );
732                                        char *folders = msn_findheader( body, "Folders-Unread:", blen );
733
734                                        if( inbox && folders )
735                                                imcb_log( ic, "INBOX contains %s new messages, plus %s messages in other folders.", inbox, folders );
736                                       
737                                        g_free( inbox );
738                                        g_free( folders );
739                                }
740                        }
741                        else if( g_strncasecmp( ct, "text/x-msmsgsemailnotification", 30 ) == 0 )
742                        {
743                                if( set_getbool( &ic->acc->set, "mail_notifications" ) )
744                                {
745                                        char *from = msn_findheader( body, "From-Addr:", blen );
746                                        char *fromname = msn_findheader( body, "From:", blen );
747                                       
748                                        if( from && fromname )
749                                                imcb_log( ic, "Received an e-mail message from %s <%s>.", fromname, from );
750
751                                        g_free( from );
752                                        g_free( fromname );
753                                }
754                        }
755                        else if( g_strncasecmp( ct, "text/x-msmsgsactivemailnotification", 35 ) == 0 )
756                        {
757                                /* Sorry, but this one really is *USELESS* */
758                        }
759                        else
760                        {
761                                debug( "Can't handle %s packet from notification server", ct );
762                        }
763                       
764                        g_free( ct );
765                }
766        }
767       
768        return( 1 );
769}
770
771void msn_auth_got_passport_token( struct im_connection *ic, char *token )
772{
773        struct msn_data *md;
774       
775        /* Dead connection? */
776        if( g_slist_find( msn_connections, ic ) == NULL )
777                return;
778       
779        md = ic->proto_data;
780       
781        {
782                char buf[1024];
783               
784                g_snprintf( buf, sizeof( buf ), "USR %d SSO S %s %s\r\n", ++md->trId, md->tokens[0], token );
785                msn_write( ic, buf, strlen( buf ) );
786        }
787}
788
789static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name )
790{
791        set_t *s;
792       
793        if( ( s = set_find( &ic->acc->set, "display_name" ) ) == NULL )
794                return FALSE; /* Shouldn't happen.. */
795       
796        http_decode( name );
797       
798        if( s->value && strcmp( s->value, name ) == 0 )
799        {
800                return TRUE;
801                /* The names match, nothing to worry about. */
802        }
803        else if( s->value != NULL &&
804                 ( strcmp( name, ic->acc->user ) == 0 ||
805                   set_getbool( &ic->acc->set, "local_display_name" ) ) )
806        {
807                /* The server thinks our display name is our e-mail address
808                   which is probably wrong, or the user *wants* us to do this:
809                   Always use the locally set display_name. */
810                return msn_set_display_name( ic, s->value );
811        }
812        else
813        {
814                if( s->value && *s->value )
815                        imcb_log( ic, "BitlBee thinks your display name is `%s' but "
816                                      "the MSN server says it's `%s'. Using the MSN "
817                                      "server's name. Set local_display_name to true "
818                                      "to use the local name.", s->value, name );
819               
820                if( g_utf8_validate( name, -1, NULL ) )
821                {
822                        g_free( s->value );
823                        s->value = g_strdup( name );
824                }
825                else
826                {
827                        imcb_log( ic, "Warning: Friendly name in server response was corrupted" );
828                }
829               
830                return TRUE;
831        }
832}
Note: See TracBrowser for help on using the repository browser.