Translate

Wednesday, November 9, 2011

MeCloud progetto Cloud computing


MeCloud
Brings me to the cloud!


Introduzione
MeCloud è un'architettura Cloud SaaS (Software as a Service) che permette agli utenti di effettuare l'upload di documenti testuali nei formati txt, rtf e htm, permette di leggere ed editarli direttamente “online” ed inoltre permette di effettuare l'upload di immagini, di visualizzare le immagini caricate e di condividere con altri utenti di MeCloud le immagini e i documenti caricati.
Il servizio è totalmente gratuito e prevede altre features come la cerazione e la gestione di nuove applicazioni e l'inserimento di inserzioni pubblicitarie e script per il SEO (Search Engine Optimization) però queste funzioni (seppur previste nel Web Service) non sono state realizzate nel sito di testing come caso di studio per l'esame di Web.

Architettura per l'implementazione reale (business):
                                                                  
Questa soluzione prevede un server contenente apache e il sito in php, N server (virtuali) in cloud sparsi per il mondo ospitanti ognuno un Web Service MeCloud e X server SQL in replica tra loro (tutti contengono gli stessi dati) con X << N .
Il database di MeCloud prevede una soluzione che permette di gestire utenti diversi su diversi Web Service e addirittura documenti (file degli utenti) diversi su Web Services diversi.
Cioè se l'utente n1 effettua l'upload del file “xyz” tale file sarà caricato su un WebService scelto mediante una politica di random o performance. Così più file di ogni utente vengono caricati su diversi WebServices sparsi per il globo terrestre (the cloud).
Inoltre se altri utenti sono abilitati ad accedere a tali file, perché esplicitamente condivisi, questi potranno accederci senza problemi usando tutti i diversi Web Services necessari, tutto questo a totale insaputa dell'utente finale.  In questo modo si realizza la relazione molti a molti (un grafo) tipica di un social network.... però di files e applicazioni online!
Questa architettura viene chiamata “Cloud Balancing” e solo poche aziende al mondo la possiedono (Google App Engine, Amazon EC2).

MeCloud Web Service
Il Web Service di MeCloud si divide in 2 sotto servizi:

  • Web Service SOAP per l'autenticazione e l'interscambio di informazioni da e verso il sito o un'applicazione esterna.
  • Web Service HTTP Request per la creazione di path virtuali verso i file e lo streaming del contenuto dei file attraverso HTTP.

Per evitare di dare l'accesso diretto (la full path) del file presente sul server al client, il Web Service, mediante il secondo sotto servizio, ad ogni richiesta crea una path virtuale verso il file e lo trasferisce al client mediante http. Tale path virtuale è data dal passaggio di parametri queli l'ID del file richiesto e il TokenID (cifrato con RSA a 1024 bit e codificato in base64) della sessione.
Per maggiori informazioni riguardo il sistema di cifratura usato fare riferimento alla sezione Sicurezza in MeCloud del presente documento.
La path virtuale verso un documento (o immagine) quindi sarà così modellata:
http://mecloud.us:8081/file?id=”idDelFile”&tk=”idCifratoEcodificatoDellaSessione”
Il parametro tk è il TokenID della sessione: ogni utente dopo aver effettuato il login ha un tokenid, tale stringa di 32 caratteri rappresenta l'utente all'interno del sistema. La stringa viene rigenerata a random ad ogni login ed è diversa per ogni utente.
Ho implementato un algoritmo di “collision prevent” per la generazione automatica di stringhe a 32 caratteri (vedere  funzione RandomString di MeCloudService.asmx.cs).


Il web service soap MeCloudService utilizza il protocollo di comunicazione SOAP (Simple Object Access Protocol) versione 1.1 e 1.2 che si attiene alle specifiche REST dove:
Lo stato dell'applicazione e le funzionalità sono divisi in Risorse WEB
§  Ogni risorsa è unica e indirizzabile usando sintassi universale per uso nei link ipertestuali
§  Tutte le risorse sono condivise come interfaccia uniforme per il trasferimento di stato tra client e risorse, questo consiste in:
§  un insieme vincolato di operazioni ben definite
§  un insieme vincolato di contenuti, opzionalmente supportato da codice on demand
§  un protocollo che è:
§  Client-Server
§  Stateless
§  Cachable
§  A livelli

Il Web Service nonostante sia implementato in C# .NET gira su Linux Ubuntu 11.04 grazie al framework open source Mono che ne garantisce anche la portabilità su piattaforme Windows e Unix Like a 32 o 64 bit senza bisogno di ricompilare il tutto per la specifica architettura.
Lista dei metodi implementati in MeCloudService Web Service:








Operation / Method Name
SOAPAction*
Input Message
Output Message
Login
http://mecloud.us/Login
LostPassword
http://mecloud.us/LostPassword
ShareItem
http://mecloud.us/ShareItem
SendInvitations
http://mecloud.us/SendInvitations
DeleteItem
http://mecloud.us/DeleteItem
GetLinearizedListOfItems
http://mecloud.us/GetLinearizedListOfItems
Register
http://mecloud.us/Register
UploadFile
http://mecloud.us/UploadFile
AddApp
http://mecloud.us/AddApp
ShareApp
http://mecloud.us/ShareApp
RemoveAppAssociation
http://mecloud.us/RemoveAppAssociation
GetAppList
http://mecloud.us/GetAppList
StoreSettings
http://mecloud.us/StoreSettings
GetSettings
http://mecloud.us/GetSettings
GetUserInfo
http://mecloud.us/GetUserInfo

  • Il Metodo Login :  Il Metodo di Login accetta 3 parametri in input:



     Input Parameters

encryptedBase64Mail
string
encryptedBas64Password
string
encryptedBase64APIKey
string


     Output Parameters

LoginResult
string

Tale metodo permette di autenticarsi nel sistema MeCloud.
Il sito invia i parametri (mail, password e API Key) cifrati con la chiave pubblica del sistema e codificati in base64. Il WS dopo aver decodificato da base64 a UTF-8 la stringa e dopo aver decriptato la stessa, effettua una query sul db per vedere se la API Key è presente, se il risultato è affermativo allora la procedura continua, altrimenti il WS ritorna un errore di “bad API Key”. Dopodiché si verifica la presenza della mail nel db e in caso affermativo si estrae la password e la si confronta con la password passata in input dal sito. Le password sono “case sensitive”. Se le password coincidono, il WS ritornerà in output il TokenID (generato automaticamente in questo istante e che ha la durata dell’intera sessione per poi essere rigenerato) della sessione ma non cifrato, in caso contrario un errore di “bad password”.

  • Il Metodo LostPassword: Accetta in input un solo parametro:

Input Parameters
encryptedBase64Mail
string

Questo metodo server a rinviare la password in caso di smarrimento.
Se la Mail cifrata e codificata è presente nel database, allora verrà estratta la relativa password e quest’ultima verrà inviata mediante una mail alla mailbox relativa. Se la password non è presente, nulla verrà inviato. Il metodo non restituisce alcun parametro (void).

  • Il Metodo ShareItem: Accetta 4 parametri in ingresso:
Input Parameters
base64EncryptedAPIKey
string
base64EncryptedToken
string
base64EncryptedOtherUserMail
string
ItemID
string

        • Output Parameters
ShareItemResult
string


            Questo metodo permette di condividere un oggetto (immagine o documento) con più utenti.
            Il metodo accetta in input 3 parametri cifrati e l’ItemID non cifrato.
Il sistema dopo aver decriptato e decodificato tutti i parametri in ingresso controlla la     presenza dell’API Key, estrae l’ID dell’utente (colui che condivide il documento) dal TokenID della sessione e l’id del secondo utente, colui che subirà la condivisione dal parametro otherUserMail. Dopodiché associa nella tabella del database USERSTOITEM lo stesso item a più utenti (nel esempio solo 2), l’utente che ha subìto la condivisione dell’item riceverà una mail che lo informa dell’avvenuta condivisione.

  • Il Metodo SendInvitations: accetta un solo parametro in ingresso, cioè la mail di colui che riceverà l’invito. Esso serve per inviare inviti ad usare MeCloud a persone non ancora registrate. Non effettuerà alcun controllo.
  • Il Metodo DeleteItem: Serve a cancellare un item. Verrà cancellata sia la presenza fisica del file sul sistema di storage che tutte le referenze relative nel database.
Tale metodo accetta 3 parametri in input:
Input Parameters
base64EncryptedAPIKey
string
base64EncryptedToken
string
ItemID
string


Output Parameters

DeleteItemResult
string
Dopo aver decodificato e decriptato i dati in input (tranne ItemID il quale non è cifrato) viene controllata la presenza dell’API Key nel DB, viene estratto l’user id relativo al TokenID passato e viene verificata l’esistenza dell’associazione userid -> itemid nella tabella USERSTOITEM del database. In caso affermativo, l’eliminazione può avere atto:
viene cancellato l’item dalla tabella ITEM e dalla tabella USERSTOITEM e dopo viene cancellato il relativo file fisico dal sistema di storage.

§  Il Metodo GetLinearizedListOfItems: ha il compito di ritornare una lista linearizzata contenente gli items di ogni utente. Tale lista è una stringa dove ogni item diverso è separato dall’altro item mediante il simbolo “pipe” |. La stringa in output sarà così formattata: FileName1,MimeType1,ServerAddress1,ItemID1|FileName2,MimeType2,ServerAddress2,ItemName2|

Ho deciso di usare una lista linearizzata perché non è sempre vero che tutti i linguaggi di programmazione gestiscono array di stringhe serializzate su XML. Quindi, per compatibilità, ho deciso di linearizzare il tutto. Il quale verrà poi splittato in array di stringhe da chi invoca il WS.
Input Parameters
base64EncryptedAPIKey
string
base64EncryptedToken
string


Output Parameters

GetLinearizedListOfItemsResult
string



§  Il Metodo Register : permette di restrarsi al sistema
I parametri sono :
Input Parameters
encryptedBase64Mail
string
encryptedBas64Password
string
encryptedBase64RealName
string
encryptedBase64LastName
string


Output Parameters

RegisterResult
string
I parametri in input sono 4 però RealName e LastName sono facoltativi, infatti non vengono usati da MeCloud (sito) in PHP.
Il sistema restituisce una stringa contenente “ok” se la registrazione ha avuto successo, altrimenti riporta il tipo di errore (ad esempio “Already Registered”).

§  Il Metodo UploadFile: permette di caricare file sul cloud. I file devono avere dimensione inferiore a 25 MBytes e possono essere soltanto del tipo accettato dal web service, infatti esso controlla il MimeType del file prima della memorizzazione. I tipi supportati dal WS sono: PDF, JPG,PNG,GIF,TIFF,MP3,DOC,DOCX,TXT,RTF,PPT,XLS.


Input Parameters

encryptedBase64Token
string
encryptedBase64APIKey
string
data
base64Binary
encryptedBase64MimeType
string
encryptedBase64FileNameWithoutPath
string


Output Parameters

UploadFileResult
string
Tutti i parametri tranne l’array di bytes da trasferire sono codificati e criptati con RSA.
Una volta che i dati sono arrivati al WebService mediante SOAP, quest’ultimo controlla la dimensione dei bytes, i quali devono essere < 25Mbytes. Poi controlla la correttezza dell’API Key, recupera le informazioni riguardo l’utente mediante il TokenID, analizza il tipo mime ed è pronto per scrivere il file sullo storage.
Se ci sono alcuni problemi durante la scrittura, un’eccezione verrà sollevata e il file non verrà salvato e la procedura verrà chiusa automaticamente.
Se il file viene scritto senza problemi, verranno create dei reference all’interno delle tabelle ITEMS e USERSTOITEM, dove la tabella ITEMS conterrà tutte le informazioni riguardanti il file caricato, la tabella USERSTOITEM invece conterrà la relazione itemid -> userid.



§  Il Metodo GetUserInfo: è importante per l’integrazione API e l’interazione con altre applicazioni le quali vogliono recuperare informazioni riguardo l’utente. Per esempio Facebook o Google mettono a disposizione degli strumenti simili per “tirar fuori” informazioni riguardo l’utente. In questo caso MeCloud ritorna solo l’user id e la mail dell’utente. La password non uscirà mai dal sitema, potrà soltanto essere reinviata alla mail del associata per il recupero della stessa.




Input Parameters

encryptedBase64Token
string
encryptedBase64APIKey
string


Output Parameters

GetUserInfoResult
string

§  I Metodi AddApp, ShareApp, RemoveAppAssociation, GetAppList, StoreSettings, GetSettings sono REALMENTE implementati all’interno di Mecloud Service WS ma non sono stati implementati nel sito in php a causa della scarsità di tempo a disposizione.
Tali metodi permettono agli utenti di memorizzare delle proprie applicazioni (RIA) e linkarle all’interno del sistema MeCloud, dando l’opportunità all’utente di creare il proprio contenuto.
Sicurezza in MeCloud

In un Web Service di uso pubblico la sicurezza delle informazioni memorizzate è fondamentale.
Dalla letteratura informatica si evince che al momento gli algoritmi di cifratura più sicuri (il che significa non sicuri al 100%) sono gli algoritmi a chiave pubblica OTP (one time pad).
A causa dell'overhead causato dal continuo generare di chiavi per ogni richiesta scambiata tra il sito ed il Web Service (multi-tier architecture), non è consigliabile usare un sistema (per quanto matematicamente dimostrato come il più sicuro) one time pad. Per MeCloud ho deciso di cifrare con l'algoritmo RSA  a 1024 bit solo alcune informazioni scambiate tra il Web Service e il sito in PHP. Per mantenere la compatibilità tra i due sistemi ho usato uno strumento di generazione chiavi molto conosciuto ed ultra testato : OpenSSL.
Con OpenSSL ho generato la chiave pubblica, privata, modulo e il certificato.
Tali file risiedono sia nella directory “certificates” del sito in php che nella directory “certificates” del web service MeCloud Service.
Come precendentemente descritto  molti metodi del web service accettano in ingresso dei parametri cifrati, di solito sono l'API Key e il Token ID.
Abbiamo già parlato del TokenID, ma non dell' API Key. Ogni Web Service che si rispetti ha un APIKey (Google Map, Youtube, Facebook Web Service ed ecc...), questo ApiKey identifica l'applicazione che sta effettuando la chiamata al web service e quest'ultimo può applicare delle policy di sicurezza diverse per ogni applicazione che si interfaccia verso di esso: ad esempio l'API Key di un'applicazione per smartphone (Android ad esempio) sarà certamente diversa da quella del sito MeCloud o da un'applicazione desktop di MeCloud.
Per quanto riguarda la sicurezza, possono accedere a Mecloud Service WS solo gli API Key prememorizzati nel database, cioè solo le applicazioni autorizzate.
Questi parametri (API Key e TokenID) vengono cifrati (mediante la chiave pubblica) e codificati in base64 dal sito in php e poi inviati via SOAP al web service MeCloud Service, il quale provvederà a decodificarli e decriptarli mediante il binomio chiave pubblica e privata tipico di un sistema di cifratura asimmetrico .
Anche il Web Service HTTP (il secondo web service integrato in MeCloud) usa il sistema di decifraggio RSA per decriptare il TokenID dell'utente e creare la path virtuale verso il file, il quale viene inviato in streaming.
I dati binari trasferiti  tra l'utente e il sito e tra il sito e il web service non sono cifrati. Cifrare tutti i dati “costerebbe” significativamente sulle performance fino a rendere il servizio inutilizzabile.
D'altro canto non è possibile tirar fuori i dati dal WS manualmente poiché il TokenID della sessione è sempre trasferito cifrato.
Ecco la funzione (php) di cifratura :

function encryptAndEncodeToBase64($data){
         $server_public_key = openssl_pkey_get_public(file_get_contents("certificates/publickey.pem"));
         openssl_public_encrypt($data, $encrypted, $server_public_key);
         return base64_encode($encrypted);

}

Ecco la funzione di decriptaggio in c#:

Carico le chiavi e creo l'oggetto RSA che mi permetterà di effettuare il decriptaggio
if(myCert2 == null || rsa == null){
                                               myCert2 = new X509Certificate2(certificatesPath+"mecloudprivatekey.pfx",privatePassw,X509KeyStorageFlags.MachineKeySet);
                                                   rsa = (RSACryptoServiceProvider)myCert2.PrivateKey;
                                                               }
 e per decriptare :
                                               byte[]  decrpyted = rsa.Decrypt(Convert.FromBase64String(encryptedBas64Password), false);
                                               String  loginPwd = System.Text.Encoding.UTF8.GetString(decrpyted);
                                              
                                                               decrpyted = rsa.Decrypt(Convert.FromBase64String(encryptedBase64APIKey), false);
                                               String  ApiKey = System.Text.Encoding.UTF8.GetString(decrpyted);
                                              

Il database MySQL interno a MeCloud è protetto da password e non accetta connessioni in ingresso da host non autorizzati. In questo caso ho opportunamente modificato il file /etc/hosts facendo in modo che l'unico host autorizzato sia il loop back device, ovvero localhost (127.0.01).
MeCloud usa un sistema di passaggio di TokenID su url e mediante l’uso di cookie contenente il TokenID. Quando l’utente effettua il logout, il cookie relativo alla sessione viene cancellato (si imposta la scadenza ad un numero molto precedente) e l'utente è costretto ad effettuare nuovamente il login.


Interfacciamento tra PHP e MeCloudService Web Service
Invece di utilizzare direttamente la classe SoapClient messa a disposizione dagli sviluppatori di PHP, ho deciso di generarmi in automatico una classe wrapper chiamata MeCloudService.php che si occupa di invocare i metodi tramite SoapClient e ritornare i valori ricevuti dal web service.
Il tool usato si chiama WSDLInterpreter e genera in automatico la classe PHP mediante l'analisi del WSDL di Mecloud Web Service.
Il protocollo usato per l'interscambio di informazioni è SOAP. Soap permette di trasferire “buste” XML contenenti dati serializzati. XML è anche usato in altri protocolli come XML-RPC ed ecc...
Avrei potuto usare Json invece di XML risparmiando banda e tempo di trasferimento dei dati, ma a discapito della compatibilità.
In futuro MeCloud sarà implementato mediante chiamate asincrone (tipo Ajax) e scambi di dati tra il broswer, il lato server del sito e il Web Service.
A titolo informativo, sono in corso alcune polemiche riguardo l'uso di Ajax browser side... si pensa che l'uso abbondante di questa tecnologia nelle pagine dinamiche sia fonte di exploit (fondamentalmente Cross Site Scripting e Denial Of Service) andando contro la sicurezza degli utenti, dei loro dati e del servizio offerto. Per questo motivo si stanno implementando nuovi protocolli come WebSocket. Sto quindi pensando di implementare MeCloud con chiamate SOAP asincrone lato server per poi portare in “superficie” solo il risultato senza invocare il Web Service esterno direttamente da javascript (browser side).
Cioè login e password vengono inviate “Server side” e ciò che il Web Service ritorna viene prima elaborato dal lato server del sito e poi portato in superficie rendendolo disponibile ai controlli in javascript.

Esempio di invocazione del Web Service MeCloudService con PHP

Per l’invocazione del WS di MeCloud via PHP ho generato la classe MeCloudService.php.
L’uso è il seguente:
Innanzitutto bisogna includere tale classe nel sorgente con questa istruzione:
require_once("MeCloudService.php");

Qui di seguito ci sono le istruzioni per invocare il web service. Nell’esempio recupererò l’userid e la mail dell’utente invocando il metodo GetUserInfo del web service.

$mecloud = new MeCloudService();

$parameters = new GetUserInfo();

$parameters->encryptedBase64Token = encryptAndEncodeToBase64($TokenID);

$parameters->encryptedBase64APIKey = encryptAndEncodeToBase64("FLJQPZTXOEXWOJGLXZLMDPSEQPOQWYXO");

$response = $mecloud->GetUserInfo($parameters)->GetUserInfoResult;



//la variabile $response contiene il valore: userid,mail

//ora divido (split) la stringa in 2 paramtri userid e mail

$temp = explode(",",$response);



$userid = $temp[0];

$mail = $temp[1];





Il Database di MeCloud


Per migliorare le performance ho ridotto al minimo l'uso di join e ogni selezione è fatta basandosi unicamente dagli ID dei vari elementi. Addirittura la tabella con più elementi è la tabella USERSTO ITEM la quale ha solo due campi rappresentati dagli ID. Le performance, nonostante le basse capacità della macchina virtuale, sono abbastanza soddisfacenti.

Il progetto è scaricabile da qui: MeCloud.zip - 1.2 MB       

Il software è rilasciato gratuitamente per l'utilizzo, ma non può essere modificato ne integralmente ne in parte. Dal software in questione non possono essere copiati pezzi di codice o risorse varie.
Scaricando il software si accettano le suddette condizioni d'uso.

MyFreeCopyright.com Registered & Protected  (c) 2011 by Vincenzo Dentamaro

Leggimi TTS Engine (Text To Speech) Sapi 5.1

Leggimi TTS SR è un programma scritto da me nel 2006/2007 per il dettato, il riconoscimento vocale e l'esecuzione di comandi vocali su un pc Windows.
Usa le SAPI (Speech Application Programming Interfaces) di Windows in versione 5.1.
E' gratuiro e pienamente configurabile.


Ho voluto reinserirlo perché la mia vecchia pagina su Xoomer è andata perduta. 


Quindi guardate qui cosa avevo inventato 5 anni fa.
Ecco il link per scaricarlo