// // System.Net.WebPermission.cs // // Author: // Andreas Nahr (ClassDevelopment@A-SoftTech.com) // (based on SocketPermission.cs) // // (C) 2003 Andreas Nahr // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; namespace System.Net { internal enum WebPermissionInfoType { InfoString, InfoUnexecutedRegex, InfoRegex, } internal class WebPermissionInfo { WebPermissionInfoType _type; object _info; public WebPermissionInfo (WebPermissionInfoType type, string info) { _type = type; _info = (string) info; } public WebPermissionInfo (Regex regex) { _type = WebPermissionInfoType.InfoRegex; _info = (object) regex; } public string Info { get { if (_type == WebPermissionInfoType.InfoRegex) return null; return (string) _info; } } } // (based on SocketPermission.cs - Please look there to implement missing members!) [MonoTODO ("Most private members that include functionallity are not implemented!")] [Serializable] public sealed class WebPermission : CodeAccessPermission, IUnrestrictedPermission { // Fields ArrayList m_acceptList = new ArrayList (); ArrayList m_connectList = new ArrayList (); bool m_noRestriction = false; // Constructors public WebPermission () : base () { } public WebPermission (PermissionState state) : base () { m_noRestriction = (state == PermissionState.Unrestricted); } public WebPermission (NetworkAccess access, string uriString) : base () { AddPermission (access, uriString); } public WebPermission (NetworkAccess access, Regex uriRegex) : base () { AddPermission (access, uriRegex); } // Properties public IEnumerator AcceptList { get { return m_acceptList.GetEnumerator (); } } public IEnumerator ConnectList { get { return m_connectList.GetEnumerator (); } } // Methods public void AddPermission (NetworkAccess access, string uriString) { WebPermissionInfo info = new WebPermissionInfo (WebPermissionInfoType.InfoString, uriString); AddPermission (access, info); } public void AddPermission (NetworkAccess access, Regex uriRegex) { WebPermissionInfo info = new WebPermissionInfo (uriRegex); AddPermission (access, info); } internal void AddPermission (NetworkAccess access, WebPermissionInfo info) { switch (access) { case NetworkAccess.Accept: m_acceptList.Add (info); break; case NetworkAccess.Connect: m_connectList.Add (info); break; default: string msg = Locale.GetText ("Unknown NetworkAccess value {0}."); throw new ArgumentException (String.Format (msg, access), "access"); } } public override IPermission Copy () { WebPermission permission; permission = new WebPermission (m_noRestriction ? PermissionState.Unrestricted : PermissionState.None); // as EndpointPermission's are immutable it's safe to do a shallow copy. permission.m_connectList = (ArrayList) this.m_connectList.Clone (); permission.m_acceptList = (ArrayList) this.m_acceptList.Clone (); return permission; } public override IPermission Intersect (IPermission target) { if (target == null) return null; WebPermission perm = target as WebPermission; if (perm == null) throw new ArgumentException ("Argument not of type WebPermission"); if (m_noRestriction) return IntersectEmpty (perm) ? null : perm.Copy (); if (perm.m_noRestriction) return IntersectEmpty (this) ? null : this.Copy (); WebPermission newperm = new WebPermission (PermissionState.None); Intersect (this.m_connectList, perm.m_connectList, newperm.m_connectList); Intersect (this.m_acceptList, perm.m_acceptList, newperm.m_acceptList); return IntersectEmpty (newperm) ? null : newperm; } private bool IntersectEmpty (WebPermission permission) { return !permission.m_noRestriction && (permission.m_connectList.Count == 0) && (permission.m_acceptList.Count == 0); } [MonoTODO] private void Intersect (ArrayList list1, ArrayList list2, ArrayList result) { throw new NotImplementedException (); } public override bool IsSubsetOf (IPermission target) { if (target == null) return (!m_noRestriction && m_connectList.Count == 0 && m_acceptList.Count == 0); WebPermission perm = target as WebPermission; if (perm == null) throw new ArgumentException ("Parameter target must be of type WebPermission"); if (perm.m_noRestriction) return true; if (this.m_noRestriction) return false; if (this.m_acceptList.Count == 0 && this.m_connectList.Count == 0) return true; if (perm.m_acceptList.Count == 0 && perm.m_connectList.Count == 0) return false; return IsSubsetOf (this.m_connectList, perm.m_connectList) && IsSubsetOf (this.m_acceptList, perm.m_acceptList); } [MonoTODO] private bool IsSubsetOf (ArrayList list1, ArrayList list2) { throw new NotImplementedException (); } public bool IsUnrestricted () { return m_noRestriction; } public override SecurityElement ToXml () { SecurityElement root = new SecurityElement ("IPermission"); root.AddAttribute ("class", this.GetType ().AssemblyQualifiedName); root.AddAttribute ("version", "1"); if (m_noRestriction) { root.AddAttribute ("Unrestricted", "true"); return root; } if (this.m_connectList.Count > 0) ToXml (root, "ConnectAccess", m_connectList.GetEnumerator ()); if (this.m_acceptList.Count > 0) ToXml (root, "AcceptAccess", m_acceptList.GetEnumerator ()); return root; } private void ToXml (SecurityElement root, string childName, IEnumerator enumerator) { SecurityElement child = new SecurityElement (childName, null); root.AddChild (child); while (enumerator.MoveNext ()){ WebPermissionInfo x = enumerator.Current as WebPermissionInfo; if (x == null) continue; SecurityElement uri = new SecurityElement ("URI"); uri.AddAttribute ("uri", x.Info); child.AddChild (uri); } } public override void FromXml (SecurityElement securityElement) { if (securityElement == null) throw new ArgumentNullException ("securityElement"); // LAMESPEC: it says to throw an ArgumentNullException in this case if (securityElement.Tag != "IPermission") throw new ArgumentException ("securityElement"); string unrestricted = securityElement.Attribute ("Unrestricted"); if (unrestricted != null) { this.m_noRestriction = (String.Compare (unrestricted, "true", true) == 0); if (this.m_noRestriction) return; } this.m_noRestriction = false; this.m_connectList = new ArrayList (); this.m_acceptList = new ArrayList (); ArrayList children = securityElement.Children; foreach (SecurityElement child in children) { if (child.Tag == "ConnectAccess") FromXml (child.Children, NetworkAccess.Connect); else if (child.Tag == "AcceptAccess") FromXml (child.Children, NetworkAccess.Accept); } } private void FromXml (ArrayList endpoints, NetworkAccess access) { throw new NotImplementedException (); } public override IPermission Union (IPermission target) { // LAMESPEC: according to spec we should throw an // exception when target is null. We'll follow the // behaviour of MS.Net instead of the spec, also // because it matches the Intersect behaviour. if (target == null) return null; // throw new ArgumentNullException ("target"); WebPermission perm = target as WebPermission; if (perm == null) throw new ArgumentException ("Argument not of type WebPermission"); if (this.m_noRestriction || perm.m_noRestriction) return new WebPermission (PermissionState.Unrestricted); WebPermission copy = (WebPermission) perm.Copy (); copy.m_acceptList.InsertRange (copy.m_acceptList.Count, this.m_acceptList); copy.m_connectList.InsertRange (copy.m_connectList.Count, this.m_connectList); return copy; } } }