Quando la password non funziona

Se avete installato il server di una delle ultime versioni di MySQL per farci qualche prova, avrete notato che non potete accedervi facilmente da applicazioni che invece funzionavano bene con le versioni 3.23.x e 4.0.x.

Può esservi capitato di installare il server, seguire le istruzioni e creare uno o più utenti, e vedere che dal classico client mysql (il monitor a linea di comando) tutto sembra andar bene. Ma quando volete accedervi da una procedura in PHP, Perl, Delphi, o anche dal comodo MySQL Control Center, il server risponde con un messaggio criptico, negando l’accesso per una qualche incompatibilità protocollare.

Il motivo è che, a partire dalla versione 4.1, MySQL utilizza un diverso protocollo di autenticazione. In pratica, viene utilizzata una password di 160 bit invece del vecchio formato a 64 bit. Quindi, se avete creato un utente con il client a linea di comando, la password viene memorizzata nel nuovo formato. Il problema è che le vecchie applicazioni utilizzano ancora le librerie che trattano password a 64 bit. Quindi, al momento del collegamento, il server chiede al client qualcosa a 160 bit che il client non è in grado di capire.

Come risolvere questo problema? Se le vostre applicazioni sono scritte in C, allora basta ricompilarle utilizzando le librerie fornite con la versione installata di fresco. Ma se usate un’applicazione che si basa su driver diversi, allora dovete ricorrere a un sotterfugio alternativo.

Il sistema di riconoscimento degli utenti mantiene la compatibilità con il formato precedente, per cui se una password è registrata con il vecchio formato a 64 bit, il server userà il protocollo che è ancora usato dalle vostre applicazioni.

Il problema sorge dal fatto che nel server 4.1 e 5.0 la funzione password usa il formato a 160 bit, che non e’ riconosciuta dai client delle vecchie versioni.

Il problema è presto risolto. Collegatevi al server con il client mysql appena installato, e cambiate la password in questo modo:


mysql> SET PASSWORD=OLD_PASSWORD("LaTuaPassword");

Ciò fatto, il vecchio client riconoscerà la password e funzionerà come prima.

Ma questo è solo un palliativo. La cosa migliore da fare, una volta che vi siate sincerati che tutto il resto funziona, è aggiornare la libreria del client, così da poter utilizzare le password a 160 bit, che sono molto più sicure.

Nascondere i parametri di connessione con Perl DBI

In un’applicazione Perl, usando il noto modulo DBI, la connessione a un database avviene tramite un’istruzione come questa:


my $dbh = DBI->connect("DBI:mysql:test",
"utente", "password") or die "messaggio di errore";

Il primo parametro è obbligatorio, ed è composto da “dbi”, l’identificativo del modulo, seguito dal driver del database, nel nostro caso “mysql” e il nome del database, in questo esempio “test”. Per un database che si rispetti, occorre anche specificare il nome dell’utente e la password.

Niente da dire se questo script sta al sicuro nella vostra directory, protetta da occhi indiscreti.

Ma cosa succede se dovete distribuirlo a qualcuno per dimostrare qualcosa? Bisogna ricordarsi di cancellare nome utente e password, per evitare il fastidio di doverli poi cambiare nel database se sbadatamente abbiamo distribuito utente e password con l’esempio.

Oppure, se abbiamo un’applicazione CGI, nonostante le protezioni di sistema, il nostro script potrebbe essere sempre alla mercè degli occhi indiscreti di altri utenti che hanno accesso concorrente alla stessa applicazione.

Fortunatamente, esiste una soluzione che nasconde l’accesso alle variabili di connessione, prendendole da un file di configurazione, che può essere tenuto in una directory accessibile solo all’utente che deve eseguire l’applicazione, ma invisibile agli altri.

Funziona così: nella directory dell’utente interessato si costruisce un file di nome “.my.cnf” che contenga queste righe:


[mysql]
user=nomeutente
password=ilmiosegreto

Il file va protetto con gli opportuni privilegi ( chmod 600 .my.cnf) in modo che non possa essere letto da altri utenti. Quindi, si modifica l’istruzione di connessione così:


my $dbh = DBI->connect("DBI:mysql:test"
. ";mysql_read_default_file=$ENV{HOME}/.my.cnf",
undef, undef) or die "messaggio di errore";

L’opzione mysql_read_default_file indica il file da cui prendere le opzioni di connessione. Notate che al posto di nome utente e password ci sono due valori nulli (undef). Il nome del file, in questo caso, viene preso dalla variabile d’ambiente “$HOME” (nei sistemi Unix), ma si può anche indicare il nome espressamente. Questo accorgimento fa sì che lo script possa essere eseguito da più utenti, ciascuno con il suo nome utente e password, senza modificare nemmeno una riga.