2 // System.Net.EndpointPermission.cs
\r
5 // Lawrence Pit (loz@cable.a2000.nl)
\r
9 using System.Collections;
\r
10 using System.Security;
\r
11 using System.Security.Permissions;
\r
13 namespace System.Net
\r
16 public class EndpointPermission // too bad about the lowercase p, not consistent with IPEndPoint ;)
\r
18 private static char [] dot_char = new char [] { '.' };
\r
21 private string hostname;
\r
23 private TransportType transport;
\r
25 private bool resolved;
\r
26 private bool hasWildcard;
\r
27 private IPAddress [] addresses;
\r
30 internal EndpointPermission (string hostname,
\r
32 TransportType transport) : base ()
\r
34 if (hostname == null)
\r
35 throw new ArgumentNullException ("hostname");
\r
36 this.hostname = hostname;
\r
38 this.transport = transport;
\r
39 this.resolved = false;
\r
40 this.hasWildcard = false;
\r
41 this.addresses = null;
\r
46 public string Hostname {
\r
47 get { return hostname; }
\r
51 get { return port; }
\r
54 public TransportType Transport {
\r
55 get { return transport; }
\r
60 public override bool Equals (object obj)
\r
62 EndpointPermission epp = obj as EndpointPermission;
\r
63 return ((epp != null) &&
\r
64 (this.port == epp.port) &&
\r
65 (this.transport == epp.transport) &&
\r
66 (String.Compare (this.hostname, epp.hostname, true) == 0));
\r
69 public override int GetHashCode ()
\r
71 return ToString ().GetHashCode ();
\r
74 public override string ToString ()
\r
76 return hostname + "#" + port + "#" + (int) transport;
\r
79 // Internal & Private Methods
\r
81 internal bool IsSubsetOf (EndpointPermission perm)
\r
86 if (perm.port != SocketPermission.AllPorts &&
\r
87 this.port != perm.port)
\r
90 if (perm.transport != TransportType.All &&
\r
91 this.transport != perm.transport)
\r
97 if (this.hasWildcard) {
\r
98 if (perm.hasWildcard)
\r
99 return IsSubsetOf (this.hostname, perm.hostname);
\r
104 if (this.addresses == null)
\r
107 if (perm.hasWildcard)
\r
108 // a bit dubious... should they all be a subset or is one
\r
109 // enough in this case?
\r
110 foreach (IPAddress addr in this.addresses)
\r
111 if (IsSubsetOf (addr.ToString (), perm.hostname))
\r
114 if (perm.addresses == null)
\r
117 // a bit dubious... should they all be a subset or is one
\r
118 // enough in this case?
\r
119 foreach (IPAddress addr in perm.addresses)
\r
120 if (IsSubsetOf (this.hostname, addr.ToString ()))
\r
126 private bool IsSubsetOf (string addr1, string addr2)
\r
128 string [] h1 = addr1.Split (dot_char);
\r
129 string [] h2 = addr2.Split (dot_char);
\r
131 for (int i = 0; i < 4; i++) {
\r
132 int part1 = ToNumber (h1 [i]);
\r
136 int part2 = ToNumber (h2 [i]);
\r
139 if (part1 != part2 && part2 != 256)
\r
145 internal EndpointPermission Intersect (EndpointPermission perm)
\r
151 if (this.port == perm.port)
\r
153 else if (this.port == SocketPermission.AllPorts)
\r
155 else if (perm.port == SocketPermission.AllPorts)
\r
160 TransportType _transport;
\r
161 if (this.transport == perm.transport)
\r
162 _transport = this.transport;
\r
163 else if (this.transport == TransportType.All)
\r
164 _transport = perm.transport;
\r
165 else if (perm.transport == TransportType.All)
\r
166 _transport = this.transport;
\r
170 string _hostname = IntersectHostname (perm);
\r
172 if (_hostname == null)
\r
175 if (!this.hasWildcard)
\r
178 if (!perm.hasWildcard)
\r
181 EndpointPermission newperm = new EndpointPermission (_hostname, _port, _transport);
\r
182 newperm.hasWildcard = true;
\r
183 newperm.resolved = true;
\r
187 private string IntersectHostname (EndpointPermission perm)
\r
189 if (this.hostname == perm.hostname)
\r
190 return this.hostname;
\r
195 string _hostname = null;
\r
197 if (this.hasWildcard) {
\r
198 if (perm.hasWildcard) {
\r
199 _hostname = Intersect (this.hostname, perm.hostname);
\r
200 } else if (perm.addresses != null) {
\r
201 for (int j = 0; j < perm.addresses.Length; j++) {
\r
202 _hostname = Intersect (this.hostname, perm.addresses [j].ToString ());
\r
203 if (_hostname != null)
\r
207 } else if (this.addresses != null) {
\r
208 for (int i = 0; i < this.addresses.Length; i++) {
\r
209 string thisaddr = this.addresses [i].ToString ();
\r
210 if (perm.hasWildcard) {
\r
211 _hostname = Intersect (thisaddr, perm.hostname);
\r
212 } else if (perm.addresses != null) {
\r
213 for (int j = 0; j < perm.addresses.Length; j++) {
\r
214 _hostname = Intersect (thisaddr, perm.addresses [j].ToString ());
\r
215 if (_hostname != null)
\r
225 // alas, currently we'll only support IPv4 as that's MS.Net behaviour
\r
226 // returns null when both host strings do not intersect
\r
227 private string Intersect (string addr1, string addr2)
\r
229 string [] h1 = addr1.Split (dot_char);
\r
230 string [] h2 = addr2.Split (dot_char);
\r
232 string [] s = new string [7];
\r
233 for (int i = 0; i < 4; i++) {
\r
234 int part1 = ToNumber (h1 [i]);
\r
238 int part2 = ToNumber (h2 [i]);
\r
243 s [i << 1] = (part2 == 256) ? "*" : String.Empty + part2;
\r
244 else if (part2 == 256)
\r
245 s [i << 1] = (part1 == 256) ? "*" : String.Empty + part1;
\r
246 else if (part1 == part2)
\r
247 s [i << 1] = String.Empty + part1;
\r
252 s [1] = s [3] = s [5] = ".";
\r
253 return String.Concat (s);
\r
256 // returns 256 if value is a '*' character
\r
257 // returns -1 if value isn't a number between 0 and 255
\r
258 private int ToNumber (string value)
\r
263 int len = value.Length;
\r
264 if (len < 1 || len > 3)
\r
268 for (int i = 0; i < len; i++) {
\r
269 char c = value [i];
\r
270 if ('0' <= c && c <= '9')
\r
271 val = checked (val * 10 + (c - '0'));
\r
276 return val <= 255 ? val : -1;
\r
279 internal void Resolve ()
\r
284 bool isHostname = false;
\r
285 bool hasWildcard = false;
\r
286 this.addresses = null;
\r
288 string [] s = hostname.Split (dot_char);
\r
290 if (s.Length != 4) {
\r
293 for (int i = 0; i < 4; i++) {
\r
294 int quad = ToNumber (s [i]);
\r
300 hasWildcard = true;
\r
305 this.hasWildcard = false;
\r
307 this.addresses = Dns.GetHostByName (hostname).AddressList;
\r
308 } catch (System.Net.Sockets.SocketException) {
\r
311 this.hasWildcard = hasWildcard;
\r
312 if (!hasWildcard) {
\r
313 addresses = new IPAddress [1];
\r
314 addresses [0] = IPAddress.Parse (hostname);
\r
318 this.resolved = true;
\r
321 internal void UndoResolve ()
\r