We have an intranet at work (yes really :D) And we generally trust its contents. So it would be preferrable if we could just drop a .net application and run it. All righty then: we have to set the local intranet to fulltrust. Didn't work :shock: To make a long version of trial and error short: unless enterprise level security contains fulltrust on either all_code or on the proper zone (intranet, a trusted zone or both), the machinelevel settings will not be used, and vice versa. I still don't know the details on the .net security, but I just wanted something that would trust our intranet, without having to set them manually.
There seem to be plenty of ways to incorporate group enterprise policies in Active Directory and all, but quickly got lost in the documentation. In the end making a class as below seemed like a much quicker way than reading in in the larger security scheme. Again, I'm sure there are much better ways to go about and I don't encourage usage of this code in such, but if you want something to quickly fully trust your intranet, you can use this
This time, the class was created largely in worktime (heh, don't need this at home), but I'm sure the company won't mind me sharing this bit (no company data is included and this way I know I can find it back ;-) . The latter perhaps the main reason for posting :-D )
using System;
using System.Collections;
using System.Security;
using System.Security.Policy;
using System.Security.Permissions;
using System.Reflection;
using System.Globalization;
/* quick Usage:
*
*
* CompanySecurity.Create("YourCompanyName","StartOfAllowedDomain");
*
*
* eg: CompanySecurity.Create("Subro","\\Subro\");
*
*
* The company name would not strictly be necessary, but this way the settings
* can be easily defined when checking with the 'normal' tools.
* NB: off course when executing the code above, your code will need the proper
* security permissions to execute, so make sure you execute this as a user with
* the needed permissions and from a location from where this is allowed.
*
* For ease of use, you can put this on the intranet and create a batch file
* that temporarily copies the file to the local drive and executes it. Executing
* from the local computer will have the necessary rights. To ensure the proper user
* rights are used, use runas in that batchfile
* (runas /user:\\yourdomain\adminstratoraccount)
*
*/
/// <summary>
/// can create fully trusted company intranet policy
///
public class CompanySecurity{
public
static void Create(
string Company,
string AllowedDomainName)
{
new CompanySecurity(Company,AllowedDomainName).CreateEntries();
}
public static void Create(string Company)
{
new CompanySecurity(Company).CreateEntries();
}
public readonly string Company;
public readonly string CompanyPermission;
public readonly string CompanyCodeGroup;
FrameworkSecurity.
Levels[] levelstoset =
new FrameworkSecurity.
Levels[]
{ FrameworkSecurity.Levels.Machine, FrameworkSecurity.Levels.Enterprise };
public CompanySecurity(
string Company)
:this(Company,null)
{
}
public CompanySecurity(
string Company,
string DomainName)
{
this.Company = Company;
CompanyPermission = Company + "_permissions";
CompanyCodeGroup = Company + "_zone";
this.DomainName = DomainName;
}
public
void DeleteCompanyEntries()
{
foreach (
FrameworkSecurity.
Levels level
in levelstoset)
{
PolicyLevel pl =
FrameworkSecurity.GetLevel(level);
if (DeleteCompanyEntries(pl) == 0)
Console.WriteLine("No entries existed for " + Company + " in " + pl.Label + " level");
} }
public
virtual NamedPermissionSet CreatePermissionset()
{
//create fulltrust
PermissionSet set = new PermissionSet(PermissionState.Unrestricted);
//use
// set = new PermissionSet(null);
//to start an empty permissionset
NamedPermissionSet permissions = new NamedPermissionSet(CompanyPermission, set);
permissions.Description = "Allow " + Company + " local intranet";
return permissions;
}
private
string domainName;
string domainCodeGroupName;
public string DomainName
{
get {
return domainName; }
set{
if (
value !=
null)
{
value =
value.Trim();
if (
value.Length == 0)
value = null;
else if (!
value.EndsWith(
@"\"))
value += @"\";
}
domainName = value;
if (domainName !=
null)
{
domainCodeGroupName = Company + "_allow_" + domainName;
}
}
}
public
bool DomainNameIsSet
{
get { return domainName != null ; }
}
public
int DeleteCompanyEntries(
PolicyLevel pl)
{
//remove ALL instances of the company groups
int cnt = 0;
for (; ; )
{
bool found =
false;
foreach (
CodeGroup cg
in pl.RootCodeGroup.Children)
{
if (cg.Name.ToLower() == CompanyCodeGroup.ToLower())
{
pl.RootCodeGroup.RemoveChild(cg);
Console.WriteLine("\tCode group " + cg.Name + " removed");
found = true;
cnt++;
break;
}
}
if (!found) break; }
//adjust existing intranet settings
CodeGroup grI =
FrameworkSecurity.GetCodeGroup(pl,
FrameworkSecurity.
DefaultGroups.LocalIntranet_Zone.ToString());
if (grI !=
null && grI.PermissionSetName == CompanyPermission)
{
pl.RootCodeGroup.RemoveChild(grI);
grI.PolicyStatement =new PolicyStatement( pl.GetNamedPermissionSet("LocalIntranet"));
pl.RootCodeGroup.AddChild(grI);
Console.WriteLine("\tDefault intranet settings reverted");
}
//remove trusted zone
if (domainName !=
null)
{
//add as trusted zone
CodeGroup grTrusted =
FrameworkSecurity.GetCodeGroup(pl,
FrameworkSecurity.
DefaultGroups.Trusted_Zone.ToString());
if (grTrusted !=
null)
{
if (grTrusted.PermissionSetName == CompanyPermission)
{
grTrusted.PolicyStatement =
new PolicyStatement(
new NamedPermissionSet("Internet"));
Console.WriteLine(
"\tPermissionset on trusted zone reverted to internet settings");
}
for(;;)
{
CodeGroup grD = FrameworkSecurity.GetCodeGroup(grTrusted, domainCodeGroupName);
if (grD == null) break;
grTrusted.RemoveChild(grD);
pl.RootCodeGroup.RemoveChild(grTrusted);
pl.RootCodeGroup.AddChild(grTrusted);
cnt++;
Console.WriteLine("\tTrusted zone removed");
}
}
}
//remove permissions
NamedPermissionSet ns = pl.GetNamedPermissionSet(CompanyPermission);
if (ns !=
null)
{
pl.RemoveNamedPermissionSet(ns);
Console.WriteLine("\tNamed permission set removed on " + pl.Label + " level");
cnt++;
}
SecurityManager.SavePolicyLevel(pl);
return cnt;
}
public
void CreateEntries()
{
Console.WriteLine(
"Setting permissions for " + Company);
foreach (
FrameworkSecurity.
Levels level
in levelstoset)
{
PolicyLevel pl = FrameworkSecurity.GetLevel(level);
CreateEntries(pl);
} }
public
void CreateEntries(
PolicyLevel pl)
{
if (pl.RootCodeGroup.Children.Count == 0 &&
pl.RootCodeGroup.PermissionSetName == "FullTrust")
{
Console.WriteLine(pl.Label + " not changed, all code allready has fulltrust");
return;
}
DeleteCompanyEntries(pl);
//create a full trust permission
NamedPermissionSet permissions = CreatePermissionset();
PolicyStatement polstat = new PolicyStatement(permissions);
//create a new codegroup
UnionCodeGroup gr =
new UnionCodeGroup(
new ZoneMembershipCondition(SecurityZone.Intranet),
polstat);
gr.Description = "Allow applications in the " + Company + " intranet";
gr.Name = CompanyCodeGroup;
Console.WriteLine("\t" + CompanyCodeGroup + " added");
if (domainName !=
null)
{
//add as trusted zone
CodeGroup grTrusted =
FrameworkSecurity.GetCodeGroup(pl,
FrameworkSecurity.
DefaultGroups.Trusted_Zone.ToString());
if (grTrusted !=
null)
{
pl.RootCodeGroup.RemoveChild(grTrusted);
}
else{
grTrusted =
new UnionCodeGroup(
new ZoneMembershipCondition(SecurityZone.Trusted),
new PolicyStatement(new NamedPermissionSet("Internet")));
grTrusted.Name = FrameworkSecurity.DefaultGroups.Trusted_Zone.ToString();}
UrlMembershipCondition ums = new UrlMembershipCondition(domainName + "*");
UnionCodeGroup grD = new UnionCodeGroup(ums, polstat);
grD.Name = domainCodeGroupName;
grD.Description = "Allow all applications in the domain " + domainName;
grD.PolicyStatement = new PolicyStatement(new NamedPermissionSet("FullTrust"));
grTrusted.AddChild(grD);
Console.WriteLine("\t"+ CompanyPermission + " (permissionset) added");
pl.RootCodeGroup.AddChild(grTrusted);
Console.WriteLine("\tTrusted zone added");
}
//NB use addchild and NOT Children.Add
pl.RootCodeGroup.AddChild(gr); // .Children.Add(ZoneGroup);
//add the group
FrameworkSecurity.SetNamedPermissionSet(pl, permissions);
//save the changes
SecurityManager.SavePolicyLevel(pl);
Console.WriteLine("Policy written to " + pl.Label + " level");
}
}
/// <summary>
/// Functions around the security settings. Not all are needed perhaps, but like
/// this I know where to find them ;-)
///
public static class FrameworkSecurity
{
#region enums
public enum Levels{
Enterprise, Machine, User
}
public enum DefaultGroups{
My_Computer_Zone,
LocalIntranet_Zone,
Internet_Zone,
Trusted_Zone,
Restricted_Zone
}
public enum DefaultPermissions{
FullTrust,
SkipVerification,
Execution,
Nothing,
LocalIntranet,
Internet,
Everything
}
#endregion
#region Levels
public
static PolicyLevel GetLevel(
Levels level)
{
IEnumerator policyEnumerator =
SecurityManager.PolicyHierarchy();
// Move through the policy levels to the Machine policy level.
while (policyEnumerator.MoveNext())
{
PolicyLevel currentLevel = (
PolicyLevel)policyEnumerator.Current;
if (currentLevel.Label == level.ToString())
{
return currentLevel;
} }
return null; }
#endregion
#region PermissionSets
public
static NamedPermissionSet GetPermissionSet(
Levels level,
string Name)
{
return GetPermissionSet(level, Name, false);
}
public static NamedPermissionSet GetPermissionSet(Levels level, string Name, bool Create)
{
return GetPermissionSet(GetLevel(level), Name, Create);
}
public static NamedPermissionSet GetPermissionSet(PolicyLevel pl, string Name)
{
return GetPermissionSet(pl, Name, false);
}
public static NamedPermissionSet GetPermissionSet(PolicyLevel pl, string Name, bool Create)
{
foreach (
NamedPermissionSet ps
in pl.NamedPermissionSets)
{
if (ps.Name == Name) return ps;
}
if (Create)
return new NamedPermissionSet(Name);
return null;
}
public static NamedPermissionSet GetPermissionSet(
PolicyLevel pl,
DefaultPermissions p)
{
return GetPermissionSet(pl, p.ToString());
}
public static NamedPermissionSet GetPermissionSet(Levels level, DefaultPermissions p)
{
return GetPermissionSet(level, p.ToString());
}
public
static void SetNamedPermissionSet(
PolicyLevel pl,
NamedPermissionSet ns)
{
if(pl.GetNamedPermissionSet(ns.Name) !=
null)
pl.ChangeNamedPermissionSet(ns.Name,ns);
else
pl.AddNamedPermissionSet(ns);
}
#endregion
#region Code groups
public
static CodeGroup GetCodeGroup(
Levels level)
{
return GetLevel(level).RootCodeGroup;
}
public static CodeGroup GetCodeGroup(Levels level, string Name)
{
return GetCodeGroup(GetLevel(level), Name);
}
public static CodeGroup GetCodeGroup(Levels level, string Name, bool Recursive)
{
return GetCodeGroup(GetLevel(level), Name, Recursive);
}
public static CodeGroup GetCodeGroup(PolicyLevel pl, string Name)
{
return GetCodeGroup(pl.RootCodeGroup, Name);
}
public static CodeGroup GetCodeGroup(PolicyLevel pl, string Name, bool Recursive)
{
return GetCodeGroup(pl.RootCodeGroup, Name, Recursive);
}
public static CodeGroup GetCodeGroup(CodeGroup InGroup, string Name)
{
return GetCodeGroup(InGroup, Name, true);
}
public static CodeGroup GetCodeGroup(CodeGroup InGroup, string Name, bool Recursive)
{
if (Name ==
null)
return InGroup;
CodeGroup res =
null;
foreach (
CodeGroup gr
in InGroup.Children)
{
if (gr.Name == Name)
{
res = gr;
break;
}
if (Recursive)
{
res = GetCodeGroup(gr, Name, Recursive);
if (res != null) break;
}
}
return res; }
#endregion
}
. . .