Re: Any good examples of modifying the CAS during install?
- From: Dominick Baier [DevelopMentor] <dbaier@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 25 Apr 2006 05:20:18 +0000 (UTC)
hi,
overwrite the install/uninstall methods to add custom actions...the following code should get you started
using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.Security;
using System.Security.Policy;
using System.Security.Permissions;
using System.Net;
using System.Data.SqlClient;
[RunInstaller(true)]
public class MyInstaller : System.Configuration.Install.Installer
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
string permissionSetName = "Acme Permissions";
string permissionSetDesc = "This is the set of permissions needed by ..NET applications for Acme corporation";
string codeGroupName = "Acme Code Group";
string codeGroupDesc = "Grants a few extra permissions to any assembly signed with the Acme strong name";
public MyInstaller()
{
// This call is required by the Designer.
InitializeComponent();
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
// this code will run when the MSI file is installed
public override void Install(IDictionary stateSaver) {
// first need to find the machine policy,
// which is where we'll make our changes
PolicyLevel machinePolicy = _findPolicyLevel("Machine");
if (null == machinePolicy) {
// sanity check - this should never happen
throw new ApplicationException("Failed to find the machine policy in the PolicyHierarchy");
}
// we need to add a named permission set
// that includes whatever permissions we're granting
NamedPermissionSet nps = new NamedPermissionSet(permissionSetName, PermissionState.None);
nps.Description = permissionSetDesc;
// TODO: add the permissions AcmeExpense needs
nps.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, @"c:\acme\expenses"));
nps.AddPermission(new EnvironmentPermission(EnvironmentPermissionAccess.Read, "EXPENSE"));
nps.AddPermission(new SqlClientPermission(PermissionState.Unrestricted));
nps.AddPermission(new DataProtectionPermission(PermissionState.Unrestricted));
// add our named permission set to the machine policy level
// note that nothing is saved yet (we'll save at the end)
try {
machinePolicy.AddNamedPermissionSet(nps);
}
catch {
// duplicate name - update the existing one with the same name
machinePolicy.ChangeNamedPermissionSet(nps.Name, nps);
}
// now we need to create a code group that matches all assemblies
// that we ship with AcmeExpense - one way of doing this is to
// match the strong name we assign to that application (although
// depending on how you manage strong names, this might cover
// a wider set of assemblies)
CodeGroup cg = new UnionCodeGroup(
new StrongNameMembershipCondition(
new StrongNamePublicKeyBlob(acmePublicKey),
null, // match regardless of assembly's simple name
null), // match regardless of assembly's version
new PolicyStatement(nps,
PolicyStatementAttribute.Nothing) // no LevelFinal or Exclusive attribute on this code group
);
cg.Name = codeGroupName;
cg.Description = codeGroupDesc;
// code groups with duplicate names are legal, but messy and confusing,
// so we make sure to first remove any existing code groups with our name
_removeCodeGroupsByName(machinePolicy.RootCodeGroup, cg.Name);
// add our new code group (note we've not saved yet).
machinePolicy.RootCodeGroup.AddChild(cg);
// finally, save all changes atomically.
SecurityManager.SavePolicyLevel(machinePolicy);
}
// this code will run when our MSI is uninstalled
public override void Uninstall(System.Collections.IDictionary savedState) {
// first need to find the machine policy,
// which is where we'll make our changes
PolicyLevel machinePolicy = _findPolicyLevel("Machine");
if (null == machinePolicy) {
// sanity check - this should never happen
throw new ApplicationException("Failed to find the machine policy in the PolicyHierarchy");
}
// remove our code group
_removeCodeGroupsByName(machinePolicy.RootCodeGroup, codeGroupName);
// remove our named permission set
try {
machinePolicy.RemoveNamedPermissionSet(permissionSetName);
}
catch {
// if it's not there, no biggie - just doing our best to clean up.
}
// finally, save all changes atomically.
SecurityManager.SavePolicyLevel(machinePolicy);
}
PolicyLevel _findPolicyLevel(string labelWeWant) {
IEnumerator policyLevelEnumerator = SecurityManager.PolicyHierarchy();
PolicyLevel found = null;
while (policyLevelEnumerator.MoveNext()) {
PolicyLevel lvl = (PolicyLevel)policyLevelEnumerator.Current;
if (labelWeWant == lvl.Label) {
found = lvl;
}
}
return found;
}
void _removeCodeGroupsByName(CodeGroup parent, string childName) {
// the implementation of CodeGroup.Children (viewed with Anakrino)
// gives a deep copy of the children, so technically this is overkill,
// but the documentation doesn't guarantee this, so we enumerate
// then delete in two separate steps as you would with any dynamic list
ArrayList codeGroupsToRemove = new ArrayList();
foreach (CodeGroup existingCodeGroup in parent.Children) {
if (childName == existingCodeGroup.Name) {
codeGroupsToRemove.Add(existingCodeGroup);
}
}
foreach (CodeGroup cg in codeGroupsToRemove) {
parent.RemoveChild(cg);
}
}
// TODO: get the public key from AcmeExpense.exe using the secutil tool
byte[] acmePublicKey = new byte[]{ 0, 36, 0, 0, 4, 128, 0, 0, 148, 0, 0, 0,
6, 2, 0, 0, 0, 36, 0, 0, 82, 83, 65, 49, 0, 4, 0, 0, 1, 0, 1, 0, 85, 73, 181, 56, 224, 255, 198, 167, 151, 206, 111, 135,
63, 32, 172, 222, 77, 52, 224, 240, 213,
218, 202, 79, 18, 100, 175, 171, 17, 242,
83, 200, 243, 42, 105, 75, 231, 4, 81, 164, 11, 105, 39, 193, 38, 32, 161, 246,
131, 55, 86, 216, 252, 116, 204, 12, 60,
91, 125, 46, 230, 95, 108, 13, 161, 34, 69, 98, 191, 236, 147, 208, 59, 80, 172,
98, 1, 213, 167, 105, 180, 135, 22, 231,
69, 11, 55, 252, 224, 212, 219, 86, 112,
32, 92, 118, 40, 250, 51, 173, 23, 33, 77, 179, 133, 49, 197, 137, 174, 236, 57, 143, 37, 244, 251, 98, 178, 255, 175,
135, 107, 5, 168, 106, 175, 184, 116, 206 };
}
---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com
I need to modify the .NET 2.0 CAS (create a code group, etc) in my
installer. I'm using VS.NET 2K5 and I can't seem to find a good
example that does this. I can barely understand the general flow.
This is what I understand:
1) I create something (a library?) that has a class (say
MyInstaller)
that derives from System.Configuration.Install.Installer.
2) I register for installation events. Makes sense.
3) ... ? I'm lost here
...
10) ... ? I create a custom action to run my installer?
Has anyone done this? Are there any good examples?
Thanks
Gary F
.
- References:
- Any good examples of modifying the CAS during install?
- From: Gary F.
- Any good examples of modifying the CAS during install?
- Prev by Date: X509Certificate2 Serialnumber does not have hyphen delimiters
- Next by Date: Re: Any good examples of modifying the CAS during install?
- Previous by thread: Any good examples of modifying the CAS during install?
- Next by thread: Re: Any good examples of modifying the CAS during install?
- Index(es):
Relevant Pages
|