/mcs/class/System/System.Net/EndpointPermission.cs
C# | 349 lines | 253 code | 57 blank | 39 comment | 112 complexity | 9c48415cab2c60cab0af998e13f2f1e2 MD5 | raw file
- //
- // System.Net.EndpointPermission.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;
- 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 == 256)
- continue;
- 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.GetHostAddresses (hostname);
- } 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;
- }
- }
- }