/mcs/class/System/System.Net/SocketPermission.cs
C# | 354 lines | 217 code | 54 blank | 83 comment | 67 complexity | 2518bd8957c2a38832d706e6d14b0375 MD5 | raw file
- //
- // System.Net.SocketPermission.cs
- //
- // Author:
- // Lawrence Pit (loz@cable.a2000.nl)
- //
-
- //
- // 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.Collections;
- using System.Security;
- using System.Security.Permissions;
-
- namespace System.Net {
-
- [Serializable]
- public sealed class SocketPermission : CodeAccessPermission, IUnrestrictedPermission
- {
- // Fields
- ArrayList m_acceptList = new ArrayList ();
- ArrayList m_connectList = new ArrayList ();
- bool m_noRestriction;
-
- // Constructors
- public SocketPermission (PermissionState state) : base ()
- {
- m_noRestriction = (state == PermissionState.Unrestricted);
- }
-
- public SocketPermission (NetworkAccess access, TransportType transport,
- string hostName, int portNumber) : base ()
- {
- m_noRestriction = false;
- AddPermission (access, transport, hostName, portNumber);
- }
-
- // Fields
- public const int AllPorts = -1;
-
- // Properties
-
- public IEnumerator AcceptList {
- get { return m_acceptList.GetEnumerator (); }
- }
-
- public IEnumerator ConnectList {
- get { return m_connectList.GetEnumerator (); }
- }
-
- // Methods
-
- public void AddPermission (NetworkAccess access, TransportType transport,
- string hostName, int portNumber)
- {
- if (m_noRestriction)
- return;
-
- EndpointPermission permission = new EndpointPermission (hostName, portNumber, transport);
-
- if (access == NetworkAccess.Accept)
- m_acceptList.Add (permission);
- else
- m_connectList.Add (permission);
- }
-
- public override IPermission Copy ()
- {
- SocketPermission permission;
-
- permission = new SocketPermission (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;
-
- SocketPermission perm = target as SocketPermission;
- if (perm == null)
- throw new ArgumentException ("Argument not of type SocketPermission");
-
- if (m_noRestriction)
- return IntersectEmpty (perm) ? null : perm.Copy ();
-
- if (perm.m_noRestriction)
- return IntersectEmpty (this) ? null : this.Copy ();
-
- SocketPermission newperm = new SocketPermission (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 (SocketPermission permission)
- {
- return !permission.m_noRestriction &&
- (permission.m_connectList.Count == 0) &&
- (permission.m_acceptList.Count == 0);
- }
-
- private void Intersect (ArrayList list1, ArrayList list2, ArrayList result)
- {
- foreach (EndpointPermission perm1 in list1) {
- foreach (EndpointPermission perm2 in list2) {
- EndpointPermission perm = perm1.Intersect (perm2);
- if (perm != null) {
- // instead of the below it's also okay to simply do:
- // result.Add (perm);
- // below is only done to avoid double entries
- bool replaced = false;
- for (int i = 0; i < result.Count; i++) {
- EndpointPermission res = (EndpointPermission) result [i];
- EndpointPermission resperm = perm.Intersect (res);
- if (resperm != null) {
- result [i] = resperm;
- replaced = true;
- break;
- }
- }
- if (!replaced)
- result.Add (perm);
- }
- }
- }
- }
-
- public override bool IsSubsetOf (IPermission target)
- {
- if (target == null)
- return (!m_noRestriction && m_connectList.Count == 0 && m_acceptList.Count == 0);
-
- SocketPermission perm = target as SocketPermission;
-
- if (perm == null)
- throw new ArgumentException ("Parameter target must be of type SocketPermission");
-
- 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);
- }
-
- private bool IsSubsetOf (ArrayList list1, ArrayList list2)
- {
- foreach (EndpointPermission perm1 in list1) {
- bool issubset = false;
- foreach (EndpointPermission perm2 in list2)
- if (perm1.IsSubsetOf (perm2)) {
- issubset = true;
- break;
- }
- if (!issubset)
- return false;
- }
- return true;
- }
-
- public bool IsUnrestricted ()
- {
- return m_noRestriction;
- }
-
- /*
-
- SocketPermission s = new SocketPermission (NetworkAccess.Connect, TransportType.Tcp, "www.google.com", 80);
- s.AddPermission (NetworkAccess.Accept, TransportType.All, "localhost", 8080);
- s.AddPermission (NetworkAccess.Accept, TransportType.All, "localhost", SocketPermission.AllPorts);
- // s = new SocketPermission (PermissionState.None);
- SecurityElement sec = s.ToXml ();
- Console.WriteLine (sec.ToString ());
-
- This is sample xml output:
-
- <IPermission class="System.Net.SocketPermission, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- version="1">
- <ConnectAccess>
- <ENDPOINT host="www.google.com"
- transport="Tcp"
- port="80"/>
- </ConnectAccess>
- <AcceptAccess>
- <ENDPOINT host="localhost"
- transport="All"
- port="8080"/>
- <ENDPOINT host="localhost"
- transport="All"
- port="All"/>
- </AcceptAccess>
- </IPermission>
-
-
-
- This is a sample unrestricted socketpermission, no matter how many permissions you add:
-
- <IPermission class="System.Net.SocketPermission, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- version="1"
- Unrestricted="true"/>
-
-
- This is a sample constructed restricted socketpermission with no permissions added:
-
- <IPermission class="System.Net.SocketPermission, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- version="1"/>
- */
- 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);
- while (enumerator.MoveNext ()) {
- EndpointPermission perm = enumerator.Current as EndpointPermission;
- SecurityElement grandchild = new SecurityElement ("ENDPOINT");
- grandchild.AddAttribute ("host", perm.Hostname);
- grandchild.AddAttribute ("transport", perm.Transport.ToString ());
- grandchild.AddAttribute ("port",
- perm.Port == AllPorts
- ? "All"
- : ((Int32) perm.Port).ToString ());
- child.AddChild (grandchild);
- }
- root.AddChild (child);
- }
-
- 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)
- {
- foreach (SecurityElement endpoint in endpoints) {
- if (endpoint.Tag != "ENDPOINT")
- continue;
- string hostname = endpoint.Attribute ("host");
- TransportType transport =
- (TransportType) Enum.Parse (typeof (TransportType),
- endpoint.Attribute ("transport"),
- true);
- string p = endpoint.Attribute ("port");
- int port = 0;
- if (p == "All")
- port = SocketPermission.AllPorts;
- else
- port = Int32.Parse (p);
-
- AddPermission (access, transport, hostname, port);
- }
- }
-
- 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");
-
- SocketPermission perm = target as SocketPermission;
- if (perm == null)
- throw new ArgumentException ("Argument not of type SocketPermission");
-
- if (this.m_noRestriction || perm.m_noRestriction)
- return new SocketPermission (PermissionState.Unrestricted);
-
- SocketPermission copy = (SocketPermission) 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;
- }
- }
- }