Просмотр исходного кода

Socket permission stuff, not yet used by Socket itself.

svn path=/trunk/mcs/; revision=4101
Lawrence Pit 24 лет назад
Родитель
Сommit
eed54e475f

+ 8 - 0
mcs/class/System/System.Net/ChangeLog

@@ -1,3 +1,11 @@
+2002-04-28  Lawrence Pit <[email protected]>
+
+	* EndpointPermission: implemented
+	* SocketPermission.cs: implemented
+	* SocketPermissionAttribute.cs: implemented
+	* ProtocolViolationException.cs: implemented
+	* Dns.c: passing w32 error code when no host found
+
 2002-04-27  Lawrence Pit <[email protected]>
 
 	* Cookie.cs: implemented

+ 2 - 2
mcs/class/System/System.Net/Dns.cs

@@ -152,7 +152,7 @@ namespace System.Net {
                                                           out h_aliases,
                                                           out h_addrlist);
                         if (ret == false) {
-                                throw new SocketException();
+                                throw new SocketException(11001);
                         }
                         
                         return(hostent_to_IPHostEntry(h_name, h_aliases,
@@ -171,7 +171,7 @@ namespace System.Net {
                                                           out h_aliases,
                                                           out h_addrlist);
                         if (ret == false) {
-                                throw new SocketException();
+                                throw new SocketException(11001);
                         }
 
                         return(hostent_to_IPHostEntry(h_name, h_aliases,

+ 326 - 0
mcs/class/System/System.Net/EndpointPermission.cs

@@ -0,0 +1,326 @@
+//
+// System.Net.EndpointPermission.cs
+//
+// Author:
+//   Lawrence Pit ([email protected])
+//
+
+using System;
+using System.Collections;
+using System.Security;
+using System.Security.Permissions;
+
+namespace System.Net
+{
+	[Serializable]
+	public class EndpointPermission // too bad about the lowercase p, not consistent with IPEndPoint ;)
+	{
+		private static char [] dot_char = new char [] { '.' };
+		
+		// Fields
+		private string hostname;
+		private int port;
+		private TransportType transport;
+
+		private bool resolved;		
+		private bool hasWildcard;
+		private IPAddress [] addresses;
+		
+		// Constructors
+		internal EndpointPermission (string hostname, 
+				   	     int port, 
+				   	     TransportType transport) : base () 
+		{			
+			if (hostname == null)
+				throw new ArgumentNullException ("hostname");
+			this.hostname = hostname;
+			this.port = port;
+			this.transport = transport;
+			this.resolved = false;
+			this.hasWildcard = false;
+			this.addresses = null;
+		}		
+		
+		// Properties
+
+		public string Hostname {
+			get { return hostname; }
+		}
+
+		public int Port {
+			get { return port; }
+		}
+		
+		public TransportType Transport {
+			get { return transport; }
+		}
+		
+		// Methods
+		
+		public override bool Equals (object obj) 
+		{
+			EndpointPermission epp = obj as EndpointPermission;
+			return ((epp != null) &&
+			        (this.port == epp.port) &&
+			        (this.transport == epp.transport) &&
+			        (String.Compare (this.hostname, epp.hostname, true) == 0));
+		}
+		
+		public override int GetHashCode () 
+		{
+			return ToString ().GetHashCode ();
+		}
+		
+		public override string ToString () 
+		{
+			return hostname + "#" + port + "#" + (int) transport;
+		}
+		
+		// Internal & Private Methods
+		
+		internal bool IsSubsetOf (EndpointPermission perm) 
+		{
+			if (perm == null)
+				return false;
+			
+			if (perm.port != SocketPermission.AllPorts &&
+			    this.port != perm.port)
+			    	return false;
+			
+			if (perm.transport != TransportType.All &&
+			    this.transport != perm.transport)
+				return false;
+			
+			this.Resolve ();
+			perm.Resolve ();
+			
+			if (this.hasWildcard) {
+				if (perm.hasWildcard)
+					return IsSubsetOf (this.hostname, perm.hostname);
+				else 
+					return false;
+			} 
+			
+			if (this.addresses == null) 
+				return false;
+			
+			if (perm.hasWildcard) 
+				// a bit dubious... should they all be a subset or is one 
+				// enough in this case?
+				foreach (IPAddress addr in this.addresses)
+					if (IsSubsetOf (addr.ToString (), perm.hostname))
+						return true;
+				
+			if (perm.addresses == null) 
+				return false;
+				
+			// a bit dubious... should they all be a subset or is one 
+			// enough in this case?
+			foreach (IPAddress addr in perm.addresses)
+				if (IsSubsetOf (this.hostname, addr.ToString ())) 
+					return true;	
+					
+			return false;		
+		}		
+		
+		private bool IsSubsetOf (string addr1, string addr2)
+		{
+			string [] h1 = addr1.Split (dot_char);		
+			string [] h2 = addr2.Split (dot_char);
+				
+			for (int i = 0; i < 4; i++) {
+				int part1 = ToNumber (h1 [i]);
+				if (part1 == -1) 
+					return false;				
+
+				int part2 = ToNumber (h2 [i]);
+				if (part2 == -1)
+					return false;				
+				if (part1 != part2 && part2 != 256)
+					return false;
+			}
+			return true;
+		}
+		
+		internal EndpointPermission Intersect (EndpointPermission perm) 
+		{
+			if (perm == null)
+				return null;
+			
+			int _port;
+			if (this.port == perm.port)
+				_port = this.port;
+			else if (this.port == SocketPermission.AllPorts)
+				_port = perm.port;
+			else if (perm.port == SocketPermission.AllPorts)
+				_port = this.port;
+			else
+				return null;
+
+			TransportType _transport;
+			if (this.transport == perm.transport)
+				_transport = this.transport;
+			else if (this.transport == TransportType.All)
+				_transport = perm.transport;
+			else if (perm.transport == TransportType.All)
+				_transport = this.transport;
+			else
+				return null;
+
+			string _hostname = IntersectHostname (perm);						
+			
+			if (_hostname == null)
+				return null;
+
+			if (!this.hasWildcard)
+				return this;
+				
+			if (!perm.hasWildcard)
+				return perm;
+				
+			EndpointPermission newperm = new EndpointPermission (_hostname, _port, _transport);
+			newperm.hasWildcard = true;
+			newperm.resolved = true;
+			return newperm;
+		}
+		
+		private string IntersectHostname (EndpointPermission perm)
+		{
+			if (this.hostname == perm.hostname)
+				return this.hostname;
+				
+			this.Resolve ();
+			perm.Resolve ();
+			
+			string _hostname = null;
+			
+			if (this.hasWildcard) {
+				if (perm.hasWildcard) {
+					_hostname = Intersect (this.hostname, perm.hostname);
+				} else if (perm.addresses != null) {
+					for (int j = 0; j < perm.addresses.Length; j++) {
+						_hostname = Intersect (this.hostname, perm.addresses [j].ToString ());
+						if (_hostname != null) 
+							break;
+					}
+				}
+			} else if (this.addresses != null) {
+				for (int i = 0; i < this.addresses.Length; i++) {
+					string thisaddr = this.addresses [i].ToString ();
+					if (perm.hasWildcard) {
+						_hostname = Intersect (thisaddr, perm.hostname);
+					} else if (perm.addresses != null) {
+						for (int j = 0; j < perm.addresses.Length; j++) {
+							_hostname = Intersect (thisaddr, perm.addresses [j].ToString ());
+							if (_hostname != null) 
+								break;
+						}
+					}
+				}
+			}
+			
+			return _hostname;
+		}
+		
+		// alas, currently we'll only support IPv4 as that's MS.Net behaviour
+		// returns null when both host strings do not intersect
+		private string Intersect (string addr1, string addr2)
+		{
+			string [] h1 = addr1.Split (dot_char);		
+			string [] h2 = addr2.Split (dot_char);
+				
+			string [] s = new string [7];
+			for (int i = 0; i < 4; i++) {
+				int part1 = ToNumber (h1 [i]);
+				if (part1 == -1) 
+					return null;				
+
+				int part2 = ToNumber (h2 [i]);
+				if (part2 == -1)
+					return null;				
+
+				if (part1 == 256) 
+					s [i << 1] = (part2 == 256) ? "*" : String.Empty + part2;
+				else if (part2 == 256)
+					s [i << 1] = (part1 == 256) ? "*" : String.Empty + part1;				
+				else if (part1 == part2)
+					s [i << 1] = String.Empty + part1;
+				else
+					return null;
+			}
+			
+			s [1] = s [3] = s [5] = ".";
+			return String.Concat (s);
+		}
+		
+		// returns 256 if value is a '*' character
+		// returns -1 if value isn't a number between 0 and 255		
+		private int ToNumber (string value)
+		{
+			if (value == "*")
+				return 256;
+				
+			int len = value.Length;
+			if (len < 1 || len > 3)
+				return -1;
+				
+			int val = 0;				
+			for (int i = 0; i < len; i++) {
+				char c = value [i];
+				if ('0' <= c && c <= '9') 
+					val = checked (val * 10 + (c - '0'));
+				else
+					return -1;
+			}
+			
+			return val <= 255 ? val : -1;
+		}
+
+		internal void Resolve ()
+		{
+			if (resolved) 	
+				return;
+				
+			bool isHostname = false;				
+			bool hasWildcard = false;
+			this.addresses = null;
+			
+			string [] s = hostname.Split (dot_char);
+
+			if (s.Length != 4) {
+				isHostname = true;
+			} else {
+				for (int i = 0; i < 4; i++) {
+					int quad = ToNumber (s [i]);
+					if (quad == -1) {
+						isHostname = true;
+						break;
+					}
+					if (quad == 256)
+						hasWildcard = true;
+				}
+			}
+			
+			if (isHostname) {
+				this.hasWildcard = false;
+				try {
+					this.addresses = Dns.GetHostByName (hostname).AddressList;
+				} catch (System.Net.Sockets.SocketException) {					
+				}
+			} else {
+				this.hasWildcard = hasWildcard;
+				if (!hasWildcard) {
+					addresses = new IPAddress [1];
+					addresses [0] = IPAddress.Parse (hostname);
+				}
+			}
+			
+			this.resolved = true;				
+		}
+		
+		internal void UndoResolve ()
+		{
+			resolved = false;
+		}
+	}
+}

+ 38 - 0
mcs/class/System/System.Net/ProtocolViolationException.cs

@@ -0,0 +1,38 @@
+//
+// System.Net.ProtocolViolationException.cs
+//
+// Author:
+//   Lawrence Pit ([email protected])
+//
+
+using System.Globalization;
+using System.Runtime.Serialization;
+
+namespace System.Net 
+{
+	[Serializable]
+	public class ProtocolViolationException : InvalidOperationException, ISerializable
+	{
+
+		// Constructors
+		public ProtocolViolationException () : base ()
+		{
+		}
+		
+		public ProtocolViolationException (string message) : base (message)
+		{
+		}
+
+		protected ProtocolViolationException (SerializationInfo info, StreamingContext context)
+			: base (info, context)
+		{			
+		}
+
+		// Methods
+		void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
+		{
+			base.GetObjectData (info, context);
+		}
+	}
+}
+	

+ 348 - 0
mcs/class/System/System.Net/SocketPermission.cs

@@ -0,0 +1,348 @@
+//
+// System.Net.SocketPermission.cs
+//
+// Author:
+//   Lawrence Pit ([email protected])
+//
+
+using System;
+using System.Collections;
+using System.Security;
+using System.Security.Permissions;
+
+namespace System.Net
+{
+	[Serializable]
+	public 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 ().FullName + ", " + 
+			                            "System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+
+/*			
+GetType ().Module doesn't work yet with Mono.. (2002-04-27)
+We need to do it as below though, because this class can be extended
+
+			root.AddAttribute ("class", this.GetType ().FullName + ", " + 
+			                            this.GetType ().Module.Assembly.FullName);
+*/			                            
+			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 classStr = securityElement.Attribute ("class");
+			if (classStr == null || !classStr.StartsWith (this.GetType ().FullName + ","))
+				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;
+		}
+
+	}
+}

+ 127 - 0
mcs/class/System/System.Net/SocketPermissionAttribute.cs

@@ -0,0 +1,127 @@
+//
+// System.Net.SocketPermissionAttribute.cs
+//
+// Author:
+//   Lawrence Pit ([email protected])
+//
+
+using System;
+using System.Security;
+using System.Security.Permissions;
+
+namespace System.Net
+{
+	[AttributeUsage (AttributeTargets.Assembly 
+	               | AttributeTargets.Class 
+	               | AttributeTargets.Struct 
+	               | AttributeTargets.Constructor 
+	               | AttributeTargets.Method)
+	]	
+	[Serializable]
+	public sealed class SocketPermissionAttribute : CodeAccessSecurityAttribute
+	{
+		// Fields
+		string m_access;
+		string m_host;
+		string m_port;
+		string m_transport;
+		
+		// Constructors
+		public SocketPermissionAttribute (SecurityAction action) : base (action)
+		{
+		}
+
+		// Properties
+
+		public string Access {
+			get { return m_access; }
+			set { 
+				if (m_access != null)
+					throw new ArgumentException ("The parameter 'Access' can be set only once.");
+				if (value == null) 
+					throw new ArgumentException ("The parameter 'Access' cannot be null.");
+				m_access = value;
+			}
+		}
+
+		public string Host {
+			get { return m_host; }
+			set { 
+				if (m_host != null)
+					throw new ArgumentException ("The parameter 'Host' can be set only once.");
+				if (value == null) 
+					throw new ArgumentException ("The parameter 'Host' cannot be null.");					
+				m_host = value;
+			}
+		}
+
+		public string Port {
+			get { return m_port; }
+			set { 
+				if (m_port != null)
+					throw new ArgumentException ("The parameter 'Port' can be set only once.");
+				if (value == null) 
+					throw new ArgumentException ("The parameter 'Port' cannot be null.");					
+				m_port = value;
+			}
+		}
+
+		public string Transport {
+			get { return m_transport; }
+			set { 
+				if (m_transport != null)
+					throw new ArgumentException ("The parameter 'Transport' can be set only once.");
+				if (value == null) 
+					throw new ArgumentException ("The parameter 'Transport' cannot be null.");					
+				m_transport = value;
+			}
+		}
+		
+		// Methods
+		
+		public override IPermission CreatePermission () {
+			if (this.Unrestricted)
+				return new SocketPermission (PermissionState.Unrestricted);
+
+			if (m_access == null) 
+				throw new ArgumentException ("The value for 'Access' must be specified.");
+			if (m_host == null) 
+				throw new ArgumentException ("The value for 'Host' must be specified.");
+			if (m_port == null) 
+				throw new ArgumentException ("The value for 'Port' must be specified.");
+			if (m_transport == null) 
+				throw new ArgumentException ("The value for 'Transport' must be specified.");
+
+			NetworkAccess access;
+			TransportType transport;
+			int port = SocketPermission.AllPorts;
+
+			if (String.Compare (m_access, "Connect", true) == 0)
+				access = NetworkAccess.Connect;
+			else if (String.Compare (m_access, "Accept", true) == 0)
+				access = NetworkAccess.Accept;
+			else 
+				throw new ArgumentException ("The parameter value 'Access=" + m_access + "' is invalid.");
+
+			if (String.Compare (m_port, "All", true) != 0) {
+				try {
+					port = Int32.Parse (m_port);					
+				} catch (Exception) {
+					throw new ArgumentException ("The parameter value 'Port=" + port + "' is invalid.");
+				}
+				// test whether port number is valid..
+				new IPEndPoint (1, port);
+			}
+
+			try {
+				transport = (TransportType) Enum.Parse (typeof (TransportType), m_transport, true);
+			} catch (Exception) {
+				throw new ArgumentException ("The parameter value 'Transport=" + m_transport + "' is invalid.");
+			}
+						
+			SocketPermission perm = new SocketPermission (PermissionState.None);
+			perm.AddPermission (access, transport, m_host, port);
+			return perm;
+		}		
+	}
+}

+ 1 - 0
mcs/class/System/Test/System.Net/AllTests.cs

@@ -22,6 +22,7 @@ namespace MonoTests.System.Net {
                                 TestSuite suite = new TestSuite ();
                                 suite.AddTest (IPAddressTest.Suite);
                                 suite.AddTest (IPEndPointTest.Suite);
+                                suite.AddTest (SocketPermissionTest.Suite);
                                 suite.AddTest (CookieTest.Suite);
                                 suite.AddTest (CookieCollectionTest.Suite);
                                 //suite.AddTest (CookieContainerTest.Suite);

+ 113 - 0
mcs/class/System/Test/System.Net/SocketPermissionTest.cs

@@ -0,0 +1,113 @@
+//
+// SocketPermissionTest.cs - NUnit Test Cases for System.Net.SocketPermission
+//
+// Author:
+//   Lawrence Pit ([email protected])
+//
+
+using NUnit.Framework;
+using System;
+using System.Net;
+using System.Collections;
+using System.Security;
+using System.Security.Permissions;
+
+namespace MonoTests.System.Net
+{
+
+public class SocketPermissionTest : TestCase
+{
+	SocketPermission s1;
+	SocketPermission s2;
+	
+        public SocketPermissionTest () :
+                base ("[MonoTests.System.Net.SocketPermissionTest]") {}
+
+        public SocketPermissionTest (string name) : base (name) {}
+
+        protected override void SetUp () 
+        {
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "localhost", 8080);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "123", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "www.ximian.com", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "120.4.3.2", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "www.google.com", 80);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "1.*.10.*.99", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "128.0.0.1", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "0.0.0.0", SocketPermission.AllPorts);
+		s1.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.*", SocketPermission.AllPorts);
+
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.All, "12.13.14.15", 80);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "localhost", 8080);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "123", 8080);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "www.google.com", SocketPermission.AllPorts);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "213.*.*.*", SocketPermission.AllPorts);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "128.0.0.1", 9090);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "216.239.*.*", SocketPermission.AllPorts);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "128.0.0.1", SocketPermission.AllPorts);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "120.4.3.2", 80);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "196.*.*.*", SocketPermission.AllPorts);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "1.*.*.*.99", SocketPermission.AllPorts);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.*.*", 9090);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.7", SocketPermission.AllPorts);		
+	}
+
+        protected override void TearDown () {}
+
+        public static ITest Suite
+        {
+                get {
+                        return new TestSuite (typeof (SocketPermissionTest));
+                }
+        }
+        
+        public void TestIsSubsetOf ()
+        {
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		s1.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.*", SocketPermission.AllPorts);
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.All, "12.13.14.15", 80);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.*.*", 9090);
+		
+		Assert ("#1", !s1.IsSubsetOf (s2));
+		Assert ("#2", !s2.IsSubsetOf (s1));
+
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		s1.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.*", 9090);
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.All, "12.13.14.15", 80);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.*.*", 9090);
+		
+		Assert ("#3: bug in MS.Net", s1.IsSubsetOf (s2));
+		Assert ("#4", !s2.IsSubsetOf (s1));
+		
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.*.*", 80);
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.All, "12.13.14.*", 80);
+		Assert ("#5", !s1.IsSubsetOf (s2));
+		Assert ("#6", !s2.IsSubsetOf (s1));
+
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		s1.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "10.11.*.*", 9090);
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.*", SocketPermission.AllPorts);
+		Assert ("#7", !s1.IsSubsetOf (s2));
+		Assert ("#8", s2.IsSubsetOf (s1));
+	}
+	
+	public void TestIntersect ()
+	{
+	}
+	
+	public void TestUnion ()
+	{
+	}
+	
+	public void TestXml ()
+	{
+		SecurityElement elem = s2.ToXml ();
+		s1.FromXml (elem);
+		Assert ("#1", s2.IsSubsetOf (s1) && s1.IsSubsetOf (s2));
+	}
+}
+
+}
+

+ 5 - 1
mcs/class/corlib/System.Security/ChangeLog

@@ -1,4 +1,8 @@
-2002-04-47  Lawrence Pit <[email protected]>
+2002-04-28  Lawrence Pit <[email protected]>
+
+	* CodeAccessPermission.cs : implemented ToString method
+
+2002-04-27  Lawrence Pit <[email protected]>
 
 	* SecurityElement.cs: fixed bugs, implemented several methods
 

+ 2 - 1
mcs/class/corlib/System.Security/CodeAccessPermission.cs

@@ -55,7 +55,8 @@ namespace System.Security {
 		///<returns> A System.String containing the XML  representation of the state of the current instance.</returns>
 		public override string ToString()
 		{
-		    return null;
+			SecurityElement elem = ToXml ();
+			return elem == null ? null : elem.ToString ();
 		}
 
 		///<summary> Returns the XML encoding of the current instance.</summary>

+ 2 - 2
mcs/class/corlib/System.Security/SecurityElement.cs

@@ -322,9 +322,9 @@ namespace System.Security
 			else {
 				s.Append (">").Append (text);
 				if (children != null) {
-					for (int i = 0; i < children.Count; i++) {
+					foreach (SecurityElement child in children) {
 						s.Append (Environment.NewLine);
-						((SecurityElement) children [i]).ToXml (ref s, level + 1);
+						child.ToXml (ref s, level + 1);
 					}
 				}
 				s.Append (Environment.NewLine)

+ 1 - 0
mcs/class/corlib/Test/System.Net/AllTests.cs

@@ -22,6 +22,7 @@ namespace MonoTests.System.Net {
                                 TestSuite suite = new TestSuite ();
                                 suite.AddTest (IPAddressTest.Suite);
                                 suite.AddTest (IPEndPointTest.Suite);
+                                suite.AddTest (SocketPermissionTest.Suite);
                                 suite.AddTest (CookieTest.Suite);
                                 suite.AddTest (CookieCollectionTest.Suite);
                                 //suite.AddTest (CookieContainerTest.Suite);

+ 113 - 0
mcs/class/corlib/Test/System.Net/SocketPermissionTest.cs

@@ -0,0 +1,113 @@
+//
+// SocketPermissionTest.cs - NUnit Test Cases for System.Net.SocketPermission
+//
+// Author:
+//   Lawrence Pit ([email protected])
+//
+
+using NUnit.Framework;
+using System;
+using System.Net;
+using System.Collections;
+using System.Security;
+using System.Security.Permissions;
+
+namespace MonoTests.System.Net
+{
+
+public class SocketPermissionTest : TestCase
+{
+	SocketPermission s1;
+	SocketPermission s2;
+	
+        public SocketPermissionTest () :
+                base ("[MonoTests.System.Net.SocketPermissionTest]") {}
+
+        public SocketPermissionTest (string name) : base (name) {}
+
+        protected override void SetUp () 
+        {
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "localhost", 8080);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "123", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "www.ximian.com", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "120.4.3.2", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "www.google.com", 80);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "1.*.10.*.99", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "128.0.0.1", SocketPermission.AllPorts);
+		//s1.AddPermission(NetworkAccess.Accept, TransportType.All, "0.0.0.0", SocketPermission.AllPorts);
+		s1.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.*", SocketPermission.AllPorts);
+
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.All, "12.13.14.15", 80);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "localhost", 8080);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "123", 8080);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "www.google.com", SocketPermission.AllPorts);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "213.*.*.*", SocketPermission.AllPorts);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "128.0.0.1", 9090);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "216.239.*.*", SocketPermission.AllPorts);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "128.0.0.1", SocketPermission.AllPorts);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "120.4.3.2", 80);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "196.*.*.*", SocketPermission.AllPorts);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "1.*.*.*.99", SocketPermission.AllPorts);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.*.*", 9090);
+		//s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.7", SocketPermission.AllPorts);		
+	}
+
+        protected override void TearDown () {}
+
+        public static ITest Suite
+        {
+                get {
+                        return new TestSuite (typeof (SocketPermissionTest));
+                }
+        }
+        
+        public void TestIsSubsetOf ()
+        {
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		s1.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.*", SocketPermission.AllPorts);
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.All, "12.13.14.15", 80);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.*.*", 9090);
+		
+		Assert ("#1", !s1.IsSubsetOf (s2));
+		Assert ("#2", !s2.IsSubsetOf (s1));
+
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		s1.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.*", 9090);
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.All, "12.13.14.15", 80);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.*.*", 9090);
+		
+		Assert ("#3: bug in MS.Net", s1.IsSubsetOf (s2));
+		Assert ("#4", !s2.IsSubsetOf (s1));
+		
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.*.*", 80);
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.All, "12.13.14.*", 80);
+		Assert ("#5", !s1.IsSubsetOf (s2));
+		Assert ("#6", !s2.IsSubsetOf (s1));
+
+		s1 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		s1.AddPermission(NetworkAccess.Accept, TransportType.Tcp, "10.11.*.*", 9090);
+		s2 = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "12.13.14.15", 80);
+		s2.AddPermission(NetworkAccess.Accept, TransportType.All, "10.11.4.*", SocketPermission.AllPorts);
+		Assert ("#7", !s1.IsSubsetOf (s2));
+		Assert ("#8", s2.IsSubsetOf (s1));
+	}
+	
+	public void TestIntersect ()
+	{
+	}
+	
+	public void TestUnion ()
+	{
+	}
+	
+	public void TestXml ()
+	{
+		SecurityElement elem = s2.ToXml ();
+		s1.FromXml (elem);
+		Assert ("#1", s2.IsSubsetOf (s1) && s1.IsSubsetOf (s2));
+	}
+}
+
+}
+