Pari-IM: aggiornamento client MSN alla versione 15

Pagina creata da Claudio Leone
 
CONTINUA A LEGGERE
Pari-IM: aggiornamento client MSN alla versione 15
UNIVERSITA’ DEGLI STUDI DI PADOVA
                    Facoltà di Ingegneria
        Corso di Laurea Triennale in Ingegneria Informatica

                         TESI DI LAUREA

Pari-IM: aggiornamento client
        MSN alla versione 15

RELATORE: Chiar.mo Prof. Enoch Peserico Stecchini Negri De Salvi

               CORRELATORE: Ing. Paolo Bertasi

                LAUREANDO: Gianluigi Disconzi

                          A.A. 2010-2011
Pari-IM: aggiornamento client MSN alla versione 15
1
2

Prefazione
Il presente elaborato costituisce la relazione del lavoro da me personalmente svolto, tra Set-
tembre 2010 e Marzo 2011, sulla modica del client di Instant Messaging di PariPari al ne di
implementare una versione aggiornata del protocollo MSN.
    Inizialmente si introducono le principali caratteristiche del progetto PariPari. Si passa quindi
a presentare concetti, convenzioni e speciche che saranno utili nell'arontare le parti centrali
della trattazione:   si forniscono pertanto i rudimenti dell'Instant Messaging e della presenza
online, si studia la composizione del protocollo MSN e come funziona l'infrastruttura ad esso
sottesa, e viene inne introdotto il plugin di IM che nel progetto PariPari ha tra gli altri il
compito di interfacciarsi correttamente alla rete Messenger.
    La seconda parte descrive il lavoro svolto per l'adeguamento del client alla versione di pro-
tocollo a cui ci si è pressi di aderire:   in particolare vengono trattati gli interventi eseguiti
per l'aggiornamento della procedura di login nella rete MSN, ivi compresa l'autenticazione e la
gestione delle credenziali di accesso, sino a giungere alla gestione delle liste di contatti e delle
sessioni di chat vere e proprie. Oltre che alla procedura di ingresso, questa parte spiega come si
è intervenuti nella gestione dei parametri di riconoscimento durante la connessione.
    Viene quindi descritto il lavoro eseguito sul le transfer:     si approfondisce innanzitutto la
conoscenza del protocollo MSN introducendone i concetti specici per la trasmissione di dati per
passare poi a presentare gli interventi eettuati sul client.
    La relazione si conclude con una serie di riessioni sullo stato attuale del plugin e si presentano
le possibilità di sviluppo future.
3
4                                                                              1 Il progetto PariPari

                                     Fig. 1.1: Logo di PariPari

Parte I. Introduzione
1 Il progetto PariPari
PariPari è una rete Peer-To-Peer serverless multifunzionale; il suo scopo principale è di fornire
numerosi servizi, che oggi si possono avere solo utilizzando diverse applicazioni separate, in un
unico programma - [Bertasi(2005)]. Il linguaggio di programmazione usato per PariPari è Java
e, nonostante presenti degli svantaggi (principalmente scarse prestazioni) molti sono i vantaggi
tra i quali:

    •   Maggior portabilità a causa dell'indipendenza dalla piattaforma;

    •   Maggior sicurezza dell'applicazione;

    •   Uso facilitato per l'utente nale grazie a Java Web Start che permette di scaricare ed
        eseguire le applicazioni direttamente dal web nonché di avere sempre l'ultima versione del
        software disponibile, evitando procedure di installazione;

    •   Sviluppo facilitato di nuovi servizi per il programmatore grazie alle numerose API disponi-
        bili;

L'adozione dell'Extreme Programming, una metodologia agile che prevede la scrittura a più mani
del codice e il suo continuo testing per renderlo robusto e privo di errori, consente di coordinare
gli interventi di più persone all'interno dei gruppi di lavoro.
1.1 La struttura della rete                                                                                       5

1.1 La struttura della rete
PariPari non prevede l'utilizzo di nodi gerarchizzati (client o server) bensì un numero di nodi
equivalenti (peer), che fungono sia da cliente sia da servente verso gli altri nodi della rete.
L'assenza di server centralizzati nella struttura peer-to-peer comporta numerosi vantaggi:

      •   Indipendenza: si annulla il rischio di collasso nel caso in cui uno o più server non fossero
          disponibili;

      •   Adabilità: si azzera il rischio di attacchi di tipo Denial of Service ;
                                                                                        1

      •   Scalabilità: poiché ogni nodo contribuisce con le proprie risorse alla sopravvivenza della
          rete, non è necessario che la potenza dei server venga aumentata per scongiurare il collasso
          della rete stessa.

PariPari implementa una variante dell'algoritmo Kademlia, utilizzato anche da altri programmi
peer-to-peer come, ad esempio, Emule.

1.2 I plug-in e i servizi
PariPari (inteso come programma applicativo) presenta una struttura modulare molto semplice
ed ecace organizzata in plug-in. Un plug-in è un programma non autonomo che interagisce con
un altro programma per ampliarne le funzioni. Grazie a questa strategia, il programma principale
può essere ampliato senza necessità di essere modicato; inoltre possono essere aggiunte innite
funzioni mantenendo la medesima architettura principale. I plug-in in PariPari si dividono in
due diverse tipologie:

      •   Cerchia interna: Core, Crediti, Connettività, Storage e DHT forniscono servizi di base per
          il funzionamento della rete e si coordinano con il Core per gestire richieste di risorse quali
          rete, disco, etc.

      •   Cerchia esterna:     Emule, Torrent, Voip, IM, IRC, DNS, etc.             Si basano sull'utilizzo dei
          plug-in della cerchia interna per fornire i servizi specici.

Il core ha il compito di gestire le richieste ed assegnare equamente le risorse disponibili per evitare
starvation
              2 a favore di un singolo plug-in.

2 Il protocollo MSN Messenger
La dicitura MSN Messenger viene utilizzata per riferirsi generalmente all'infrastruttura di rete
in cui si organizza il servizio di messaggistica istantanea sviluppato da Microsoft. Il protocollo
che ne determina il funzionamento e ne codica il comportamento è generalmente indicato con
la sigla MSNP (      Microsoft Notication Protocol) a cui segue la versione dello stesso quando vi
sia necessità di indicarlo.
      Il protocollo MSN appartiene alla famiglia dei protocolli di presenza e messaggistica istanta-
nea, i quali descrivono sistemi per lo scambio in tempo reale di informazioni sul proprio stato di
presenza e di messaggi tra computer connessi alla rete. Una lettura interessante che ne descrive
approfonditamente i concetti è l'RFC 2778: [Day et al.(2000)Day, Rosenberg, and Sugano].
      Sia per il protocollo di comunicazione che per la struttura della rete e dei servizi Microsoft,
non esistono documenti uciali sui quali basare il lavoro di sviluppo di un client (fatto salvo

  1   Denial of Service: impedire l'accesso autorizzato a risorse, oppure ritardare l'esecuzione di operazione time-
critical.
  2   Starvation o stallo individuale : fenomeno per il quale un processo ( o un insieme di processi ) monopolizza
gran parte delle risorse disponibili nel sistema
6                                                                                  2 Il protocollo MSN Messenger

un internet draft di stampo informativo - [Movva and Lai(1999)]); è anzi vero che molte delle
loro caratteristiche, come si vedrà, sono state modellate con l'intento di scoraggiare se non di
impedire totalmente l'accesso al servizio da parte di client non uciali.
        La mancanza di disponibilità di documentazione riguardante MSN Messenger ha portato alla
creazione di diverse comunità virtuali dedite allo studio del sistema IM di Microsoft.                      La loro
attività ha reso possibile conoscere in modo sucientemente approfondito il servizio, al punto
che al momento in cui si scrive si stima esistano almeno 20 client in grado di supportarlo, secon-
do [Wikipedia(2011a)] (conteggiando solamente quelli a grande diusione e con codice stabile),
mentre fonti del 2003 ne citano addirittura 41, vedi [Hypotetic.org(2003b)].
        Il presente lavoro trae spunto da informazioni reperite presso summenzionate comunità (in
particolar modo dal forum di [MSNFanatic(2011a)]); tuttavia la parte preponderante e sicura-
mente più interessante è stata infatti quella di validare tali informazioni (talvolta non del tutto
complete o adabili) mediante o verica diretta contro altri client già funzionanti o mediante
utilizzo di strumenti atti allo scopo, su tutti Wireshark.

Convenzioni          Nel corso dell'esposizione si presenteranno diversi scambi di comandi tra client
e server. Verranno utilizzate le seguenti due notazioni grache per indicare la direzione in cui
viaggiano tali messaggi:

            >>> Messaggio inviato dal client al server
2.1 Cenni sull'infrastruttura                                                                                   7

                                Inizio connessione rete MSN
                                             1

                                                    Dispatch Server                       Notification Server

                                             2

                                                             3

                           1. Il client invia la richiesta al Dispatch Server
                           2. Il DS risponde fornendo l'indirizzo di un Notification Server
                           • Chiusura connessione con il DS
                            3. Il client effettua la connessione al NS ed avvia la procedura di login

                                       Inizio sessione di chat
                                             1

                                                  Notification Server                     Switchboard Server

                                             2
                                                                                                ...

                                                                 3
                                                             ...

                                                                                          Switchboard Server
                                                                 n

                           1. Il client invia la richiesta al Notification Server
                           2. Il DS risponde fornendo l'indirizzo di uno Switchboard Server
                           • La connessione con il NS rimane aperta
                            3. Il client si connette al NS e può iniziare ad invitare contatti
                           …
                           n. Il client, mantenendo la connessione con un unico NS, può
                           avviare più sessioni di chat su Switchboard Server diversi

                                     Invito a sessione di chat
                               Si rifà alla procedura di inizio sessione: il punto 1. in questo caso
                               viene eliso in quanto la sessione viene avviata da un altro client

                                                                     Invio di uno o più messaggi
                                 Legenda                             Connessione

                          Fig. 2.1: Schema di funzionamento della rete MSN
8                                                                               2 Il protocollo MSN Messenger

        Esiste inne una quarta famiglia di macchine a cui non è stato dato un nome formalmente, in
quanto sono state introdotte nella versione 13 del protocollo MSNP (la nomenclatura utilizzata
fa sempre riferimento al draft [Movva and Lai(1999)]): queste hanno la funzione di memorizzare
e fornire a richiesta le liste di utenti associate a ciascun contatto, tipicamente mediante richieste
SOAP, vedi [W3C(2007)].

2.2 MSNP
Il cuore del protocollo MSN è dato dall'insieme di regole di grammatica e di sintassi da applicare
ai comandi scambiati tra client e server. Tutto ciò che viene trasmesso tra essi è un comando,
il quale è rappresentato da una combinazione di 3 lettere maiuscole seguite da dei parametri
(specici per ciaschedun comando) separati da uno spazio; il tutto è terminato dal carattere
speciale  \r\n.
        Lo schema tipico prevede che sia il client ad inviare per primo un comando al server, prestando
attenzione a numerarlo con un identicativo detto              TrID                              4
                                                                       (Transaction identier) ; a questo il
server risponde con un altro comando, citando il TrID fornito dal client.
        Oltre ai comandi che prevedono questa semplice sintassi ve ne sono di altri tipi:

        •   con payload: prevedono la presenza di ulteriori dati dopo i caratteri di terminazione; la
            gestione del payload verrà discussa in seguito;

        •   di errore: inviati dal server al client, hanno la peculiarità di essere indicati da un codice
            numerico a 3 cifre in sostituzione delle 3 lettere maiuscole;

        •   comandi asincroni: sono inviati dal server senza che vi sia una richiesta esplicita da parte
            del client; talvolta alcuni di questi comandi utilizzano un TrID pari a zero.

Alcuni tra i comandi di maggiore importanza all'interno del protocollo verranno presentati alla
bisogna durante questa presentazione.

2.2.1 La versione 15 del protocollo
La versione a cui ci si è pressi di aderire durante il lavoro svolto sul plugin IM PariPari è la
numero 15, rilasciata ad Ottobre 2006 con il client MSN Live 8.1, e tutt'ora supportata dalla
rete Messenger.
        L'importanza di giungere ad un pieno supporto a detta versione risiede principalmente nel
numero e nella tipologia di funzionalità implementate, e non secondariamente nella costante
opera di epurazione delle versioni di protocollo obsolete costantemente compiuta da Microsoft
(soprattutto in caso di riscontro di vulnerabilità, vedi [Microsoft.com(2007)]) mediante blocco
dell'accesso a client di versioni eccessivamente vecchie.
        Le novità più interessanti introdotte in MSNP15 includono:

        •   nuovo metodo di autenticazione basato su Single Sign On (SSO): una volta vericato l'ac-
            count al momento dell'accesso, viene rilasciato un ticket valido per l'intera sessione con
            cui eettuare le operazioni che richiedono una verica dell'identità; questo meccanismo di
            fatto integra la rete MSN all'interno del sistema di servizi Microsoft (Hotmail, Live Spaces,
            etc...);

        •   miglioramento delle procedure SOAP per la gestione delle liste dei contatti, soprattuto
            grazie all'impiego dei ticket di sessione;

    4   Il TrID deve essere univoco ed ogni successione di TrID è associata ad una connessione, pertanto è lecito
che un client invii un comando con TrID 10 ad un server ne invii un altro ad un secondo server con lo stesso
identicativo; se in una stessa connessione un TrID viene però ripetuto avviene la disconnessione immediata senza
preavviso.
9

   •   proprietà dell'utente gestite in modalità roaming: le informazioni personali sono conservate
       su server e vengono inviate al client al momento del login, rendendo indipendenti tali
       informazioni dal particolare client utilizzato e, per estensione, dal luogo da cui ci si connette
       alla rete.

3 Pari-IM: introduzione all'architettura del plugin
Il plugin IM è stato progettato con l'intenzione di essere reso il più generico ed estensibile pos-
sibile; il suo scopo non è di implementare un protocollo di IM in particolare, bensì di fornire
un'infrastruttura di base su cui costruire plugin specici per i vari protocolli.
   Come si vede il nucleo del plugin IM astrae dalla peculiare struttura di qualsivoglia protocollo
di messaggistica istantanea. Il suo obbiettivo è quello di fornire ai progettisti di plugin specici
ed, in ultima istanza, agli utenti stessi un mezzo per comunicare automaticamente con tutti i
protocolli desiderati, come descritto in [Vallini(2009)].
   La costruzione di un plugin che vada ad innestarsi su quello già presente deve pertanto essere
progettato pensando a due parti:

   •   il listener: la parte di plugin che si fa carico di inviare e ricevere comandi da/al server, i
       quali sono chiaramente dipendenti dal tipo di protocollo che si intende usare;

   •   il core vero e proprio: essendo la sua architettura relativamente indipendente dal plugin
       IM lo si può strutturare con un certo grado di libertà.

Il plugin MSN, già giunto ad un buon punto di maturazione dal punto di vista architetturale,
vedi anche [Montini(2009)], può essere schematizzato secondo la gura 3.2.
   Dall'immagine si possono collocare concettualmente tutti i vari componenti, ciascheduno
implementato come classe. Con questo schema in mente è ora possibile presentare nel dettaglio
gli interventi apportati ai vari componenti: nel prosieguo della trattazione si presenteranno di
volta in volta gli aspetti peculiari che contraddistinguono il protocollo MSNP15 dalle versioni
precedenti e verrà spiegato come tali caratteristiche sono state implementate nel plugin.
10                                                                                                        3 Pari-IM: introduzione all'architettura del plugin

                                                                              socket

                                                                                                                          socket
                          socket

                                                                                                                                                                      socket
               Listener MSN                                        Listener MSN                              Listener ICQ                                        Listener
                                                                                                                                                                 JABBER
                         NS                                         SBserver1

     ConnectionManager

                                                                                                                                                                               outForwarder

                                   IN                                                                                                     forwardToListeners()
                                                                                       hashTable

                                                                                        prot_server_client | listener 1
                                                                                                                                             _prot_server(destinatario)_client(mittente)_string\r\n
                                                                                        prot_server_client | listener 2
          _prot_server(mittente)_client(destinatario)_string\r\n
                                                                                        prot_server_client | listener 3
                                                                                                                                             _prot_server(destinatario)_client(mittente)_string\r\n
                                                                                        prot_server_client | listener 4
          _prot_server(mittente)_client(destinatario)_string\r\n

                                                                                                                                             _prot_server(destinatario)_client(mittente)_string\r\n

          _prot_server(mittente)_client(destinatario)_string\r\n

         forwardToClients()
       inForwarder
                      listOfClients                                                                                                                                                  OUT
                                                                                                                                   Riferimento a
               Riferimento a                         Riferimento a                     Riferimento a                                   client
                client MSN                             client ICQ                      client YAHOO                                   JABBER

           InString                                                InString                                         InString                                              InString

                CLIENT                                             CLIENT                                           CLIENT                                           CLIENT
                 MSN                                                ICQ                                             YA HOO                                           JABBER

                                                                   Fig. 3.1: Struttura del plugin IM
11

      Rete MSN: NS, SB, DS

                                           Gestisce le connessioni in ingresso ed uscita:
                                           .readFromSocket()
                 ImListener                .writeOnSocket(String)

Infrastruttura
plugin IM

        Code circolari IN/OUT

                         Client MSN – ver. 15

                                        Gestisce, organizza e coordina i vari componenti del
                 MsnClient              plugin. Ad esso fanno capo altre classi di supporto come
                                        MsnUser, MsnGroups, MsnHashTables, etc...

                                                         Assembla i comandi con
                    MsnMessageCreator                    payload spezzati dal listener

                                                         Riconosce i comandi inviati dal
                   MsnMessageActuator                    server ed in base a questi decide il
                                                         comportamento del client

                                 Gestisce l'interazione con l'utente: invia alla rete i comandi
    MsnGuiInterpreter            quando richiesto, comunica all'interfaccia grafica il verificarsi di
                                 eventi basati sulla ricezione di comandi dalla rete MSN

                          SOAPManager                                     Le classi Soap si incaricano
                                                                          di reperire e gestire le liste di
                                                                          contatti
                             SOAPPArser

                                                            Rete MSN: Soap server

   Interfaccia utente               Gestisce l'interazione con l'utente: invia i comandi
                                    quando richiesto o comunica il verificarsi di eventi
                                    basati sulla ricezione di comandi dalla rete MSN

                        Fig. 3.2: Schema plugin MSN
12                                                                         4 Procedura di autenticazione e login

     Parte II. Interventi sul client
     In questa parte si presenterà il lavoro svolto per aggiornare il client. In questa sezione nulla è
     stato fatto per alterare lo schema di funzionamento del client: i meccanismi di interrelazione
     tra i suoi componenti e le logiche di funzionamento sono rimaste immutate. Semplicemente si
     sono apportate modiche mirate al codice deputato a svolgere talune operazioni, rispettando le
     modiche apportate al protocollo dagli architetti Microsoft.

     4 Procedura di autenticazione e login
     La prima parte del lavoro svolta è stata nalizzata alla realizzazione di una procedura di login che
     rispettasse quanto previsto dal protocollo MSNP15. A dierenza di quanto previsto nelle versioni
     precedenti la procedura di riconoscimento delle credenziali e di conferimento di certicato per
     l'accesso alla rete MSN prevede lo scambio di informazioni con più entità e con varie metodologie.
          Questa scelta è stata dettata dall'impossibilità di compiere l'accesso alla rete Messenger con
     un qualsiasi algoritmo di autenticazione antecedente a quello previsto nella versione 15, algoritmo
     non implementato nel client PariPari al momento dell'inizio del lavoro di chi scrive.
          Le classi interessate da questa prima azione di aggiornamento sono state MsnMessageActuator
     per quanto riguarda la risposta ai comandi ricevuti dal NS, SOAPManager e SOAPPArser per
     la gestione della richiesta dei token di sicurezza.

     4.1 Ottenimento policy e nonce
     Dopo aver negoziato la versione di protocollo e di client come da prassi generale, segue la co-
     municazione da parte del client del nome utente, a cui il server risponde fornendo dei security
     tokens, secondo il seguente abstract:

            >>> USR  SSO I \r\n
            
10           < ps:AuthInfo     xmlns:ps = " http: // schemas . microsoft . com / Passport / SoapServices / PPCRL " Id = "
                   PPAuthInfo " >
11               < ps:HostingApp > {7108 E71A -9926 -4 FCB - BCC9 -9 A9D3F32E423 } 
12               < ps:BinaryVersion >4 
13               < ps:UIVersion >1 
14               < ps:Cookies >
15               < ps:RequestParams > AQAAAAIAAABsYwQAAAAxMDMz 
16           
17           < wsse:Security >
18               < wsse:UsernameToken Id =" user " >
19                   < wsse:Username > UserEmail 
20                   < wsse:Password > UserPassword 
21               
22           
23
4.2 Ottenimento ticket token e binary secret                                                                          13

24      < Body >
25                 < ps:RequestMultipleSecurityTokens
26                     xmlns:ps =" http: // schemas . microsoft . com / Passport / SoapServices / PPCRL " Id =" RSTS " >
27                     < wst:RequestSecurityToken Id = " RST0 " >
28                         < wst:RequestType > http: // schemas . xmlsoap . org / ws /2004/04/ security / trust / Issue
29                         
30                         < wsp:AppliesTo >
31                             < wsa:EndpointReference >
32                                 < wsa:Address > http: // Passport . NET / tb 
33                             
34                         
35                     
36                     < wst:RequestSecurityToken Id = " RSTn " >
37                         < wst:RequestType > http: // schemas . xmlsoap . org / ws /2004/04/ security / trust / Issue
38                         
39                         < wsp:AppliesTo >
40                             < wsa:EndpointReference >
41                                 < wsa:Address > domain 
42                             
43                         
44                         < wsse:PolicyReference URI =" policy parameter " > 
45                     
46
47                    ...
48                    ...
49
50               
51       
52   

         Mediante questa operazione si comunicano al server le credenziali per l'accesso (vedi righe 19
     e 20), ovvero nome utente (nella forma di indirizzo email scelto in fase di iscrizione al servizio),
     password ad esso associato, policy di accesso (secondo quanto ci è stato indicato dal NS con il
     precedente comando), ed indicazione sul servizio o sui servizi per i quali si richiede autenticazione.
         Va infatti notato che questa procedura è utilizzata per l'accesso a tutta la rete di servizi pub-
     blici Microsoft, tra cui Messenger, Hotmail, Spaces, Live Storage, etc. Nella pratica, lo schema
     soprastante può essere utilizzato per richiedere molteplici accessi simultanei ai servizi semplice-
     mente aggiungendo al documento SOAP dei sotto alberi con radice  seguendo l'opportuna numerazione RST0, RST1, etc.
         A questo comando il server risponde con:

 1   
 2       
 3           
 4       
 5       
 6           < wst : RequestSecurityTokenResponseCollection
 7               xmlns : soap =" http :// schemas . xmlsoap . org / soap / envelope /"
 8               xmlns : wst =" http :// schemas . xmlsoap . org / ws /2004/04/ trust "
 9               xmlns : wsse =" http :// schemas . xmlsoap . org / ws /2003/06/ secext "
10               xmlns : wsu =" http :// docs . oasis - open . org / wss /2004/01/ oasis -200401 - wss - wssecurity -
                         utility -1.0. xsd "
11               xmlns : saml =" urn : oasis : names : tc : SAML :1.0: assertion "
12               xmlns : wsp =" http :// schemas . xmlsoap . org / ws /2002/12/ policy "
13               xmlns : psf =" http :// schemas . microsoft . com / Passport / SoapServices / SOAPFault ">
14               < wst : RequestSecurityTokenResponse >
15                    < wst : TokenType > urn : passport : legacy 
16                         < wsp : AppliesTo xmlns : wsa =" http :// schemas . xmlsoap . org / ws /2004/03/ addressing " >
17                             < wsa : EndpointReference >
18                             < wsa : Address > http :// Passport . NET / tb 
19                         
20                    
21                    < wst : LifeTime >
22                         < wsu : Created >2006 -12 -06 T05 :12:10 Z 
23                         < wsu : Expires >2006 -12 -07 T05 :12:10 Z 
24                    
25                    < wst : RequestedSecurityToken >
26                         < EncryptedData xmlns =" http :// www . w3 . org /2001/04/ xmlenc #"
27                         Id =" BinaryDAToken0 "
28                         Type =" http :// www . w3 . org /2001/04/ xmlenc # Element ">
29                             < EncryptionMethod Algorithm =" http :// www . w3 . org /2001/04/ xmlenc # tripledes - cbc
                                      ">
14                                                                       4 Procedura di autenticazione e login

30                               
31                          
32                                http :// Passport . NET / STS 
33                          
34                          < CipherData >
35                               < CipherValue >
36                                   
37                               
38                          
39                      
40                 
41                 < wst : RequestedTokenReference >
42                      < wsse : KeyIdentifier ValueType =" urn : passport " > 
43                      < wsse : Reference URI ="# BinaryDAToken0 " > 
44                 
45                 < wst : RequestedProofToken >
46                      < wst : BinarySecret > ignore this one 
47                 
48             
49             < wst : RequestSecurityTokenResponse >
50                 < wst : TokenType > urn : passport : compact 
51                 < wsp : AppliesTo xmlns : wsa =" http :// schemas . xmlsoap . org / ws /2004/03/ addressing " >
52                      < wsa : EndpointReference >
53                          < wsa : Address > messengerclear . live . com 
54                      
55                 
56                 < wst : LifeTime >
57                      < wsu : Created >2006 -12 -06 T05 :12:10 Z 
58                      < wsu : Expires >2006 -12 -06 T13 :12:10 Z 
59                 
60                 < wst : RequestedSecurityToken >
61                      < wsse : BinarySecurityToken Id =" Compactn ">
62                          t= < Ticket >& p=
63                      
64                 
65                 < wst : RequestedTokenReference >
66                      < wsse : KeyIdentifier ValueType =" urn : passport : compact " > 
67                      < wsse : Reference URI ="# Compactn " > 
68                 
69                 < wst : RequestedProofToken >
70                      < wst : BinarySecret > Binary Secret 
71                 
72             
73             < wst : RequestSecurityTokenResponse >
74                 < wst : TokenType > urn : passport : legacy 
75                 < wsp : AppliesTo xmlns : wsa =" http :// schemas . xmlsoap . org / ws /2004/03/ addressing " >
76                      < wsa : EndpointReference >
77                          < wsa : Address > site domain 
78                      
79                 
80                 < wst : LifeTime >
81                      < wsu : Created >2006 -12 -06 T05 :12:10 Z 
82                      < wsu : Expires >2006 -12 -06 T05 :20:30 Z 
83                 
84                 < wst : RequestedSecurityToken >
85                      < wsse : BinarySecurityToken Id =" PPTokenn "> t=< Ticket Token >& p = 
86                 
87                 < wst : RequestedTokenReference >
88                      < wsse : KeyIdentifier ValueType =" urn : passport " > 
89                      < wsse : Reference URI ="# PPTokenn " > 
90                 
91             
92
93             ...
94             ...
95
96           
97       
98   

          Come si nota, nel documento SOAP ad ogni nodo               
     corrisponde la risposta del server per ogni richiesta di autenticazione ai servizi: alla numerazione
     imposta dal client con     RSTn     il server risponde con      Compactn.        Il sotto albero che contiene
     il segreto binario (security token) per l'autenticazione al servizio Messenger è contraddistinto
4.3 Uso dei token                                                                                   15

dal nodo   messengerclear.live.com. Inne, nell'ultimo sotto
albero    viene riportato il Ticket Token. Diversamente
dai security token i quali vengono utilizzati solamente al momento dell'autenticazione per ciascun
servizio, il Ticket Token è unico ed ha validità per tutta la sessione (in caso di login eseguito con
successo); con questo espediente si minimizzano gli scambi di dati tra server e client e si ha un
modo sicuro per stabilire l'identità di un utente. Questa metodologia di identicazione prende il
nome di   Single Sign-On (SSO).

4.3 Uso dei token
In questa sezione si utilizzeranno nonce e binary secret per elaborare una stringa da ritornare al
NS in modo da dimostrare la nostra identità e poter accedere al servizio Messenger.

4.3.1 decodica Base64
Per prima cosa il binary secret viene semplicemente decodicato dalla sua rappresentazione
corrente in Base64. Si chiami    key1    la stringa risultante.
   L'algoritmo di decifratura qui utilizzato è quello fornito dal pacchetto Bouncy Castle.

4.3.2 calcolo di key2 e key3
Si calcolano ora altre due chiavi, rispettivamente    key2 e key3, secondo l'algoritmo sotto riportato:

  1     hash1   =   SHA1 - HMAC ( key1 ," WS - SecureConversationSESSION KEY HASH ")
  2     hash2   =   SHA1 - HMAC ( key1 , hash1 +" WS - SecureConversationSESSION KEY HASH ")
  3     hash3   =   SHA1 - HMAC ( key1 , hash1 )
  4     hash4   =   SHA1 - HMAC ( key1 , hash3 +" WS - SecureConversationSESSION KEY HASH ")

key2    viene creata come array di 24 byte:        i primi 20 corrispondono ad    hash2,   gli ultimi 4
corrispondono ai primi 4 di     hash4.
   key3 è calcolata mediante lo stesso algoritmo, tuttavia nel suo caso si utilizza la stringa "WS-
SecureConversationSESSION KEY ENCRYPTION" come input dell'algoritmo di criptazione. Il
calcolo della funzione di hash è stato eseguito mediante chiamata alla classe javax.crypto.Mac
della libreria standard Java:

        Mac mac = Mac.getInstance("HmacSHA1");

4.3.3 hash
Si applica al nonce il codice di autenticazione HMAC con algoritmo di hash SHA1 con chiave
key2:

        hash = SHA1-HMAC(key2, nonce)

4.3.4 padding del nonce
Il nonce viene ora esteso accodandovi 8 byte di valore 0x08.

4.3.5 vettore di numeri casuale
Si genera un vettore di 8 byte casuali.
16                                                               4 Procedura di autenticazione e login

4.3.6 criptazione triplo DES in modalità CBC
Si opera ora la cifratura del nonce paddato nel passo 2.3.4. Per fare questo si usa       key3   come
chiave dell'algoritmo, come vettore di inizializzazione (IV) si usa il vettore di 8 byte casuali testé
creato; l'output risultante sarà un vettore di 72 byte che verrà chiamato    encrypted.
     Anche in questo caso è stata usata la libreria standard di Java (javax.crypto.Cipher):

         Cipher c2 = Cipher.getInstance( "DESede/CBC/PKCS5Padding" );

4.3.7 creazione struttura dati da inviare al server
Ottenuti questi dati, è stato necessario organizzarli all'interno di una struttura comprensibile
dal server anché possa avvenirne il controllo. La documentazione riportata in rete descrive la
struttura in sintassi C come segue:

         struct tagMSGRUSRKEY { // Header
             unsigned int uStructHeaderSize ; // 28. Does not count data
             unsigned int uCryptMode ; // CRYPT_MODE_CBC (1)
             unsigned int uCipherType ; // TripleDES (0 x6603 )
             unsigned int uHashType ; // SHA1 (0 x8004 )
             unsigned int uIVLen ; // 8
             unsigned int uHashLen ; // 20
             unsigned int uCipherLen ; // 72 // Data
             unsigned char aIVBytes [8];
             unsigned char aHashBytes [20];
             unsigned char aCipherBytes [72];
         } MSGUSRKEY ;

Va notato che tutti i campi qui riportati sono da considerarsi Little-Endian; gli unsigned int
sono da 4 byte (alcuni compilatori C per macchine da 64bit allocano 8 byte per tali dati). La
traslazione in Java qui eseguita si è limitata alla creazione di un array di 128 byte così creato:

     1   byte [] answer = new byte [128]; // the data header is always like this :
     2   byte [] tmp = Base64 . decode ( " HAAAAAEAAAADZgAABIAAAAgAAAAUAAAASAAAAE == " );
     3   // and then the body of the answer
     4   for ( int i =0; i
4.3 Uso dei token                                                                 17

4.3.9 Il codice
Di seguito si riporta l'implementazione dell'algoritmo testé esposto.

  1   // Step 1: base64 decode the binary secret
  2   byte [] key1 = Base64 . decode ( binarySecret );
  3
  4   // Step 2: Calculate key2 and key3 as :
  5   byte [] key2 = deriveKey ( " WS - SecureConversationSESSION KEY HASH " , key1 );
  6
  7   // Step 3: For key3 we ' ll use " WS - SecureConversationSESSION KEY ENCRYPTION "
  8   byte [] key3 = deriveKey ( " WS - SecureConversationSESSION KEY ENCRYPTION " , key1 );
  9
 10   // Step 4: hash = SHA1 - HMAC ( key2 , nonce )
 11   byte [] hash = new byte [20];
 12   try {
 13      Mac mac = Mac . getInstance ( " HmacSHA1 " );
 14      SecretKeySpec secret = new SecretKeySpec ( key2 , " HmacSHA1 " );
 15      mac . init ( secret );
 16      hash = mac . doFinal ( base64nonce . getBytes ());
 17   } catch ( Exception e ) { System . out . println ( e . getMessage ()); }
 18
 19   // Step 5: pad the nonce with 8 bytes which value is 0 x08
 20   // and creates a byte [8] of random values
 21   byte [] nonceBytes = new byte [ base64nonce . length ()+8];
 22   byte [] tmp1 = base64nonce . getBytes ();
 23   for ( int i =0; i
18                                          5 Sincronizzazione iniziale: Membership List ed Address Book

 53   catch ( NoSuchPaddingException e ) { e . printStackTrace (); }
 54   try {
 55      c2 . init ( Cipher . ENCRYPT_MODE , key , paramSpec );
 56   } catch ( InvalidKeyException e ) { e . printStackTrace (); }
 57   catch ( InvalidAlgorithmParameterException e ) { e . printStackTrace (); }
 58   try {
 59      encrypted = c2 . doFinal ( nonceBytes );
 60   } catch ( IllegalBlockSizeException e ) { e . printStackTrace (); }
 61   catch ( BadPaddingException e ) { e . printStackTrace (); }
 62
 63   // Step 7: create the final data object
 64   byte [] answer = new byte [128];
 65   // the data header is always like this :
 66   byte [] tmp = Base64 . decode ( " HAAAAAEAAAADZgAABIAAAAgAAAAUAAAASAAAAE == " );
 67
 68   // and then the body of the answer
 69   for ( int i =0; i
5.1 Membership List                                                                                                19

         Terminata l'autenticazione si procede con la sincronizzazione iniziale del client: vanno ese-
     guite in sequenza l'aggiornamento della Membership List e dell'Address Book. Entrambe queste
     azioni sono invocate dalla classe MsnGuiInterpreter durante procedura di login. La loro eettiva
     esecuzione è demandata alla classe SOAPManager per quanto riguarda l'invio della richiesta al
     server e la ricezione della risposta da quest'ultimo, ed alla classe SOAPPArser per l'analisi della
     risposta.

     5.1 Membership List
     La richiesta per la Membership List si esegue con il POST all'URL                 http://contacts.msn.com/
     abservice/SharingService.asmx              del seguente oggetto SOAP:

 1   Content - Type: text / xml , charset = utf -8
 2   Connection: Keep - Alive
 3   Cache - Control: no - cache
 4   SOAPAction: http: // www . msn . com / webservices / AddressBook / FindMembership
 5   Host: contacts . msn . com
 6   Content - Length: String . valueOf ( message . length ))
 7
 8   
 9   < soap:Envelope xmlns:soap =\ http: // schemas . xmlsoap . org / soap / envelope /\ >
10      < soap:Header xmlns:soap =\ http: // schemas . xmlsoap . org / soap / envelope /\ >
11         < ABApplicationHeader xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
12                  < ApplicationId xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
13            CFE80F9D -180 F -4399 -82 AB -413 F33A1FA11
14         
15            < IsMigration xmlns =\ http: // www . msn . com / webservices / AddressBook \ > false 
16            < PartnerScenario xmlns =\ http: // www . msn . com / webservices / AddressBook \ > Initial 
17         
18         < ABAuthHeader xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
19            < ManagedGroupRequest xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
20               false
21            
22            < TicketToken > ticket 
23         
24      
25      < soap:Body xmlns:soap =\ http: // schemas . xmlsoap . org / soap / envelope /\ >
26         < FindMembership xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
27            < serviceFilter xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
28               < Types xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
29                  < ServiceType xmlns =\ http: // www . msn . com / webservices / AddressBook \ > Messenger 
30                  < ServiceType xmlns =\ http: // www . msn . com / webservices / AddressBook \ > Invitation 
31                  < ServiceType xmlns =\ http: // www . msn . com / webservices / AddressBook \ > SocialNetwork 
32                  < ServiceType xmlns =\ http: // www . msn . com / webservices / AddressBook \ > Space 
33                  < ServiceType xmlns =\ http: // www . msn . com / webservices / AddressBook \ > Profile 
34               
35            
36         
37      
38   

         Come si può notare l'unica informazione che si trasmette al server è il Ticket ottenuto al
     login, in base ad esso il server riconosce l'utente e gli invia le informazioni corrette. La risposta
     del server ha una forma come segue:

 1   
 2   < soap:Envelope xmlns:soap =" http: // schemas . xmlsoap . org / soap / envelope / "
 3   xmlns:xsi =" http: // www . w3 . org /2001/ XMLSchema - instance "
 4   xmlns:xsd =" http: // www . w3 . org /2001/ XMLSchema " >
 5      < soap:Header >
 6         < ServiceHeader xmlns = " http: // www . msn . com / webservices / AddressBook " >
 7            < Version > 15.04.1114.0000 
 8            < CacheKey >
 9   14 r2 ; lGDEA5Gkyc2MW2HdypHpx3RQbK0YPzi8Rd1uJNG0B /0 xVS3xEsV0P /d +
            PL23oLbONg7znjBxBuCIJilaz8C6xifTfnjfu7d8Mr2IpJ4QfM81vmnMR + RnPne3vDpRr98HF /
            UNCIdmEwI4F0pgtGTkmhvTyVFdvxBhFyer6eVwGKI =
20                                                5 Sincronizzazione iniziale: Membership List ed Address Book

10              
11              < CacheKeyChanged > true 
12              < PreferredHostName > proxy - bay . contacts . msn . com 
13              < SessionId > ABCH .9 b61b6cd - c09a -4 bb7 -9429 -9 bec9b4e3204 
14           
15        
16        < soap:Body >
17           < FindMembershipResponse xmlns =" http: // www . msn . com / webservices / AddressBook " >
18              < FindMembershipResult >
19                 < Services >
20                    < Service >
21                       < Memberships >
22                          < Membership >
23                             < MemberRole > Reverse 
24                             < Members >
25                                < Member xsi:type = " PassportMember " >
26                                   < MembershipId > 23 
27                                   < Type > Passport 
28                                   < DisplayName > buddy1 
29                                   < State > Accepted 
30                                   < Deleted > false 
31                                   < LastChanged > 2010 -07 -27 T13:30:38 .56 -07 :00 
32                                   < JoinedDate > 2010 -07 -27 T13:30:38 .463 -07 :00 
33                                   < ExpirationDate > 0001 -01 -01 T00:00:00 
34                                   < Changes / >
35                                   < PassportName > buddy1@hotmail . com 
36                                   < IsPassportNameHidden > false 
37                                   < PassportId >0 
38                                   < CID > -4695065377381910654 
39                                   < PassportChanges / >
40                                   < LookedupByCID > false 
41                                
42                             
43                             < MembershipIsComplete > true 
44                          
45                          < Membership >
46                             < MemberRole > Pending 
47                             < Members >
48                                < Member xsi:type = " PassportMember " >
49                                   < MembershipId > 22 
50                                   < Type > Passport 
51                                   < DisplayName > buddy2 
52                                   < State > Accepted 
53                                   < Deleted > false 
54                                   < LastChanged > 2010 -07 -27 T13:30:38 .56 -07 :00 
55                                   < JoinedDate > 2010 -07 -27 T13:30:38 .463 -07 :00 
56                                   < ExpirationDate > 0001 -01 -01 T00:00:00 
57                                   < Changes / >
58                                   < PassportName > buddy2@hotmail . com 
59                                   < IsPassportNameHidden > false 
60                                   < PassportId >0 
61                                   < CID > -4695065377381910654 
62                                   < PassportChanges / >
63                                   < LookedupByCID > false 
64                                
65                             
66                          
67
68                      ...
69
70                    
71                    < Info >
72                       < Handle >
73                          5 
74                          < Type > SocialNetwork 
75                          < ForeignId / >
76                       
77                       < InverseRequired > false 
78                       < AuthorizationCriteria > TrustLevel3FMBR ; OwnerRM 
79                       < IsBot > false 
80                    
81                    < Changes / >
82                    < LastChange > 2010 -11 -26 T02:49:52 .747 -08 :00 
83                    < CreatedDate > 2010 -10 -08 T11:02:28 .903 -07 :00 
84                    < Deleted > false 
85
5.2 Address Book                                                                                        21

 86               
 87               < OwnerNamespace >
 88                  < Info >
 89                     < Handle >
 90                         00000000 -0000 -0000 -0000 -000000000000 
 91                        < IsPassportNameHidden > false 
 92                        < CID >0 
 93                     
 94                     < CreatorPuid >0 
 95                     < CreatorCID > -7926224447272188711 
 96                     < CreatorPassportName > userMail@hotmail . com 
 97                     < CircleAttributes >
 98                        < IsPresenceEnabled > false 
 99                        < Domain > WindowsLive 
100                     
101                     < MessengerApplicationServiceCreated > true 
102                  
103                  < Changes / >
104                  < CreateDate > 2010 -07 -27 T09:29:15 .22 -07 :00 
105                  < LastChange > 2010 -12 -10 T01:08:00 .75 -08 :00 
106               
107            
108         
109      
110   

         In questo documento sono contenuti tutti i contatti dell'utente, suddivisi per ruoli. Dai nodi
            dipartono infatti dei sotto alberi contenenti per ogni lista gli utenti ed i loro dati
      principali. Le liste più importanti sono:

         •   Forward:     la lista forward è la lista principale dei contatti; dei contatti qui presenti è stata
             eseguita la sottoscrizione della presenza, ovverosia si è fatta richiesta di ricevere tutte le
             informazioni personali e quelle che riguardo il loro stato (in linea, disconnesso, occupato,
             etc...).

         •   Reverse:     costituisce la lista di contatti che hanno il nostro nominativo inserito nella loro
             forward list; si tratta di una lista informativa e non può essere chiaramente soggetta a
             modiche da parte dell'utente.

         •   Allow:     è la lista di contatti a cui è concesso di essere noticati sulla nostra presenza
             online; si noti la dierenza tra reverse list, ovvero degli gli utenti che chiedono di poter
             essere informati sul nostro stato, ed allowed list, in cui compaiono solo quelli che si decide
             di tenere informati.

         •   Block:     ovvero la lista dei contatti a cui non è concesso di ricevere notiche sul nostro
             stato di presenza; questi non hanno la possibilità di vedere nemmeno gli aggiornamenti sui
             messaggi personali e se tentano di instaurare una sessione di chat vengono bloccati dal SB
             con un messaggio di errore utente non in linea. Ovviamente la block list è disgiunta dalla
             allow list, ciononostante esiste un codice di errore apposito (il     219) in risposta al tentativo
             di inserire un contatto in ambo le liste.

         •   Pending:      la lista dei contatti che hanno inoltrato una richiesta di amicizia al nostro
             contatto e non sono ancora stati inseriti né nella allow né nella block list, pur essendo nella
             reverse.

      5.2 Address Book
      L'azione da eseguire mediante SOAP per la richiesta dell'Address Book è:

  1   Content - Type: text / xml , charset = utf -8
  2   Connection: Keep - Alive
  3   Cache - Control: no - cache
  4   SOAPAction: http: // www . msn . com / webservices / AddressBook / FindMembership
  5   Host: contacts . msn . com
22                                             5 Sincronizzazione iniziale: Membership List ed Address Book

 6   Content - Length: String . valueOf ( message . length ))
 7
 8   
 9   < soap:Envelope
10   xmlns:soap =\ http: // schemas . xmlsoap . org / soap / envelope /\
11   xmlns:xsi =\ http: // www . w3 . org /2001/ XMLSchema - instance \
12   xmlns:xsd =\ http: // www . w3 . org /2001/ XMLSchema \
13   xmlns:soapenc =\ http: // schemas . xmlsoap . org / soap / encoding /\ >
14      < soap:Header >
15         < ABApplicationHeader xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
16            < ApplicationId > CFE80F9D -180 F -4399 -82 AB -413 F33A1FA11 
17            < IsMigration > false 
18            < PartnerScenario > Initial 
19         
20         < ABAuthHeader xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
21            < ManagedGroupRequest > false 
22            < TicketToken > ticket 
23         
24      
25      < soap:Body >
26      < ABFindAll xmlns =\ http: // www . msn . com / webservices / AddressBook \ >
27            < abId > 00000000 -0000 -0000 -0000 -000000000000 
28            < abView > Full 
29            < deltasOnly > false 
30            < lastChange > 0001 -01 -01 T00:00:00 .0000000 -08 :00 
31         
32      
33   

          e la relativa risposta inviata dal server:

 1   
 2   < soap:Envelope xmlns:soap =" http: // schemas . xmlsoap . org / soap / envelope / " xmlns:xsi =" http: // www .
           w3 . org /2001/ XMLSchema - instance " xmlns:xsd =" http: // www . w3 . org /2001/ XMLSchema " >
 3       < soap:Header >
 4           < ServiceHeader xmlns =" http: // www . msn . com / webservices / AddressBook " >
 5                < Version > 16.00.1219.0001 
 6                < CacheKey > 
 7                < CacheKeyChanged > true 
 8                < PreferredHostName > proxy - bay . contacts . msn . com 
 9                < SessionId > ABCH .4 e7a061c -1352 -483 c - a377 -2 ee6d68e8669 
10           
11       
12       < soap:Body >
13           < ABFindAllResponse xmlns =" http: // www . msn . com / webservices / AddressBook " >
14                < ABFindAllResult >
15                    < groups >
16                        < Group >
17                            < groupId > da6c1de2 - cda9 -49 de - b2eb - b53eb16bece9 
18                            < groupInfo >
19                                < groupType > c8529ce2 -6 ead -434 d -881 f -341 e17db3ff8 
20                                < name > Preferiti 
21                                < IsNotMobileVisible > false 
22                                < IsPrivate > false 
23                                < IsFavorite > true 
24                            
25                            < propertiesChanged / >
26                            < fDeleted > false 
27                            < lastChange > 2010 -12 -03 T08:49:29 .037 -08 :00 
28                        
29                    
30                    < contacts >
31                        < Contact >
32                            < contactId > c5bd42a3 - f949 -46 c3 - ba24 -295318 cfb798 
33                            < contactInfo >
34                                < annotations >
35                                    < Annotation >
36                                         < Name > MSN . IM . MBEA 
37                                         < Value >0 
38                                    
39                                    < Annotation >
40                                         < Name > MSN . IM . GTC 
41                                         < Value >1 
42                                    
43                                    < Annotation >
44                                         < Name > MSN . IM . BLP 
45                                         < Value >0
5.2 Address Book                                                                               23

 46                              
 47                              < Annotation >
 48                                   < Name > Live . Locale 
 49                                   < Value > 1040 
 50                              
 51                              < Annotation >
 52                                   < Name > Live . Profile . Expression . LastChanged 
 53                                   < Value > 2010 -12 -10 T01:07:38 .34 -08 :00 
 54                              
 55                              < Annotation >
 56                                   < Name > Live . Passport . Birthdate 
 57                                   < Value > 01/01/1974 00 :00:00 
 58                              
 59                              < Annotation >
 60                                   < Name > Live . Passport . Country 
 61                                   < Value > IT 
 62                              
 63                          
 64                          < contactType >Me 
 65                          < quickName >ME 
 66                          < firstName > don 
 67                          < lastName > chisciotte 
 68                          < passportName >im -001 @hotmail . it 
 69                          < IsPassportNameHidden > false 
 70                          < displayName > don 
 71                          < puid >0 
 72                          < CID > -7926224447272188711 
 73                          < IsNotMobileVisible > true 
 74                          < isMobileIMEnabled > false 
 75                          < isMessengerUser > false 
 76                          < isFavorite > false 
 77                          < isSmtp > false 
 78                          < hasSpace > false 
 79                          < spotWatchState > NoDevice 
 80                          < birthdate > 0001 -01 -01 T00:00:00 
 81                          < primaryEmailType > ContactEmailPersonal 
 82                          < PrimaryLocation > ContactLocationPersonal 
 83                          < PrimaryPhone > ContactPhonePersonal 
 84                          < FileAs > chisciotte , don 
 85                          < IsPrivate > false 
 86                          < IsHidden > false 
 87                          < Gender > Unspecified 
 88                          < TimeZone > None 
 89                          < PublicDisplayName > don 
 90                          < IsAutoUpdateDisabled > false 
 91                          < IsShellContact > false 
 92                          < TrustLevel >0 
 93                          < PropertiesChanged / >
 94                      
 95                      < propertiesChanged / >
 96                      < fDeleted > false 
 97                      < CreateDate > 2010 -07 -27 T09:29:00 -07 :00 
 98                      < lastChange > 2011 -02 -08 T04:53:17 .29 -08 :00 
 99                      < LastModifiedBy >8 
100                  
101                  < Contact >
102                      < contactId >90 dd2299 - c19b -4 f51 -90 cd -776 d82a14472 
103                      < contactInfo >
104                          < contactType > LivePending 
105                          < quickName > buddyName 
106                          < passportName > buddy@mail . com 
107                          < IsPassportNameHidden > false 
108                          < displayName > MyBro 
109                          < puid >0 
110                          < CID > -1273360585163271030 
111                          < IsNotMobileVisible > false 
112                          < isMobileIMEnabled > false 
113                          < isMessengerUser > true 
114                          < isFavorite > false 
115                          < isSmtp > false 
116                          < hasSpace > false 
117                          < spotWatchState > NoDevice 
118                          < birthdate > 0001 -01 -01 T00:00:00 
119                          < primaryEmailType > ContactEmailPersonal 
120                          < PrimaryLocation > ContactLocationPersonal 
121                          < PrimaryPhone > ContactPhonePersonal
24                                               5 Sincronizzazione iniziale: Membership List ed Address Book

122                               < IsPrivate > false 
123                               < IsHidden > false 
124                               < Gender > Unspecified 
125                               < TimeZone > None 
126                               < IsAutoUpdateDisabled > false 
127                               < IsShellContact > false 
128                               < TrustLevel >2 
129                               < PropertiesChanged / >
130                           
131                           < propertiesChanged / >
132                           < fDeleted > false 
133                           < CreateDate > 2010 -10 -16 T06:50:00 -07 :00 
134                           < lastChange > 2010 -10 -16 T06:50:20 .15 -07 :00 
135                           < CreatedBy >7 
136                           < LastModifiedBy >7 
137                       
138
139                 ...
140
141                   
142                   
143                       < abId > 00000000 -0000 -0000 -0000 -000000000000 
144                       < abInfo >
145                           < MigratedTo >6 
146                           < ownerPuid >0 
147                           < OwnerCID > -7926224447272188711 
148                           < ownerEmail >im -001 @hotmail . it 
149                           < fDefault > true 
150                           < joinedNamespace > false 
151                           < IsBot > false 
152                           < IsParentManaged > false 
153                           < AccountTierLastChanged > 0001 -01 -01 T00:00:00 
154                           < ProfileVersion >0 
155                           < SubscribeExternalPartner > false 
156                           < NotifyExternalPartner > false 
157                           < AddressBookType > Individual 
158                           < MessengerApplicationServiceCreated > true 
159                           < IsBetaMigrated > false 
160                       
161                       < lastChange > 2011 -02 -08 T04:53:17 .29 -08 :00 
162                       < DynamicItemLastChanged > 0001 -01 -01 T00:00:00 
163                       < RecentActivityItemLastChanged > 0001 -01 -01 T00:00:00 
164                       < createDate > 2010 -07 -27 T09:29:15 .22 -07 :00 
165                       < propertiesChanged / >
166                   
167               
168           
169       
170   

           Come si può vedere, mentre la Membership List fornisce i nominativi conosciuti dall'utente,
      suddividendoli per gruppi e liste in base a diritti di visibilità reciproca, lo scopo dell'Address
      Book è quello di fornire informazioni esaustive sui singoli contatti conosciuti. Mediante questo
      documento vengono inoltre rese note al client le informazioni relative all'utente che si sta colle-
      gando alla rete Messenger: per identicare questo utente speciale distinguendolo dai suoi contat-
      ti vengono utilizzati i nodi      Me              e   ME.
      Questo espediente rende possibile all'utente l'utilizzo di più client che in automatico hanno sempre
      le informazioni personali aggiornate.

           Per ovviare alla grandezza del documento inviato in caso di elevato numero di contatti, il
      recupero dell'Address Book può essere realizzato anche solo parzialmente. In questo caso dopo la
      sincronizzazione iniziale al primo login con un dato client si possono salvare in locale i nominativi,
      e per le successive connessioni sarà necessario fare una richiesta per le sole modiche, indicando
      nel nodo    quando è stata fatta l'ultima sincronizzazione (per la prima richiesta si
      indica   0001-01-01T00:00:00.0000000-08:00 come timestamp).
5.2 Address Book                                                                                    25

Implementazione
Sia per la Membership List che per l'Address Book è stato utilizzato il medesimo approccio
nella progettazione e nello sviluppo di codice per la corretta gestione di liste, sottoliste, singoli
utenti e relative proprietà. Entrambe le procedure condividono la struttura realizzativa: la loro
invocazione comporta la chiamata alla classe SOAPManager che è deputata alla creazione del
comando SOAP da inviare, all'instaurazione della connessione http al server, alla ricezione del
messaggio di risposta dal server ed inne al salvataggio di quest'ultimo su disco.
   Una volta eettuate questi passaggi, viene chiamata la classe SOAPPArser che si fa carico
di interpretare la struttura della risposta mediante lettura dell'albero XML in esso contenuta.
Questo passaggio viene realizzato creando un documento DOM parsando i le salvati mediante
la classe DocumentBuilder (javax.xml.parsers)

  1   DocumentBuilder builder =
  2      DocumentBuilderFactory . newInstance (). newDocumentBuilder ();
  3   File f = new File ( root + " im / conf / membership . xml " );
  4   Document document = builder . parse ( f );

Una volta creato l'albero del documento si estraggono le liste di utenti, facendo pesante uso del
metodo   Document.getElementsByTagName(String tagname).

Estrazione Membership List
L' algoritmo per l'estrazione delle liste è il seguente

  1   cerca i nodi con tag " MemberRole "
  2   per ogni valore di tali nodi
  3      cerca i nodi con tag " PassportName "
  4      per ogni nodo trovato
  5         aggiungi l ' utente alla lista che si sta scorrendo

La sua implementazione in Java è risultata abbastanza banale, eccetto che per il nesting dei
due cicli   for:   il metodo   getElementsByTagName   infatti esegue la ricerca all'interno di tutto un
documento, e pertanto è stato necessario all'inizio di ogni ciclo      for   esterno creare un nuovo
albero DOM su cui eettuare la ricerca:

  1   NodeList nl = document . getElementsByTagName ( " MemberRole " ) ;
  2      for ( int i =0; i < nl . getLength () ; i ++) {
  3         String listName = nl . item ( i ) . getFirstChild () . getNodeValue
                 () ;
  4         // Creates the subtree
  5         Document doc = createDomDocument ( nl . item ( i ) . getParentNode
                 () ) ;
  6         NodeList contacts = doc . getElementsByTagName ( " PassportName
                 ");
  7         for ( int j =0; j < contacts . getLength () ; j ++) {
  8             // add the contact to the list listName
  9             ...
 10         }
 11      }

Nessuna modica è stata apportata al codice che gestisce le liste, poiché già presente e funzionante
a partire dall'implementazione del protocollo versione 9.
26                                                                         6 Server pings - Challenges

Estrazione Address Book
La lettura dei dati contenuti nell'Address Book avviene con le stesse metodologie impiegate nel
caso precedente. Non essendo qui presenti dierenti liste da scorrere però l'implementazione è
stata semplicata. Si è comunque ricorso allo stesso espediente di creare dei nuovi documenti
per ogni contatto in modo da poter impiegare il metodo        getElementsByTagName      per la ricerca
dei singoli nodi contenenti le diverse proprietà di un contatto.
     Anche in questo caso i dati estratti sono stati memorizzati su strutture già implementate da
versioni precedenti del client.

Gestione dei contatti
Con metodologie simili a quelle sin qui incontrate, il protocollo MSN permette di gestire ambedue
le liste, fornendo ai client strumenti per aggiungere, rimuovere e modicare contatti.
     Lo sviluppo di queste funzionalità e stato considerato da chi scrive non di primaria importanza
ai ni di ottenere un client immediatamente funzionante e fruibile da parte dell'utente.          Si è
preferito infatti arontare e risolvere altre problematiche relative alla stabilità della connessione
(si veda ad esempio la prossima sezione) o implementare altre funzionalità a più alta priorità.

6 Server pings - Challenges
Avendo come obbiettivo primario quello di consentire una connessione stabile e duratura alla
rete Messenger da parte del nostro client, si è reso necessario lavorare sulla corretta gestione dei
challenge da parte del Notication Server.
     Mentre il client è nella rete MSN, il NS gli invia ad intervalli casuali dei comandi di ping che
hanno il duplice scopo di testare lo stato della connessione e al contempo di vericare l'autenticità
del client connesso. Sulle motivazioni legate a questa verica si possono solamente formulare delle
ipotesi; per questo argomento si rimanda alla sezione conclusiva
     Lo scambio di comandi avviene secondo la sintassi:

         > QRY   32\r\n
6.1 Calcolo della risposta al challenge                                                             27

MsnChallengeHandler, invocata quando necessario da MsnMessageActuator in risposta al CHL
del server.

6.1 Calcolo della risposta al challenge
Per poter calcolare la risposta, sono necessari oltre alla stringa di challenge anche due codici
identicativi che sono propri di ogni build del client uciale (a partire da     MSN Messenger     agli
ultimi   Live Messenger ):   il client ID string ed il client ID code. Attualmente per il client di
PariPari vengono utilizzati i codici di Windows Live Messenger 8.1 client build 8.1.0168.00:

        String IDString = "PROD0113H11T8$X_";
        String IDCode = "RG@XY*28Q5QHS%Q5";

Con questi dati si può iniziare l'elaborazione.

6.1.1 IDString: hash MD5
Si calcola innanzitutto un hash in MD5 della concatenazione tra challenge e IDString

        hash = MD5(challenge + IDString)

il risultato è trasformato in una stringa di cifre esadecimali mediante chiamata del metodo statico

        java.lang.Integer.toHexString(0xFF & hash[i])

su ogni byte del digest ed accodando i risultati in una stringa che è poi convertita in 4 array da
4 long ciascuno

        java.lang.Long.parseLong(reverseHex(Long.toHexString(num)), 16);

questo risultato è inne sottoposto ad una operazione di AND con il valore 0x7FFFFFFF.

6.1.2 IDCode: divisione in DWord
Si crea una nuova stringa data dalla concatenazione di challenge e IDCode e la si rende di
lunghezza pari ad un multiplo di 8 mediante padding con zeri (zeri in formato stringa, ovvero
0, non byte nulli). La stringa risultante viene divisa in parti da 4 byte, ciascuna delle quali
deve essere interpretata come una DWord a rappresentazione testuale, ovvero per ogni byte di
ogni array si esegue l'operazione

        hex += Integer.toHexString((int)char);

6.1.3 Creazione chiave a 64 bit
E' necessario creare una chiave da 64 bit da usare nei passaggi seguenti.          Per questo si cicla
sugli array di byte creati nel passo precedente; creo due variabili    high = low = 0,    poi per ogni
iterazione N:

    •   si crea una variabile temporanea    temp   contenente il valore dell'array corrente (N), la si
        moltiplica per 0x0E79A9C1 e se ne calcola il modulo su 0x7FFFFFFF per evitare overow
        o inversione di segno; al risultato si aggiunge il valore di high;

    • temp    viene moltiplicata per la prima parte dell'hash MD5 ed al risultato si somma la
        seconda parte dello stesso hash; di nuovo se ne calcola il modulo su 0x7FFFFFFF;
28                                                                                             7 Implementazione chat

     •    si aggiorna poi il valore di      high:    lo si aumenta del valore del (N+1)-esimo array, al solito
          calcolando il modulo su 0x7FFFFFFF;

     • high         viene quindi moltiplicata per la terza parte dell'hash MD5 e gli viene sommata la
          quarta parte di detto hash; segue il consueto modulo anti overow/cambio di segno;

     •    si aggiorna inne il valore di      low, la quale viene incrementata di un valore pari alla somma
          di   temp   ed   high;   di questo valore non si calcola il modulo su 0x7FFFFFFF.

Per chiarezza si riporta qui il codice Java per quanto testé esposto:

     1          long high = 0 , low = 0;
     2          for ( int i = 0; i < splitChallenge . length ; i = i + 2) {
     3             long temp = splitChallenge [ i ];
     4             temp = (0 x0E79A9C1 * temp ) % 0 x7FFFFFFF ;
     5             temp += high ;
     6             temp = splitHash [0] * temp + splitHash [1];
     7             temp = temp % 0 x7FFFFFFF ;
     8
     9                high   =     splitChallenge [ i + 1];
 10                   high   =     ( high + temp ) % 0 x7FFFFFFF ;
 11                   high   =     splitHash [2] * high + splitHash [3];
 12                   high   =     high % 0 x7FFFFFFF ;
 13
 14                   low += high + temp ;
 15             }

Finito questo ciclo, alle variabili           high   e   low   vengono aggiunti rispettivamente il secondo ed il
quarto pezzo dell'hash MD5, e di nuovo per entrambe si calcola il modulo su 0x7FFFFFFF.
Fatto questo la chiave da 64 bit che si cercava è pronta:                 high   e   low   hanno questo nome poiché
rappresentano rispettivamente la DWord alta e quella bassa di una QWord da 64 bit.                                È
pertanto suciente shiftare            high   di 32 bit a sinistra ed aggiungere il risultato a       low.

6.1.4 Creazione risposta
La parte nale della computazione della risposta da inviare al server consiste fondamentalmente
nell'operare uno XOR tra la chiave a 64 bit e l'hash calcolato nel punto iniziale.
     L'implementazione di questa operazione è avvenuta tenendo separate le due variabili                       high   e
low      del passo precedente ed eseguendo per ciascuna separatamente lo XOR con 2 delle 4 parti
in cui si era diviso l'hash.
     L'ultimo passaggio prevede la conversione del risultato ottenuto ad una rappresentazione
decimale in formato stringa. Il tutto è stato riassunto nel seguente passaggio:

          long highlow = (i == 0 || i == 2) ? high : low;
          s += Long.toHexString(Long.parseLong(hash.substring(8 * i, 8 * i + 8), 16) ^ highlow);

A questo punto non rimane che assemblare il messaggio di risposta come da sintassi vista ad
inizio capitolo inserendo nel payload la stringa qui creata.

7 Implementazione chat
Il lavoro svolto sinora ha dato al client MSN di PariPari la capacità di collegarsi alla rete Mes-
senger correttamente e di rimanervi per un tempo indenito, superando i controlli imposti dal
Puoi anche leggere