Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

[MCAD.32] Strong Names, sn.exe e miglioramento della sicurezza

Dopo aver visto caspol.exe nel post [MCAD.31] di ieri, ho trovato utile passare direttamente a vedere gli strong names e la relativa l'utility sn.exe. Questa volta ho utilizzato come spunto questo articolo su codeproject.com , che spiega a cosa servono gli strong names, come si fa a firmare (sign) un assemby con uno strong name e quali scopi pratici ha.

A cosa serve uno strong name? Versioning e Authentication
Lo risposta è già nel titolo di questo paragrafo.
Uno strong name è un meccanismo tramite il quale vengono firmati gli assembly. Ad un assembly che viene firmato con uno strong name viene garantito un nome univoco, tramite l'aggiunta di informazioni/metadati come la versione (appunto), la localizzazione e così via. Un assembly firmato può finire quindi nella GAC (Global Assembly Cache); di conseguenza, tutti gli assembly nella GAC deve essere stati firmati con uno strong name. Per esempio, basta andare nella directory C:\WINNT\Assembly del proprio sistema per vedere tutti gli assembly della propria GAC: tutti questi assembly sono firmati con uno strong name. Difatti, ogni assembly possiede un Global Assembly Name, una Version, una Culture ed una Public Key Token. Passiamo altro.

A me però piace parlare degli strong name nel campo dell'authentication, soprattutto perchè si lega con quello che abbiamo detto ieri, cioè Code Access Security e quant'altro.
In pratica, per esempio, possiamo assegnare agli assembly firmati con un certo strong name le permissions per girare come FullTrust. Come? Creando un Code Group la cui membership condition è propria quella di avere uno strong name uguale a "xyz", e assegnando quindi a tale Code Group le permissions FullTrust. Possiamo fare questa operazione usando il .NET Framework 1.1 Configuration oppure usando l'utility caspol.exe.

Ma andiamo con calma: prima vediamo di costruire una piccola applicazione che legga nel registry di Windows e vediamo che problematiche di security ci sono.

Problemi di security: My_Computer_Zone e LocalIntranet_Zone
Ho creato un'applicazione Windows Forms, ReadRegistry. Una sola form ed una sola TextBox. Nel costruttore ho inserito il seguente codice:

//
// TODO: Add any constructor code after InitializeComponent call
//
Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.CurrentUser;
this.txtReading.Text = rk.OpenSubKey(@"Software").SubKeyCount.ToString();

Compiliamo, eseguiamo. Tutto ok, nella TextBox appare "33". Proviamo adesso a copiare l'EXE appena generato in uno share di rete qualsiasi: va bene anche il nostro stesso PC, l'importante è che l'EXE venga lanciato da \\nome_pc\nome_dir\nome_exe. Questa volta abbiamo una SecurityException.

Perchè? Nel primo caso, l'EXE veniva eseguito da My_Computer_Zone, che gira come FullTrust. Nel secondo caso gira da LocalIntranet_Zone, che non ha diritti di lettura dal registry. Risultato: exception. Come risolviamo la questione? La prima cosa da fare è firmato l'EXE con uno strong name, successivamente dare i permessi corretti per farlo girare senza problemi.

Firmare un assembly con lo strong name
Apriamo la command-line di VS, e finalmente usiamo sn.exe. Diamo il comando:

sn -k C:\Key.snk

Questo comando scrive il file C:\Key.snk contenente una coppia di chiavi (pubblica & privata) che utilizzeremo fra qualche istante per firmare il nostro assembly.

Torniamo a Visual Studio (se l'avete chiuso, male: riapritelo subito!!! ). Guardiamo la window Solution Explorer, apriamo il file AssemblyInfo.cs. Questo file contiene diversi attribute che il compilatore utilizza per decorare il nostro assembly finale. Cerchiamo l'attribute AssemblyKeyFile e modifichiamolo in:

[assembly: AssemblyKeyFile(@"C:\\Key.snk")]

Ricompiliamo l'applicazione. Questa volta, l'EXE è stato firmato con lo strong name contenuto in C:\Key.snk. Possiamo semplicemente verificarlo con il comando:

sn -v ReadRegistry.exe

che ci risponde "Assembly 'ReadRegistry.exe' is valid". Bene, cosa facciamo ora? Se eseguiamo il nuovo EXE dal nostro disco locale non cambia nulla. Se lo eseguiamo dallo share di rete, ancora SecurityException!  Cosa c'è che non va? Beh, l'exception è normale: comunque sia, il nostro EXE gira dalla zone LocalIntranet_Zone, per cui i permessi sono limitati.

Quello che dobbiamo fare è, come dicevo prima, creare un nuovo code group a cui possa appartenere il nostro assembly, e dare a questo code group i permessi FullTrust. Come facciamo?

Un nuovo code group con pieni poteri!
Creiamo un nuovo code group con le seguenti caratteristiche:

  1. Il nome sarà ReadRegistry
  2. La membership condition necessaria sarà quella di avere lo stesso strong name del nostro EXE appena compilato
  3. I permessi saranno FullTrust
  4. Incastreremo il nuovo code group all'interno del nodo LocalIntranet_Zone

La sintassi di caspol.exe è piuttosto complessa, ho fatto diversi tentativi prima di trovare quella giusta. La logica c'era, i parametri erano quelli giusti, ma l'ordine deve essere quello giusto, altrimenti caspol.exe risponde picche. Il comando giusto è:

caspol
-addgroup 1.2.
-strong
-file "D:\Documenti\Visual Studio Projects\ReadRegistry\bin\Debug\ReadRegistry.exe"
-noname -noversion
FullTrust
-name "ReadRegistry"

Ovviamente, va lanciato tutto su una riga sola, trattandosi di un buon vecchio comando DOS. I parametri che ho passato sono i seguenti:

-addgroup 1.2.
crea il nuovo code group dentro il 2° nodo del 1° nodo (in pratica, dentro LocalIntranet_Zone, a sua volta dentro All_Code)

-strong -file <nome_file>
crea la membership condition del nuovo code group. In questo caso, la condition deriva dal fatto di avere lo stesso strong name incluso nel file passato come parametro

-noname -noversion
la membership condition considera solo lo strong name, ignorando il nome esatto dell'assembly e la sua version

FullTrust
permission sets associato a questo code group

-name "<nome_code_group>"
dà un nome al code group appena creato

Risultato? Nessun SecurityException
Se caspol.exe ha fatto il suo dovere fino in fondo, aprendo il tool .NET Framework 1.1 Configuration, vediamo il nuovo code group indentato in LocalIntranet_Zone. Tutti quegli assembly che verranno lanciati dalla Intranet o da uno share di rete e che conterranno quello strong name, apparterranno a questo code group, e pertanto gireranno come FullTrust

Eseguiamo il nostro EXE dal solito share di rete (senza ricompilare, ovviamente) e questa volta non c'è alcuna SecurityException. Missione compiuta!!!!

powered by IMHO 1.2

Print | posted on Thursday, September 15, 2005 12:00 PM | Filed Under [ MCAD ]

Feedback

Gravatar

# [MCAD.33] Un ultimo sguardo a caspol.exe e alle policy di sicurezza

9/19/2005 11:16 AM | Technology Experience
Gravatar

# [MCAD.34] Global Assembly Cache, gacutil.exe e dintorni

9/20/2005 3:08 PM | Technology Experience
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET