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
39 static NetworkCredential empty = new NetworkCredential (String.Empty, String.Empty, String.Empty);
42 Hashtable cacheForHost;
45 public CredentialCache ()
47 cache = new Hashtable ();
49 cacheForHost = new Hashtable ();
53 [MonoTODO ("Need EnvironmentPermission implementation first")]
54 public static ICredentials DefaultCredentials {
56 // This is used for NTLM, Kerberos and Negotiate under MS
62 // MS does might return a special ICredentials which does not allow getting the
63 // username/password information out of it for non-internal classes.
64 public static NetworkCredential DefaultNetworkCredentials {
69 public NetworkCredential GetCredential (Uri uriPrefix, string authType)
71 int longestPrefix = -1;
72 NetworkCredential result = null;
74 if (uriPrefix == null || authType == null)
77 string absPath = uriPrefix.AbsolutePath;
78 absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));
80 IDictionaryEnumerator e = cache.GetEnumerator ();
81 while (e.MoveNext ()) {
82 CredentialCacheKey key = e.Key as CredentialCacheKey;
84 if (key.Length <= longestPrefix)
87 if (String.Compare (key.AuthType, authType, true) != 0)
90 Uri cachedUri = key.UriPrefix;
92 if (cachedUri.Scheme != uriPrefix.Scheme)
95 if (cachedUri.Port != uriPrefix.Port)
98 if (cachedUri.Host != uriPrefix.Host)
101 if (!absPath.StartsWith (key.AbsPath))
104 longestPrefix = key.Length;
105 result = (NetworkCredential) e.Value;
111 public IEnumerator GetEnumerator ()
113 return cache.Values.GetEnumerator ();
116 public void Add (Uri uriPrefix, string authType, NetworkCredential cred)
118 if (uriPrefix == null)
119 throw new ArgumentNullException ("uriPrefix");
121 if (authType == null)
122 throw new ArgumentNullException ("authType");
124 // throws ArgumentException when same key already exists.
125 cache.Add (new CredentialCacheKey (uriPrefix, authType), cred);
128 public void Remove (Uri uriPrefix, string authType)
130 if (uriPrefix == null)
131 throw new ArgumentNullException ("uriPrefix");
133 if (authType == null)
134 throw new ArgumentNullException ("authType");
136 cache.Remove (new CredentialCacheKey (uriPrefix, authType));
140 public NetworkCredential GetCredential (string host, int port, string authenticationType)
142 NetworkCredential result = null;
144 if (host == null || port < 0 || authenticationType == null)
147 IDictionaryEnumerator e = cacheForHost.GetEnumerator ();
148 while (e.MoveNext ()) {
149 CredentialCacheForHostKey key = e.Key as CredentialCacheForHostKey;
151 if (String.Compare (key.AuthType, authenticationType, true) != 0)
154 if (key.Host != host)
157 if (key.Port != port)
160 result = (NetworkCredential) e.Value;
166 public void Add (string host, int port, string authenticationType, NetworkCredential credential)
169 throw new ArgumentNullException("host");
172 throw new ArgumentOutOfRangeException("port");
174 if (authenticationType == null)
175 throw new ArgumentOutOfRangeException("authenticationType");
177 cacheForHost.Add (new CredentialCacheForHostKey (host, port, authenticationType), credential);
180 public void Remove (string host, int port, string authenticationType)
185 if (authenticationType == null)
188 cacheForHost.Remove (new CredentialCacheForHostKey (host, port, authenticationType));
192 class CredentialCacheKey {
199 internal CredentialCacheKey (Uri uriPrefix, string authType)
201 this.uriPrefix = uriPrefix;
202 this.authType = authType;
204 this.absPath = uriPrefix.AbsolutePath;
205 this.absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));
207 this.len = uriPrefix.AbsoluteUri.Length;
208 this.hash = uriPrefix.GetHashCode ()
209 + authType.GetHashCode ();
216 public string AbsPath {
217 get { return absPath; }
220 public Uri UriPrefix {
221 get { return uriPrefix; }
224 public string AuthType {
225 get { return authType; }
228 public override int GetHashCode ()
233 public override bool Equals (object obj)
235 CredentialCacheKey key = obj as CredentialCacheKey;
236 return ((key != null) && (this.hash == key.hash));
239 public override string ToString ()
241 return absPath + " : " + authType + " : len=" + len;
246 class CredentialCacheForHostKey {
252 internal CredentialCacheForHostKey (string host, int port, string authType)
256 this.authType = authType;
258 this.hash = host.GetHashCode ()
259 + port.GetHashCode ()
260 + authType.GetHashCode ();
271 public string AuthType {
272 get { return authType; }
275 public override int GetHashCode ()
280 public override bool Equals (object obj)
282 CredentialCacheForHostKey key = obj as CredentialCacheForHostKey;
283 return ((key != null) && (this.hash == key.hash));
286 public override string ToString ()
288 return host + " : " + authType;