2 // System.Net.CredentialCache.cs
5 // Lawrence Pit (loz@cable.a2000.nl)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections;
31 using System.Runtime.Serialization;
33 namespace System.Net {
34 public class CredentialCache : ICredentials, IEnumerable, ICredentialsByHost
36 static NetworkCredential empty = new NetworkCredential (String.Empty, String.Empty, String.Empty);
38 Hashtable cacheForHost;
40 public CredentialCache ()
42 cache = new Hashtable ();
43 cacheForHost = new Hashtable ();
46 [MonoTODO ("Need EnvironmentPermission implementation first")]
47 public static ICredentials DefaultCredentials {
49 // This is used for NTLM, Kerberos and Negotiate under MS
54 // MS does might return a special ICredentials which does not allow getting the
55 // username/password information out of it for non-internal classes.
56 public static NetworkCredential DefaultNetworkCredentials {
60 public NetworkCredential GetCredential (Uri uriPrefix, string authType)
62 int longestPrefix = -1;
63 NetworkCredential result = null;
65 if (uriPrefix == null || authType == null)
68 string absPath = uriPrefix.AbsolutePath;
69 absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));
71 IDictionaryEnumerator e = cache.GetEnumerator ();
72 while (e.MoveNext ()) {
73 CredentialCacheKey key = e.Key as CredentialCacheKey;
75 if (key.Length <= longestPrefix)
78 if (String.Compare (key.AuthType, authType, true) != 0)
81 Uri cachedUri = key.UriPrefix;
83 if (cachedUri.Scheme != uriPrefix.Scheme)
86 if (cachedUri.Port != uriPrefix.Port)
89 if (cachedUri.Host != uriPrefix.Host)
92 if (!absPath.StartsWith (key.AbsPath))
95 longestPrefix = key.Length;
96 result = (NetworkCredential) e.Value;
102 public IEnumerator GetEnumerator ()
104 return cache.Values.GetEnumerator ();
107 public void Add (Uri uriPrefix, string authType, NetworkCredential cred)
109 if (uriPrefix == null)
110 throw new ArgumentNullException ("uriPrefix");
112 if (authType == null)
113 throw new ArgumentNullException ("authType");
115 // throws ArgumentException when same key already exists.
116 cache.Add (new CredentialCacheKey (uriPrefix, authType), cred);
119 public void Remove (Uri uriPrefix, string authType)
121 if (uriPrefix == null)
122 throw new ArgumentNullException ("uriPrefix");
124 if (authType == null)
125 throw new ArgumentNullException ("authType");
127 cache.Remove (new CredentialCacheKey (uriPrefix, authType));
130 public NetworkCredential GetCredential (string host, int port, string authenticationType)
132 NetworkCredential result = null;
134 if (host == null || port < 0 || authenticationType == null)
137 IDictionaryEnumerator e = cacheForHost.GetEnumerator ();
138 while (e.MoveNext ()) {
139 CredentialCacheForHostKey key = e.Key as CredentialCacheForHostKey;
141 if (String.Compare (key.AuthType, authenticationType, true) != 0)
144 if (key.Host != host)
147 if (key.Port != port)
150 result = (NetworkCredential) e.Value;
156 public void Add (string host, int port, string authenticationType, NetworkCredential credential)
159 throw new ArgumentNullException("host");
162 throw new ArgumentOutOfRangeException("port");
164 if (authenticationType == null)
165 throw new ArgumentOutOfRangeException("authenticationType");
167 cacheForHost.Add (new CredentialCacheForHostKey (host, port, authenticationType), credential);
170 public void Remove (string host, int port, string authenticationType)
175 if (authenticationType == null)
178 cacheForHost.Remove (new CredentialCacheForHostKey (host, port, authenticationType));
181 class CredentialCacheKey {
188 internal CredentialCacheKey (Uri uriPrefix, string authType)
190 this.uriPrefix = uriPrefix;
191 this.authType = authType;
193 this.absPath = uriPrefix.AbsolutePath;
194 this.absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));
196 this.len = uriPrefix.AbsoluteUri.Length;
197 this.hash = uriPrefix.GetHashCode ()
198 + authType.GetHashCode ();
205 public string AbsPath {
206 get { return absPath; }
209 public Uri UriPrefix {
210 get { return uriPrefix; }
213 public string AuthType {
214 get { return authType; }
217 public override int GetHashCode ()
222 public override bool Equals (object obj)
224 CredentialCacheKey key = obj as CredentialCacheKey;
225 return ((key != null) && (this.hash == key.hash));
228 public override string ToString ()
230 return absPath + " : " + authType + " : len=" + len;
234 class CredentialCacheForHostKey {
240 internal CredentialCacheForHostKey (string host, int port, string authType)
244 this.authType = authType;
246 this.hash = host.GetHashCode ()
247 + port.GetHashCode ()
248 + authType.GetHashCode ();
259 public string AuthType {
260 get { return authType; }
263 public override int GetHashCode ()
268 public override bool Equals (object obj)
270 CredentialCacheForHostKey key = obj as CredentialCacheForHostKey;
271 return ((key != null) && (this.hash == key.hash));
274 public override string ToString ()
276 return host + " : " + authType;