Merge pull request #1504 from madrang/SafeHandle.SetInvalidRelease
[mono.git] / mcs / class / System / System.Net / CredentialCache.cs
index b6ff252ab8fcbf2cd8c136d84a22ba464820423e..9978daa46d73a1caee1e21f8f0706712daeeafdc 100644 (file)
@@ -1,9 +1,9 @@
-//\r
-// System.Net.CredentialCache.cs\r
-//\r
-// Author:\r
-//   Lawrence Pit (loz@cable.a2000.nl)\r
-//\r
+//
+// System.Net.CredentialCache.cs
+//
+// Author:
+//   Lawrence Pit (loz@cable.a2000.nl)
+//
 
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-\r
-using System;\r
-using System.Collections;\r
-using System.Runtime.Serialization;\r
-\r
-namespace System.Net \r
-{\r
-       public class CredentialCache : ICredentials, IEnumerable\r
-       {\r
-               // Fields\r
-               private Hashtable cache;\r
-               \r
-               // Constructors         \r
-               public CredentialCache () \r
-               {\r
-                       cache = new Hashtable ();\r
-               }\r
-               \r
-               // Properties\r
-               \r
-               [MonoTODO ("Need EnvironmentPermission implementation first")]\r
-               public static ICredentials DefaultCredentials {\r
-                       get {\r
-                               // This is used for NTLM, Kerberos and Negotiate under MS\r
-                               return null;\r
-                       }\r
-               }\r
-               \r
-\r
-               // ICredentials\r
-\r
-               public NetworkCredential GetCredential (Uri uriPrefix, string authType)\r
-               {\r
-                       int longestPrefix = -1;\r
-                       NetworkCredential result = null;\r
-                       \r
-                       if (uriPrefix == null || authType == null)\r
-                               return null;\r
-                               \r
-                       string absPath = uriPrefix.AbsolutePath;\r
-                       absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));\r
-                       \r
-                       IDictionaryEnumerator e = cache.GetEnumerator ();\r
-                       while (e.MoveNext ()) {\r
-                               CredentialCacheKey key = e.Key as CredentialCacheKey;\r
-                               \r
-                               if (key.Length <= longestPrefix) \r
-                                       continue;\r
-                               \r
-                               if (String.Compare (key.AuthType, authType, true) != 0)\r
-                                       continue;\r
-                               \r
-                               Uri cachedUri = key.UriPrefix;\r
-                               \r
-                               if (cachedUri.Scheme != uriPrefix.Scheme)\r
-                                       continue;\r
-                                       \r
-                               if (cachedUri.Port != uriPrefix.Port)\r
-                                       continue;\r
-                                       \r
-                               if (cachedUri.Host != uriPrefix.Host)\r
-                                       continue;\r
-                                                               \r
-                               if (!absPath.StartsWith (key.AbsPath))\r
-                                       continue;\r
-                                       \r
-                               longestPrefix = key.Length;\r
-                               result = (NetworkCredential) e.Value;\r
-                       }\r
-                       \r
-                       return result;\r
-               }\r
-\r
-               // IEnumerable\r
-\r
-               public IEnumerator GetEnumerator ()\r
-               {\r
-                       return cache.Values.GetEnumerator ();\r
-               }               \r
-               \r
-               // Methods\r
-               \r
-               public void Add (Uri uriPrefix, string authType, NetworkCredential cred)\r
-               {\r
-                       if (uriPrefix == null) \r
-                               throw new ArgumentNullException ("uriPrefix");\r
-\r
-                       if (authType == null) \r
-                               throw new ArgumentNullException ("authType");\r
-                       \r
-                       // throws ArgumentException when same key already exists.\r
-                       cache.Add (new CredentialCacheKey (uriPrefix, authType), cred);\r
-               }\r
-               \r
-               public void Remove (Uri uriPrefix, string authType)\r
-               {\r
-                       if (uriPrefix == null) \r
-                               throw new ArgumentNullException ("uriPrefix");\r
-\r
-                       if (authType == null) \r
-                               throw new ArgumentNullException ("authType");\r
-\r
-                       cache.Remove (new CredentialCacheKey (uriPrefix, authType));\r
-               }\r
-               \r
-               // Inner Classes\r
-               \r
-               internal class CredentialCacheKey\r
-               {\r
-                       private Uri uriPrefix;\r
-                       private string authType;\r
-                       \r
-                       private string absPath;\r
-                       private int len;\r
-                       private int hash;\r
-                       \r
-                       internal CredentialCacheKey (Uri uriPrefix, string authType)\r
-                       {\r
-                               this.uriPrefix = uriPrefix;\r
-                               this.authType = authType;\r
-                               \r
-                               this.absPath = uriPrefix.AbsolutePath;\r
-                               this.absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));                                \r
-\r
-                               this.len = uriPrefix.AbsoluteUri.Length;\r
-                               this.hash = uriPrefix.GetHashCode () \r
-                                         + authType.ToString ().GetHashCode ();\r
-                       }\r
-                       \r
-                       public int Length {\r
-                               get { return len; }\r
-                       }                       \r
-                       \r
-                       public string AbsPath {\r
-                               get { return absPath; }\r
-                       }\r
-                       \r
-                       public Uri UriPrefix {\r
-                               get { return uriPrefix; }\r
-                       }\r
-                       \r
-                       public string AuthType {\r
-                               get { return authType; }\r
-                       }\r
-                       \r
-                       public override int GetHashCode ()\r
-                       {\r
-                               return hash;\r
-                       }\r
-                       \r
-                       public override bool Equals (object obj)\r
-                       {\r
-                               CredentialCacheKey key = obj as CredentialCacheKey;\r
-                               return ((key != null) && (this.hash == key.hash));\r
-                       }\r
-                       \r
-                       public override string ToString ()\r
-                       {\r
-                               return absPath + " : " + authType + " : len=" + len;\r
-                       }\r
-               }\r
-       } \r
-} \r
-\r
+
+using System;
+using System.Collections;
+using System.Runtime.Serialization;
+
+namespace System.Net {
+       public class CredentialCache : ICredentials, IEnumerable, ICredentialsByHost
+       {
+               static NetworkCredential empty = new NetworkCredential (String.Empty, String.Empty, String.Empty);
+               Hashtable cache;
+               Hashtable cacheForHost;
+
+               public CredentialCache () 
+               {
+                       cache = new Hashtable ();
+                       cacheForHost = new Hashtable ();
+               }
+               
+               [MonoTODO ("Need EnvironmentPermission implementation first")]
+               public static ICredentials DefaultCredentials {
+                       get {
+                               // This is used for NTLM, Kerberos and Negotiate under MS
+                               return empty;
+                       }
+               }
+
+               // MS does might return a special ICredentials which does not allow getting the
+               // username/password information out of it for non-internal classes.
+               public static NetworkCredential DefaultNetworkCredentials {
+                       get { return empty; }
+               }
+
+               public NetworkCredential GetCredential (Uri uriPrefix, string authType)
+               {
+                       int longestPrefix = -1;
+                       NetworkCredential result = null;
+                       
+                       if (uriPrefix == null || authType == null)
+                               return null;
+                               
+                       string absPath = uriPrefix.AbsolutePath;
+                       absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));
+                       
+                       IDictionaryEnumerator e = cache.GetEnumerator ();
+                       while (e.MoveNext ()) {
+                               CredentialCacheKey key = e.Key as CredentialCacheKey;
+                               
+                               if (key.Length <= longestPrefix) 
+                                       continue;
+                               
+                               if (String.Compare (key.AuthType, authType, true) != 0)
+                                       continue;
+                               
+                               Uri cachedUri = key.UriPrefix;
+                               
+                               if (cachedUri.Scheme != uriPrefix.Scheme)
+                                       continue;
+                                       
+                               if (cachedUri.Port != uriPrefix.Port)
+                                       continue;
+                                       
+                               if (cachedUri.Host != uriPrefix.Host)
+                                       continue;
+                                                               
+                               if (!absPath.StartsWith (key.AbsPath))
+                                       continue;
+                                       
+                               longestPrefix = key.Length;
+                               result = (NetworkCredential) e.Value;
+                       }
+                       
+                       return result;
+               }
+
+               public IEnumerator GetEnumerator ()
+               {
+                       return cache.Values.GetEnumerator ();
+               }               
+               
+               public void Add (Uri uriPrefix, string authType, NetworkCredential cred)
+               {
+                       if (uriPrefix == null) 
+                               throw new ArgumentNullException ("uriPrefix");
+
+                       if (authType == null) 
+                               throw new ArgumentNullException ("authType");
+                       
+                       // throws ArgumentException when same key already exists.
+                       cache.Add (new CredentialCacheKey (uriPrefix, authType), cred);
+               }
+               
+               public void Remove (Uri uriPrefix, string authType)
+               {
+                       if (uriPrefix == null) 
+                               throw new ArgumentNullException ("uriPrefix");
+
+                       if (authType == null) 
+                               throw new ArgumentNullException ("authType");
+
+                       cache.Remove (new CredentialCacheKey (uriPrefix, authType));
+               }
+               
+               public NetworkCredential GetCredential (string host, int port, string authenticationType)
+               {
+                       NetworkCredential result = null;
+                       
+                       if (host == null || port < 0 || authenticationType == null)
+                               return null;
+
+                       IDictionaryEnumerator e = cacheForHost.GetEnumerator ();
+                       while (e.MoveNext ()) {
+                               CredentialCacheForHostKey key = e.Key as CredentialCacheForHostKey;
+                               
+                               if (String.Compare (key.AuthType, authenticationType, true) != 0)
+                                       continue;
+                               
+                               if (key.Host != host)
+                                       continue;
+                               
+                               if (key.Port != port)
+                                       continue;
+                               
+                               result = (NetworkCredential) e.Value;
+                       }
+                       
+                       return result;
+               }
+
+               public void Add (string host, int port, string authenticationType, NetworkCredential credential)
+               {
+                       if (host == null)
+                               throw new ArgumentNullException("host");
+
+                       if (port < 0)
+                               throw new ArgumentOutOfRangeException("port");
+
+                       if (authenticationType == null)
+                               throw new ArgumentOutOfRangeException("authenticationType");
+
+                       cacheForHost.Add (new CredentialCacheForHostKey (host, port, authenticationType), credential);
+               }
+
+               public void Remove (string host, int port, string authenticationType)
+               {
+                       if (host == null)
+                               return;
+
+                       if (authenticationType == null)
+                               return;
+
+                       cacheForHost.Remove (new CredentialCacheForHostKey (host, port, authenticationType));
+               }
+
+               class CredentialCacheKey {
+                       Uri uriPrefix;
+                       string authType;
+                       string absPath;
+                       int len;
+                       int hash;
+                       
+                       internal CredentialCacheKey (Uri uriPrefix, string authType)
+                       {
+                               this.uriPrefix = uriPrefix;
+                               this.authType = authType;
+                               
+                               this.absPath = uriPrefix.AbsolutePath;
+                               this.absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));                                
+
+                               this.len = uriPrefix.AbsoluteUri.Length;
+                               this.hash = uriPrefix.GetHashCode () 
+                                         + authType.GetHashCode ();
+                       }
+                       
+                       public int Length {
+                               get { return len; }
+                       }                       
+                       
+                       public string AbsPath {
+                               get { return absPath; }
+                       }
+                       
+                       public Uri UriPrefix {
+                               get { return uriPrefix; }
+                       }
+                       
+                       public string AuthType {
+                               get { return authType; }
+                       }
+                       
+                       public override int GetHashCode ()
+                       {
+                               return hash;
+                       }
+                       
+                       public override bool Equals (object obj)
+                       {
+                               CredentialCacheKey key = obj as CredentialCacheKey;
+                               return ((key != null) && (this.hash == key.hash));
+                       }
+                       
+                       public override string ToString ()
+                       {
+                               return absPath + " : " + authType + " : len=" + len;
+                       }
+               }
+
+               class CredentialCacheForHostKey {
+                       string host;
+                       int port;
+                       string authType;
+                       int hash;
+
+                       internal CredentialCacheForHostKey (string host, int port, string authType)
+                       {
+                               this.host = host;
+                               this.port = port;
+                               this.authType = authType;
+
+                               this.hash = host.GetHashCode ()
+                                       + port.GetHashCode ()
+                                       + authType.GetHashCode ();
+                       }
+
+                       public string Host {
+                               get { return host; }
+                       }
+
+                       public int Port {
+                               get { return port; }
+                       }
+
+                       public string AuthType {
+                               get { return authType; }
+                       }
+
+               public override int GetHashCode ()
+               {
+                       return hash;
+               }
+
+               public override bool Equals (object obj)
+               {
+                       CredentialCacheForHostKey key = obj as CredentialCacheForHostKey;
+                       return ((key != null) && (this.hash == key.hash));
+               }
+
+               public override string ToString ()
+               {
+                       return host + " : " + authType;
+               }
+       }
+}
+}
+
+