3 // Copyright (c) Microsoft Corporation. All rights reserved.
8 // <OWNER>[....]</OWNER>
11 namespace System.Security.Util {
13 using System.Collections;
14 using System.Globalization;
15 using System.Diagnostics.Contracts;
18 internal class SiteString
20 protected String m_site;
21 protected ArrayList m_separatedSite;
23 protected static char[] m_separators = { '.' };
25 protected internal SiteString()
27 // Only call this in derived classes when you know what you're doing.
30 public SiteString( String site )
32 m_separatedSite = CreateSeparatedSite( site );
36 private SiteString(String site, ArrayList separatedSite)
38 m_separatedSite = separatedSite;
42 private static ArrayList CreateSeparatedSite(String site)
44 if (site == null || site.Length == 0)
46 throw new ArgumentException( Environment.GetResourceString("Argument_InvalidSite" ));
48 Contract.EndContractBlock();
50 ArrayList list = new ArrayList();
53 braIndex = site.IndexOf('[');
55 ketIndex = site.IndexOf(']', braIndex+1);
59 // Found an IPv6 address. Special case that
60 String ipv6Addr = site.Substring(braIndex+1, ketIndex-braIndex-1);
65 // Regular hostnames or IPv4 addresses
66 // We dont need to do this for IPv4 addresses, but it's easier to do it anyway
67 String[] separatedArray = site.Split( m_separators );
69 for (int index = separatedArray.Length-1; index > -1; --index)
71 if (separatedArray[index] == null)
73 throw new ArgumentException( Environment.GetResourceString("Argument_InvalidSite" ));
75 else if (separatedArray[index].Equals( "" ))
77 if (index != separatedArray.Length-1)
79 throw new ArgumentException( Environment.GetResourceString("Argument_InvalidSite" ));
82 else if (separatedArray[index].Equals( "*" ))
86 throw new ArgumentException( Environment.GetResourceString("Argument_InvalidSite" ));
88 list.Add( separatedArray[index] );
90 else if (!AllLegalCharacters( separatedArray[index] ))
92 throw new ArgumentException( Environment.GetResourceString("Argument_InvalidSite" ));
96 list.Add( separatedArray[index] );
103 // KB# Q188997 - http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q188997& gives the list of allowed characters in
104 // a NETBIOS name. DNS names are a subset of that (alphanumeric or '-').
105 private static bool AllLegalCharacters( String str )
107 for (int i = 0; i < str.Length; ++i)
111 if (IsLegalDNSChar(c) ||
125 private static bool IsLegalDNSChar(char c)
127 if ((c >= 'a' && c <= 'z') ||
128 (c >= 'A' && c <= 'Z') ||
129 (c >= '0' && c <= '9') ||
135 private static bool IsNetbiosSplChar(char c)
137 // ! @ # $ % ^ & ( ) - _ ' { } . ~ are OK
161 public override String ToString()
166 public override bool Equals(Object o)
168 if (o == null || !(o is SiteString))
171 return this.Equals( (SiteString)o, true );
174 public override int GetHashCode()
176 TextInfo info = CultureInfo.InvariantCulture.TextInfo;
178 return info.GetCaseInsensitiveHashCode( this.m_site );
181 internal bool Equals( SiteString ss, bool ignoreCase )
183 if (this.m_site == null)
184 return ss.m_site == null;
185 if (ss.m_site == null)
187 return this.IsSubsetOf(ss, ignoreCase) && ss.IsSubsetOf(this, ignoreCase);
191 public virtual SiteString Copy()
193 return new SiteString( m_site, m_separatedSite );
196 public virtual bool IsSubsetOf( SiteString operand )
198 return this.IsSubsetOf( operand, true );
201 public virtual bool IsSubsetOf( SiteString operand, bool ignoreCase )
203 StringComparison strComp = (ignoreCase? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
208 else if (this.m_separatedSite.Count == operand.m_separatedSite.Count &&
209 this.m_separatedSite.Count == 0)
213 else if (this.m_separatedSite.Count < operand.m_separatedSite.Count - 1)
217 else if (this.m_separatedSite.Count > operand.m_separatedSite.Count &&
218 operand.m_separatedSite.Count > 0 &&
219 !operand.m_separatedSite[operand.m_separatedSite.Count - 1].Equals("*"))
223 else if (String.Compare( this.m_site, operand.m_site, strComp) == 0)
228 for (int index = 0; index < operand.m_separatedSite.Count - 1; ++index)
230 if (String.Compare((String)this.m_separatedSite[index], (String)operand.m_separatedSite[index], strComp) != 0)
236 if (this.m_separatedSite.Count < operand.m_separatedSite.Count)
238 return operand.m_separatedSite[operand.m_separatedSite.Count - 1].Equals("*");
240 else if (this.m_separatedSite.Count == operand.m_separatedSite.Count)
242 // last item must be the same or operand must have a * in its last item
243 return (String.Compare((String)this.m_separatedSite[this.m_separatedSite.Count - 1],
244 (String)operand.m_separatedSite[this.m_separatedSite.Count - 1],
246 operand.m_separatedSite[operand.m_separatedSite.Count - 1].Equals("*"));
255 public virtual SiteString Intersect( SiteString operand )
261 else if (this.IsSubsetOf( operand ))
265 else if (operand.IsSubsetOf( this ))
267 return operand.Copy();
275 public virtual SiteString Union( SiteString operand )
281 else if (this.IsSubsetOf( operand ))
283 return operand.Copy();
285 else if (operand.IsSubsetOf( this ))