Nel post di ieri ho fatto una breve panoramica sulle utility
della command-line di .NET. Preso dal panico dalla mia ignoranza in fatto di
security, e spinto anche dal fatto che ho incontrato diverse domande
sull'utility caspol.exe, ho
deciso di cominciare da quest'ultima. Ho sfogliato e stampato le pagine su MSDN dedicate a questo tool
,
e ho letto un articolo su www.15seconds.com che illustra in breve come funziona il nuovo
modello di security implementato da .NET.
In cosa consiste? Come funziona la nuova security di
.NET?
Dunque, per farla breve, e molto semplice, possiamo subito
dare una regola generale (francamente, ansioso di essere corretto, di avere
comment più autorevoli e magari qualche links): quando viene eseguito un
assembly scritto in managed-code, il runtime di .NET verifica
da dove arriva, qual'è la sua origine. Come fa? Ieri
sera, mentre seguivo il documentario su Rai 1 dedicato ad Einstein, ho
letto alcune pagine del mitico "Programmare Visual Basic .NET" di Francesco
Balena che mi hanno chiaro un po' le
idee. Ogni assembly .NET contiene dei metadati, grazie ai quali (presumibilmente
tramite Reflection) il runtime è in grado di leggere quelle che vengono definite
evidence: in base a queste evidence, l'assembly viene assegnato
ad un code group, e di conseguenza ad un particolare
permission sets.
Per spiegarmi meglio, è sufficiente aprire dal Control Panel -->
Administrative Tools --> Microsoft .NET Framework 1.1 Configuration. Si apre
un tool (che non è nient'altro che l'equivalente di caspol.exe,
solo che questo ha una UI piacevole). Espandendo il nodo Runtime
Security Policy, si vedono innanzitutto tre livelli: Enterprise,
Machine e User. Il primo si applica a tutta la rete, il secondo a tutte le
applicazioni sul PC, il secondo all'utente singolo. Per adesso ci interessa
considerare il nodo Machine.
Se si espande il nodo Machine, si vedono i suoi code
groups e i suoi permission sets. Per default, tutto il managed code non ha alcun
permesso - per assurdo, un'applicazione .NET non potrebbe
nemmeno girare. Questo si deduce dal fatto che se si vedono i permessi associati
al code group chiamato All_Code, si vede che è
Nothing.
Perchè allora quando facciamo doppio-click su un
nostro applicativo .NET tutto gira regolarmente? Semplice: il runtime di .NET non si ferma a considerare il nodo
All_Code, esplora tutto l'albero per assegnare i permessi in base alla
membership condition di ciascun nodo. Così, ad esempio, avviene che quando
eseguiamo un EXE managed dalla nostra directory K:\Documenti, questo assembly
entra a far parte del code group chiamato My_Computer_Zone,
perchè la membership condition che bisogna soddisfare per appartenere a questo
gruppo è che la Zona di provenienza deve essere "My Computer". Appunto, quello
che succede con i nostri EXE sulle nostre directory sul nostro PC. Quando un
assembly appartiene alla My_Computer_Zone, i permessi sono
quelli definiti dal permission sets FullTrust: pieni poteri, e
difatti i nostri applicativi managed possono fare quello che
vogliono.
L'articolo che ho linkato prima fa eseguire un EXE prima da
C:\Qualcosa, e poi da uno share di rete e fa chiaramente vedere che i permessi
associati in un caso e nell'altro sono diversi: nel primo caso l'EXE gira nel
code group My_Computer_Zone, nel secondo gira nel LocalIntranet_Zone. Questo
modello di sicurezza è molto diverso rispetto a quello della classica security a
cui siamo abituati: non sono tanto le credenziali dell'utente Windows a decidere
cosa un assembly può fare o meno, ma l'origine dell'assembly stesso.
Nota importante: quando una membership condition è verificata, il runtime
.NET continua ad esplorare l'albero sottostante. In questo modo, un assembly può
teoricamente appartenere a più code groups: i permessi che verranno assegnati
all'assembly saranno la somma dei permessi di ogni singolo code
group (e questo mi ha fatto perdere un sacco di tempo ieri sera, mentre
facevo esperimenti).
Ovviamente, oltre ai code group e ai permission sets prefediniti (built-in),
è possibile personalizzare del tutto la security. Per esempio, creando un nuovo
code group, possiamo dire che tutti gli assembly che provengono dall'URL
http://pincopallino posso girare tranquillamente con le permissions
FullTrust.
Ho trovato invece più complesso revocare una
certa permission: ad esempio, se è vero che tutti gli EXE che vengono lanciati
da C:\ girano come FullTrust, come faccio comunque ad evitare
con una certa applicazione vada a scrivere sul registro? Oppure che faccia
operazioni sui files?
L'utility caspol.exe
L'utility caspol.exe permette di
eseguire dalla linea di comando tutta una serie di operazioni analoghe allo
snap-in che abbiamo lanciato prima. Ovviamente, l'utility può servire nel
caso in cui bisogna scrivere script e automatizzare qualche
operazione lunga. Le opzioni previste dal comando sono davvero molte, e ho
propria voglia di impararle :
-addgroup e -remgroup, crea/cancella un code group (indicando la membership condition)
-addfulltrust, aggiunge
un assembly al code group FullTrust
-enterprise, i parametri
specificati dopo agiscono a livello del nodo Enterprise
-machine, i parametri
specificati dopo agiscono a livello del nodo Machine
-user, i parametri specificati dopo
agiscono a livello del nodo User
Eccetera, eccetera...