set svn:eol-style to native and converted several files to unix line ending
[mono.git] / mcs / class / corlib / System.Security.Policy / PolicyLevel.cs
index 433c9d0d2f85271be1ab7d86669231d93d99c110..51eb642bd5ac61ba48d32259f9909826ebad0e16 100644 (file)
@@ -55,6 +55,7 @@ namespace System.Security.Policy {
                private string _location;
                private PolicyLevelType _type;
                private Hashtable fullNames;
+               private SecurityElement xml;
 
                internal PolicyLevel (string label, PolicyLevelType type)
                 {
@@ -64,15 +65,8 @@ namespace System.Security.Policy {
                         named_permission_sets = new ArrayList ();
                 }
 
-               internal PolicyLevel (string label, PolicyLevelType type, string filename)
-                       : this (label, type)
-                {
-                       LoadFromFile (filename);
-               }
-
-               internal void LoadFromFile (string filename) 
+               internal void LoadFromFile (string filename)
                {
-                       bool loaded = false;
                        try {
                                // check for policy file
                                if (!File.Exists (filename)) {
@@ -87,25 +81,29 @@ namespace System.Security.Policy {
                                // load security policy configuration
                                if (File.Exists (filename)) {
                                        using (StreamReader sr = File.OpenText (filename)) {
-                                               LoadFromString (sr.ReadToEnd ());
+                                               xml = FromString (sr.ReadToEnd ());
                                        }
-                                       loaded = true;
-                               }
-                               else {
-                                       CreateFromHardcodedDefault (_type);
-                                       loaded = true;
+                                       try {
+                                               SecurityManager.ResolvingPolicyLevel = this;
+                                               FromXml (xml);
+                                       }
+                                       finally {
+                                               SecurityManager.ResolvingPolicyLevel = this;
+                                       }
+                               } else {
+                                       CreateDefaultFullTrustAssemblies ();
+                                       CreateDefaultNamedPermissionSets ();
+                                       CreateDefaultLevel (_type);
                                        Save ();
                                }
                        }
                        catch {
-                               // this can fail in many ways include
+                               // this can fail in many ways including...
                                // * can't lookup policy (path discovery);
                                // * can't copy default file to policy
                                // * can't read policy file;
-                               // * can't save hardcoded policy to filename
                                // * can't decode policy file
-                               if (!loaded)
-                                       CreateFromHardcodedDefault (_type);
+                               // * can't save hardcoded policy to filename
                        }
                        finally {
                                _location = filename;
@@ -113,6 +111,11 @@ namespace System.Security.Policy {
                }
 
                internal void LoadFromString (string xml) 
+               {
+                       FromXml (FromString (xml));
+               }
+
+               private SecurityElement FromString (string xml) 
                {
                        SecurityParser parser = new SecurityParser ();
                        parser.LoadXml (xml);
@@ -130,13 +133,15 @@ namespace System.Security.Policy {
                        if (policy.Tag != "policy")
                                throw new ArgumentException (Locale.GetText ("missing <policy> tag"));
                        SecurityElement policyLevel = (SecurityElement) policy.Children [0];
-                       FromXml (policyLevel);
+                       return policyLevel;
                }
 
                // properties
 
-               public IList FullTrustAssemblies
-               {
+#if NET_2_0
+               [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
+#endif
+               public IList FullTrustAssemblies {
                        get { return full_trust_assemblies; }
                }
 
@@ -170,6 +175,9 @@ namespace System.Security.Policy {
 
                // methods
 
+#if NET_2_0
+               [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
+#endif
                 public void AddFullTrustAssembly (StrongName sn)
                 {
                        if (sn == null)
@@ -181,6 +189,9 @@ namespace System.Security.Policy {
                         AddFullTrustAssembly (snMC);
                 }
 
+#if NET_2_0
+               [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
+#endif
                 public void AddFullTrustAssembly (StrongNameMembershipCondition snMC)
                 {
                         if (snMC == null)
@@ -214,7 +225,7 @@ namespace System.Security.Policy {
                                throw new ArgumentNullException ("name");
                        if (pSet == null)
                                throw new ArgumentNullException ("pSet");
-                       if (IsReserved (name))
+                       if (DefaultPolicies.ReservedNames.IsReserved (name))
                                throw new ArgumentException (Locale.GetText ("Reserved name"));
 
                        foreach (NamedPermissionSet n in named_permission_sets) {
@@ -229,8 +240,7 @@ namespace System.Security.Policy {
 
                 public static PolicyLevel CreateAppDomainLevel ()
                 {
-                       NamedPermissionSet fullTrust = new NamedPermissionSet ("FullTrust", PermissionState.Unrestricted);
-                       UnionCodeGroup cg = new UnionCodeGroup (new AllMembershipCondition (), new PolicyStatement (fullTrust));
+                       UnionCodeGroup cg = new UnionCodeGroup (new AllMembershipCondition (), new PolicyStatement (DefaultPolicies.FullTrust));
                        cg.Name = "All_Code";
                        PolicyLevel pl = new PolicyLevel ("AppDomain", PolicyLevelType.AppDomain);
                        pl.RootCodeGroup = cg;
@@ -238,10 +248,11 @@ namespace System.Security.Policy {
                         return pl;
                 }
 
-                public void FromXml (SecurityElement e)
-                {
-                        if (e == null)
-                                throw new ArgumentNullException ("e");
+
+               public void FromXml (SecurityElement e)
+               {
+                       if (e == null)
+                               throw new ArgumentNullException ("e");
 // MS doesn't throw an exception for this case
 //                     if (e.Tag != "PolicyLevel")
 //                             throw new ArgumentException (Locale.GetText ("Invalid XML"));
@@ -254,24 +265,6 @@ namespace System.Security.Policy {
                                }
                        }
 
-                       SecurityElement nps = e.SearchForChildByTag ("NamedPermissionSets");
-                       if ((nps != null) && (nps.Children != null) && (nps.Children.Count > 0)) {
-                               named_permission_sets.Clear ();
-                               foreach (SecurityElement se in nps.Children) {
-                                       NamedPermissionSet n = new NamedPermissionSet ();
-                                       n.Resolver = this;
-                                       n.FromXml (se);
-                                       named_permission_sets.Add (n);
-                               }
-                       }
-
-                       SecurityElement cg = e.SearchForChildByTag ("CodeGroup");
-                       if ((cg != null) && (cg.Children != null) && (cg.Children.Count > 0)) {
-                               root_code_group = CodeGroup.CreateFromXml (cg, this);
-                       }
-                       else
-                               throw new ArgumentException (Locale.GetText ("Missing Root CodeGroup"));
-
                        SecurityElement fta = e.SearchForChildByTag ("FullTrustAssemblies");
                        if ((fta != null) && (fta.Children != null) && (fta.Children.Count > 0)) {
                                full_trust_assemblies.Clear ();
@@ -285,6 +278,24 @@ namespace System.Security.Policy {
                                        full_trust_assemblies.Add (new StrongNameMembershipCondition (se));
                                }
                        }
+
+                       SecurityElement cg = e.SearchForChildByTag ("CodeGroup");
+                       if ((cg != null) && (cg.Children != null) && (cg.Children.Count > 0)) {
+                               root_code_group = CodeGroup.CreateFromXml (cg, this);
+                       } else {
+                               throw new ArgumentException (Locale.GetText ("Missing Root CodeGroup"));
+                       }
+
+                       SecurityElement nps = e.SearchForChildByTag ("NamedPermissionSets");
+                       if ((nps != null) && (nps.Children != null) && (nps.Children.Count > 0)) {
+                               named_permission_sets.Clear ();
+                               foreach (SecurityElement se in nps.Children) {
+                                       NamedPermissionSet n = new NamedPermissionSet ();
+                                       n.Resolver = this;
+                                       n.FromXml (se);
+                                       named_permission_sets.Add (n);
+                               }
+                       }
                }
 
                 public NamedPermissionSet GetNamedPermissionSet (string name)
@@ -299,12 +310,31 @@ namespace System.Security.Policy {
                         return null;
                 }
 
-                [MonoTODO]
                 public void Recover ()
                 {
-                        throw new NotImplementedException ();
+                       if (_location == null) {
+                               string msg = Locale.GetText ("Only file based policies may be recovered.");
+                               throw new PolicyException (msg);
+                       }
+
+                       string backup = _location + ".backup";
+                       if (!File.Exists (backup)) {
+                               string msg = Locale.GetText ("No policy backup exists.");
+                               throw new PolicyException (msg);
+                       }
+
+                       try {
+                               File.Copy (backup, _location, true);
+                       }
+                       catch (Exception e) {
+                               string msg = Locale.GetText ("Couldn't replace the policy file with it's backup.");
+                               throw new PolicyException (msg, e);
+                       }
                 }
 
+#if NET_2_0
+               [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
+#endif
                 public void RemoveFullTrustAssembly (StrongName sn)
                 {
                        if (sn == null)
@@ -314,6 +344,9 @@ namespace System.Security.Policy {
                         RemoveFullTrustAssembly (s);
                 }
 
+#if NET_2_0
+               [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
+#endif
                 public void RemoveFullTrustAssembly (StrongNameMembershipCondition snMC)
                 {
                         if (snMC == null)
@@ -335,11 +368,12 @@ namespace System.Security.Policy {
                        return RemoveNamedPermissionSet (permSet.Name);
                 }
 
-               [MonoTODO ("Check for reserved names")]
                public NamedPermissionSet RemoveNamedPermissionSet (string name)
                {
                        if (name == null)
                                throw new ArgumentNullException ("name");
+                       if (DefaultPolicies.ReservedNames.IsReserved (name))
+                               throw new ArgumentException (Locale.GetText ("Reserved name"));
 
                        foreach (NamedPermissionSet nps in named_permission_sets) {
                                if (name == nps.Name) {
@@ -355,10 +389,11 @@ namespace System.Security.Policy {
                 {
                        if (fullNames != null)
                                fullNames.Clear ();
-                        full_trust_assemblies.Clear ();
-                        named_permission_sets.Clear ();
 
                        if (_type != PolicyLevelType.AppDomain) {
+                               full_trust_assemblies.Clear ();
+                               named_permission_sets.Clear ();
+
                                // because the policy doesn't exist LoadFromFile will try to
                                // 1. use the .default file if existing (like Fx 2.0 does); or
                                // 2. use the hard-coded default values
@@ -370,15 +405,9 @@ namespace System.Security.Policy {
                                        catch {}
                                }
                                LoadFromFile (_location);
-                       }
-                       else {
-                               named_permission_sets.Add (new NamedPermissionSet ("LocalIntranet"));
-                               named_permission_sets.Add (new NamedPermissionSet ("Internet"));
-                               named_permission_sets.Add (new NamedPermissionSet ("SkipVerification"));
-                               named_permission_sets.Add (new NamedPermissionSet ("Execution"));
-                               named_permission_sets.Add (new NamedPermissionSet ("Nothing"));
-                               named_permission_sets.Add (new NamedPermissionSet ("Everything"));
-                               named_permission_sets.Add (new NamedPermissionSet ("FullTrust"));
+                       } else {
+                               CreateDefaultFullTrustAssemblies ();
+                               CreateDefaultNamedPermissionSets ();
                        }
                 }
 
@@ -397,9 +426,7 @@ namespace System.Security.Policy {
                                throw new ArgumentNullException ("evidence");
 
                        CodeGroup cg = root_code_group.ResolveMatchingCodeGroups (evidence);
-                       // TODO
                        return ((cg != null) ? cg : null);
-
                 }
 
                 public SecurityElement ToXml ()
@@ -451,23 +478,6 @@ namespace System.Security.Policy {
 
                // internal stuff
 
-               internal bool IsReserved (string name) 
-               {
-                       switch (name) {
-                               case "FullTrust":
-                               case "LocalIntranet":
-                               case "Internet":
-                               case "SkipVerification":
-                               case "Execution":
-                               case "Nothing":
-                               case "Everything":
-                                       // FIXME: Are there others ?
-                                       return true;
-                               default:
-                                       return false;
-                       }
-               }
-
                // NOTE: Callers are expected to check for ControlPolicy
                internal void Save ()
                {
@@ -477,25 +487,61 @@ namespace System.Security.Policy {
                        }
 
                        if (_location != null) {
-                               using (StreamWriter sw = new StreamWriter (_location)) {
-                                       sw.Write (ToXml ().ToString ());
-                                       sw.Close ();
+                               try {
+                                       if (File.Exists (_location)) {
+                                               File.Copy (_location, _location + ".backup", true);
+                                       }
+                               }
+                               catch (Exception) {
+                               }
+                               finally {
+                                       using (StreamWriter sw = new StreamWriter (_location)) {
+                                               sw.Write (ToXml ().ToString ());
+                                               sw.Close ();
+                                       }
                                }
                        }
                }
 
-               // TODO : hardcode defaults in case 
+               // Hardcode defaults in case 
                // (a) the specified policy file doesn't exists; and
                // (b) no corresponding default policy file exists
-               internal void CreateFromHardcodedDefault (PolicyLevelType type) 
+               internal void CreateDefaultLevel (PolicyLevelType type) 
                {
-                       PolicyStatement psu = new PolicyStatement (new PermissionSet (PermissionState.Unrestricted));
+                       PolicyStatement psu = new PolicyStatement (DefaultPolicies.FullTrust);
 
                        switch (type) {
                        case PolicyLevelType.Machine:
                                // by default all stuff is in the machine policy...
-                               root_code_group = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.MyComputer), psu);
+                               PolicyStatement psn = new PolicyStatement (DefaultPolicies.Nothing);
+                               root_code_group = new UnionCodeGroup (new AllMembershipCondition (), psn);
                                root_code_group.Name = "All_Code";
+
+                               UnionCodeGroup myComputerZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.MyComputer), psu);
+                               myComputerZone.Name = "My_Computer_Zone";
+                               // TODO: strongname code group for ECMA and MS keys
+                               root_code_group.AddChild (myComputerZone);
+
+                               UnionCodeGroup localIntranetZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.Intranet), 
+                                       new PolicyStatement (DefaultPolicies.LocalIntranet));
+                               localIntranetZone.Name = "LocalIntranet_Zone";
+                               // TODO: same site / same directory
+                               root_code_group.AddChild (localIntranetZone);
+
+                               PolicyStatement psi = new PolicyStatement (DefaultPolicies.Internet);
+                               UnionCodeGroup internetZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.Internet), psi);
+                               internetZone.Name = "Internet_Zone";
+                               // TODO: same site
+                               root_code_group.AddChild (internetZone);
+
+                               UnionCodeGroup restrictedZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.Untrusted), psn);
+                               restrictedZone.Name = "Restricted_Zone";
+                               root_code_group.AddChild (restrictedZone);
+
+                               UnionCodeGroup trustedZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.Trusted), psi);
+                               trustedZone.Name = "Trusted_Zone";
+                               // TODO: same site
+                               root_code_group.AddChild (trustedZone);
                                break;
                        case PolicyLevelType.User:
                        case PolicyLevelType.Enterprise:
@@ -507,6 +553,37 @@ namespace System.Security.Policy {
                        }
                }
 
+               internal void CreateDefaultFullTrustAssemblies () 
+               {
+                       // (default) assemblies that are fully trusted during policy resolution
+                       full_trust_assemblies.Clear ();
+                       full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("mscorlib", DefaultPolicies.Key.Ecma));
+                       full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System", DefaultPolicies.Key.Ecma));
+                       full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.Data", DefaultPolicies.Key.Ecma));
+                       full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.DirectoryServices", DefaultPolicies.Key.MsFinal));
+                       full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.Drawing", DefaultPolicies.Key.MsFinal));
+                       full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.Messaging", DefaultPolicies.Key.MsFinal));
+                       full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.ServiceProcess", DefaultPolicies.Key.MsFinal));
+               }
+
+               internal void CreateDefaultNamedPermissionSets () 
+               {
+                       named_permission_sets.Clear ();
+                       try {
+                               SecurityManager.ResolvingPolicyLevel = this;
+                               named_permission_sets.Add (DefaultPolicies.LocalIntranet);
+                               named_permission_sets.Add (DefaultPolicies.Internet);
+                               named_permission_sets.Add (DefaultPolicies.SkipVerification);
+                               named_permission_sets.Add (DefaultPolicies.Execution);
+                               named_permission_sets.Add (DefaultPolicies.Nothing);
+                               named_permission_sets.Add (DefaultPolicies.Everything);
+                               named_permission_sets.Add (DefaultPolicies.FullTrust);
+                       }
+                       finally {
+                               SecurityManager.ResolvingPolicyLevel = null;
+                       }
+               }
+
                internal string ResolveClassName (string className)
                {
                        if (fullNames != null) {
@@ -516,5 +593,18 @@ namespace System.Security.Policy {
                        }
                        return className;
                }
+
+               internal bool IsFullTrustAssembly (Assembly a)
+               {
+                       AssemblyName an = a.UnprotectedGetName ();
+                       StrongNamePublicKeyBlob snpkb = new StrongNamePublicKeyBlob (an.GetPublicKey ());
+                       StrongNameMembershipCondition snMC = new StrongNameMembershipCondition (snpkb, an.Name, an.Version);
+                       foreach (StrongNameMembershipCondition sn in full_trust_assemblies) {
+                               if (sn.Equals (snMC)) {
+                                       return true;
+                               }
+                       }
+                       return false;
+               }
         }
 }