Pari-IM: aggiornamento client MSN alla versione 15
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
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
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