Visualizzazione post con etichetta windows scripting host. Mostra tutti i post
Visualizzazione post con etichetta windows scripting host. Mostra tutti i post

giovedì 23 ottobre 2008

AriaDSL Autologin /3

Segue da AriaDSL Autologin /2.

Effettuare una request HTTP e leggere la relativa response con WSH è relativamente semplice. L'unico aspetto "delicato" è la creazione dell'oggetto XMLHTTP, che viene inizializzato tramite l'invocazione del metodo CreateObject dell'oggetto WScript.

function getPage(strURL)
{
    return httpRequest("GET", strURL, "");
}

function postPage(strURL, strParm)
{
    return httpRequest("POST", strURL, strParm);
}

function httpRequest(requestType, strURL, strParms)
{
    var xmlHTTP = WScript.CreateObject("Microsoft.XMLHTTP")
    xmlHTTP.open(requestType, strURL, false);
    if (strParms=="")
    {
        xmlHTTP.send();
    }
    else
    {
        xmlHTTP.send(strParms);
    }
    return xmlHTTP.responseText;
}

Una piccola funzione per gestire l'accodamento dei parametri all'URL:

function buildParametersList(strParametersList, parameterName, parameterValue)
{
    var result = strParametersList;
    if (strParametersList!="")
    {
        result += "&";
    }
   
    result += parameterName;
    result += "=";
    result += parameterValue
   
    return result;
}

Un po' di espressioni regolari per recuperare la password:

function extractPassword(strReturn)
{
    var infoRE = /hexMD5\('(.*)'\);/;

    var info = infoRE.exec(strReturn);

    var result = RegExp.$1;

    // prende i primi 4 caratteri
    var head = result.substr(0, 4);
   
    // prende dal 39° carattere fino in fondo
    var tail = result.substr(41, result.length-1);
   
    var pass = head + tail;
   
    return pass;
}

Uno dei maggiori problemi incontrati è stato nell'interfaccia con la funzione di hashing, che si aspetta una stringa di caratteri unicode. Soluzione:

function convertToCharString(strPassword)
{
    var splitted = strPassword.split("\\");
    var charString = "";
    for (i=1; i<splitted.length; i++)
    {
        var numeric = parseInt(splitted[i], 8);
        var charCode = String.fromCharCode(numeric);
        charString += charCode;
    }
    return charString;
}

Per quanto riguarda la funzione di hashing... beh, ho copincollato il file .js linkato dalla pagina di login dentro il mio script.

Pur trattandosi di un'implementazione molto naif sta funzionando da alcune settimane alcuni anni senza grossi problemi.

AriaDSL Autologin /2

Segue da AriaDSL Autologin /1.

Visto che la funzione che esegue l'hash MD5 è scritta in Javascript e visto che non avevo assolutamente voglia di convertirla decisi di adottare Windows Scripting Host per automatizzare la procedura, con la consapevolezza che in seguito un (eventuale) porting su Linux sarebbe stato difficoltoso, ma anche curioso di imparare a usare questo strumento. L'idea generale è rappresentata dal corpo dello script:

var strURL = "http://login.ariadsl.it/login"
var strPopupTitle = "Connessione ad AriaDSL";

autoConnect();

function autoConnect()
{
    // 1. scarica la pagina di login
    var strLoginPageBody = getPage(strURL);
   
    // 2. estrae la 'password' generata dal sistema e ne fa l'hash MD5
    var strPassword = extractPassword(strLoginPageBody);
   
    var charStringPassword = convertToCharString(strPassword);
    var strMD5 = hexMD5(charStringPassword);
   
    var strUsername = "ariadsl";
   
    // 3. prepara la chiamata alla pagina di login con i parametri
    var strParms = "";
    strParms = buildParametersList(strParms, "username", strUsername);
    strParms = buildParametersList(strParms, "password", strMD5);
    strParms = buildParametersList(strParms, "popup", "true");
    strParms = buildParametersList(strParms, "dst", "");
   
    // 4. invia la richiesta
    var resultPage = postPage(strURL, strParms);
   
    var WshShell = WScript.CreateObject("Wscript.Shell");
   
    // 5. visualizza un messaggio di successo/fallimento
    if (resultPage.indexOf("You are logged in")<0)
    {
        intButton = WshShell.Popup("Problema con la connessione!", 60, strPopupTitle, 21);
        if (intButton==4)
        {
            autoConnect();
        }
        else
        {
            intButton = WshShell.Popup("Connessione non effettuata!", 10, strPopupTitle, 16);
        }
    }
    else
    {
        intButton = WshShell.Popup("Connessione effettuata con successo", 5, strPopupTitle, 64);
    }
}

Le funzioni invocate verranno descritte in un post successivo (continua)