GINA... ADDIO !!!

La richiesta di modificare uno dei componenti storici di Windows - MSGINA.DLL  per gli amici GINA - sembra essere una di quelle domande che non tramontano mai...
Storicamente le richieste di modifica di MSGINA si possono suddividere in quattro categorie :

  • Customizzazione della UI presentata all'utente durante il logon interattivo a Windows (spesso del solo logo). Questa è forse l'80% delle richieste che ho visto negli ultimi 10 anni.
    • Via Subclassing (vedi sotto)
    • Manualmente via editor di risorse (come ad esempio quello in VIsual Studio). Orrore :-) !!! Soluzione da non considerare assolutamente per ambienti diversi dal puro laboratorio!!!!
  • Estensione vera e propria dei meccanismi di logon di Windows. Queste richieste erano rivolte principalmente all' estensione del meccanismo di autenticazione locale e supporto per particolari features su smart card e biometria.
  • Filtraggio delle password : In questo caso NON è necessario intervenire su GINA ma si può creare una custom password filter (vedi sotto).
  • Sicronizzazione delle password con ambienti non Microsoft. In questo caso è sufficiente implementare una versione STUB di GINA integrandosi con MSGINA (vedi GINA Hooking). In questi casi il mio consiglio è quello di valutare prima alcune alternative come ad esempio la creazione di un proprio Credentials Manager Network Provider che spesso può risultare più semplice e supportabile di una custom GINA (vedere le referenze).

Ma allora perchè un titolo così melodrammatico? Semplice perchè con Windows Vista e Windows Server 2008 il meccanismo di Logon è stato completamente ri-engegnerizzato  decretando la fine della buona vecchia MSGINA... rendendo molto più semplice gestire tutte e quattro le categorie di richieste!!

Oggi, a mio avviso, non ha più senso imbarcarsi in un nuovo progetto che farà spendere (un sacco) di tempo e denaro nella realizzazione di una soluzione che gli attuali sistemi operativi non supportano più. Infatti Windows Vista e Windows Server 2008 implementano un nuovo modello a plug-ins basato sui credential providers che presenterò in un prossimo post non passando più per il componente GINA.

In questo post, che vuol essere l' epitaffio di MSGINA, mi sono posto l'obiettivo di raccogliere alcune considerazioni fatte in passato sullo sviluppo e il troubleshooting di custom gina specificando i patterns e soprattutto gli antipatterns sperando di essere utile a tutti coloro che, nonostante tutto, hanno deciso di crearsi una soluzione custom per i vecchi sistemi... oppure per quelle persone che amano ricordare i tempi passati :-)

Prima di addentrarci nei meandri di GINA facciamo un brevissimo recap di cosa sia esattamente GINA e come si posiziona rispetto agli altri componenti di sistema. La MSGINA.DLL, in arte Microsoft Graphical Identification and Authentication Dynamic Link Library, è il componente di WinLogon che implementa le policy di autenticazione del processo di interactive logon ovvero quel processo di autenticazione ed autorizzazione che permette di identificare gli utenti e verificare se hanno i diritti di accesso al sistema. Il processo di interactive logon comprende i seguenti componenti:

  • WinLogon
  • MSGINA (o meglio GINA, che di default è MSGINA, quella implementata da Microsoft)
  • LSA (Local Security Authority)
  • NTLM/Kerberos (Authentication packages)

La MSGINA.DLL viene caricata da Winlogon in una delle prime fasi di boot ed opera nel suo contesto di sicurezza. La MSGINA.DLL passa le credenziali a LSA la quale crea una logon session per l'utente corrente (a differenza del System SCM che è preposto alla creazione di logon sessions per i servizi). Una logon session è una collezione di informazioni sul principal che effettuato il logon identificata da un numero univoco a 64Bits.
Successivamente MSGINA.DLL attiva la shell dell'utente (tramite userinit.exe che istanzia la shell secondo quanto definito nella chiave di registry HKLM\Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Shell=<explorer.exe>) e gestisce gli eventi SAS (Secure Attention Sequence) come ad esempio il famoso CTRL+ALT+DEL. Più in generale SAS sono degli eventi che gestiscono le transizioni di stato di winlogon. I SAS sono implementati come messaggi windows che poi vengono rigirati dal SASRouter verso le finestre top-level.

image

Nella figura sottostante si ha una panoramica più completa di come Winlogon, e quindi GINA, si posizionano rispetto al lsass.exe (per dovere di cronaca).

image

Quando pensiamo di effettuare una customizzazione di MSGINA dobbiamo ricordarci che questo componente è preposto a gestire parecchi aspetti:

  • Il messageBox chiamato "Legal Notification"
  • Visualizzazione della form di logon.
  • Visualizzazione del nome dell'utente precedentemente loggato (se non espresso diversamente dalla policy)
  • Gestione del logon automatico (se configurato nel registry)
  • Stato del tasto SHIFT per regolarsi rispetto al parametro del registry AutoAdminLogon
  • Supporto allo shutdown del sistema.
  • Esecuzione di Userinit.exe
  • Change Password e sblocco del computer.

GINA e i suoi problemi

Per capire i problemi di GINA vediamo quali sono quelli più in generale di Winlogon:

  1. Difficile da customizzare.
  2. Il processo di winlogon carica circa 10 Dlls con problemi di performace.
  3. Difficile scrivere nuove GINA.
  4. Estremamente difficile da debuggare.
  5. Tutto gira come local system il che significa che un qualsiasi componente custom con bug (ad esempio un buffer overrun) può trasformarsi in un DoS (Deny of Service).
  6. Estremamente difficile gestire processi custom di shutdown.

Nello specifico la scrittura di una nuova GINA da registrare all'interno del processo di Winlogon deve essere trattata con estrema cautela sia per gli aspetti di security sia per quelli di stabilità. Partiamo dai problemi di siucrezza : tutto il codice in questione gira nel contesto di Local System e come tale ha il pieno accesso a tutte le risorse della macchina, inoltre una faked GINA può benissimo registrare o inviare le password in chiaro inserite dagli utenti. Ovviamente il sistema si tutela dalle faked GINA  tramite i permessi di amministratore: sono necessari per modificare la registrazione di questi componenti... ma come ben sappiamo non proprio tutti lavorano normalmente con le credenziali di utente normale :-). Per quanto riguarda la stabilità è presto detto: se il processo di winlong va in crash ... possiamo quindi dire addio al nostro sistema... o meglio dobbiamo chiamare il nostro sistemista di fiducia per ripristinare la macchina:-)!!

In definitiva possiamo dire che è sconsigliato scriversi una full GINA per il grande sforzo e complessità richieste. Piuttosto conviene implementare una GINA hook o stub che effettui le operazioni custom volute e poi demandare a MSGINA le restanti operazioni.

A questo punto facciamo un distinguo tra GINA Hooking e GINA Chaining perchè la prima tecnica è consentita e supportata mentre la seconda non lo è e al 99% comporta un grave problema di stabilità al sistema.

GINA Hooking

Una delle tecniche più usate per la customizzazione delle funzionalità di GINA è quella di hooking ovvero di creare una propria DLL con le stesse funzioni esportate da MSGINA e registrarla all'interno del processo di WinLogon in modo da ricevere tutte le chiamate direttamente dal sistema. Questa tecnica si chiama anche STUB.

image

Infine MYGINA effettua il subclassing della windows procedure di MSGINA per poter cambiare l'interfaccia grafica presentata all'utente (e non via resource editor!!! ). Questo meccanismo è supportato e si possono trovare documentazione e un esempio all'interno del SDK in \Microsoft SDK\Samples\security\GINA e qui .

GINA Chaining

Quando il meccanismo di GINA Hooking viene "esteso" ad una catena di GINA allora ci troviamo di fronte a meccanismi contorti e perversi di DLL GINA a cascata. Questa tecnica o meglio questo BUG by Design viene chiamato GINA Chaining.

image

Il GINA chaining non è supportato da Microsoft per una serie di motivi ma soprattutto perchè questa tecnica mette a grave rischio la stabilità del sistema (per quanto detto sopra).
I principali problemi sono dovuti al fatto che il subclassing ricorsivo non è ammesso. In seconda istanza non esistono meccanismi di propagazione dei messaggi tra componenti GINA. Questo rende problematico il flusso delle informazioni a cascata (soprattutto per la parte custom). Essendoci una sola reg-key spesso si collegano altre GINA o direttamente la MSGINA all'interno del proprio codice sorgente. Infine quando si vuole rimuovere una GINA all'interno della catena si rischia di rompere il flusso causando un blocco del sistema. Questi problemi sono sufficienti? No? allora mettiamoci anche che è necessario riscrivere una custom gina per ogni versione di Windows... ALE'...

Debugging custom GINA

Fortunatamente il supporto tecnico ha prodotto un bellissimo articolo su questo tema, quindi non faccio altro che referenziarlo :-)

How to Debug a GINA DLL on a single computer.

Password Filters

Una Password Filer è un "plug-in" in grado di verificare le regole di validazione delle password. Come dicevo all'inizio non è necessario customizzare GINA per effettuare una password filter. Una Password Filer non è altro che una DLL che esporta 3 funzioni ben precise :

 BOOLEAN InitializeChangeNotify(void);
 BOOLEAN PasswordFilter(
  __in  PUNICODE_STRING AccountName,
  __in  PUNICODE_STRING FullName,
  __in  PUNICODE_STRING Password,
  __in  BOOLEAN SetOperation
);
 NTSTATUS PasswordChangeNotify(
  __in  PUNICODE_STRING UserName,
  __in  ULONG RelativeId,
  __in  PUNICODE_STRING NewPassword
);

Qui trovate ulteriori info e l' esempio dell' SDK

Referenze

WinLogon and GINA

WinLogon and GINA.

Interaction between WinLogon and GINA.

 "The Essential of Replacing the Microsoft Graphical Identification and Authentication Dynamic Link Library" (Whitepaper)

Documentazione su MSDN.

Esempio di customizzazione di GINA di Keith Bronw.

How to Debug a GINA DLL on a single computer.

WinLogon Stops responding with a Custom GINA.

A Discussion about the availability of the Fast User Switching features. 

Credential Manager

Implementing a Credential Manager.

Credential Manager Security

 

--Mario