Fix GetConsumingEnumerable exception handling in BlockingCollection
[mono.git] / mcs / class / System / System.Net / CredentialCache.cs
1 //
2 // System.Net.CredentialCache.cs
3 //
4 // Author:
5 //   Lawrence Pit (loz@cable.a2000.nl)
6 //
7
8 //
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:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
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.
27 //
28
29 using System;
30 using System.Collections;
31 using System.Runtime.Serialization;
32
33 namespace System.Net {
34         public class CredentialCache : ICredentials, IEnumerable
35 #if NET_2_0
36                                      , ICredentialsByHost
37 #endif
38         {
39                 static NetworkCredential empty = new NetworkCredential (String.Empty, String.Empty, String.Empty);
40                 Hashtable cache;
41 #if NET_2_0
42                 Hashtable cacheForHost;
43 #endif
44
45                 public CredentialCache () 
46                 {
47                         cache = new Hashtable ();
48 #if NET_2_0
49                         cacheForHost = new Hashtable ();
50 #endif
51                 }
52                 
53                 [MonoTODO ("Need EnvironmentPermission implementation first")]
54                 public static ICredentials DefaultCredentials {
55                         get {
56                                 // This is used for NTLM, Kerberos and Negotiate under MS
57                                 return empty;
58                         }
59                 }
60
61 #if NET_2_0
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 {
65                         get { return empty; }
66                 }
67 #endif
68
69                 public NetworkCredential GetCredential (Uri uriPrefix, string authType)
70                 {
71                         int longestPrefix = -1;
72                         NetworkCredential result = null;
73                         
74                         if (uriPrefix == null || authType == null)
75                                 return null;
76                                 
77                         string absPath = uriPrefix.AbsolutePath;
78                         absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));
79                         
80                         IDictionaryEnumerator e = cache.GetEnumerator ();
81                         while (e.MoveNext ()) {
82                                 CredentialCacheKey key = e.Key as CredentialCacheKey;
83                                 
84                                 if (key.Length <= longestPrefix) 
85                                         continue;
86                                 
87                                 if (String.Compare (key.AuthType, authType, true) != 0)
88                                         continue;
89                                 
90                                 Uri cachedUri = key.UriPrefix;
91                                 
92                                 if (cachedUri.Scheme != uriPrefix.Scheme)
93                                         continue;
94                                         
95                                 if (cachedUri.Port != uriPrefix.Port)
96                                         continue;
97                                         
98                                 if (cachedUri.Host != uriPrefix.Host)
99                                         continue;
100                                                                 
101                                 if (!absPath.StartsWith (key.AbsPath))
102                                         continue;
103                                         
104                                 longestPrefix = key.Length;
105                                 result = (NetworkCredential) e.Value;
106                         }
107                         
108                         return result;
109                 }
110
111                 public IEnumerator GetEnumerator ()
112                 {
113                         return cache.Values.GetEnumerator ();
114                 }               
115                 
116                 public void Add (Uri uriPrefix, string authType, NetworkCredential cred)
117                 {
118                         if (uriPrefix == null) 
119                                 throw new ArgumentNullException ("uriPrefix");
120
121                         if (authType == null) 
122                                 throw new ArgumentNullException ("authType");
123                         
124                         // throws ArgumentException when same key already exists.
125                         cache.Add (new CredentialCacheKey (uriPrefix, authType), cred);
126                 }
127                 
128                 public void Remove (Uri uriPrefix, string authType)
129                 {
130                         if (uriPrefix == null) 
131                                 throw new ArgumentNullException ("uriPrefix");
132
133                         if (authType == null) 
134                                 throw new ArgumentNullException ("authType");
135
136                         cache.Remove (new CredentialCacheKey (uriPrefix, authType));
137                 }
138                 
139 #if NET_2_0
140                 public NetworkCredential GetCredential (string host, int port, string authenticationType)
141                 {
142                         NetworkCredential result = null;
143                         
144                         if (host == null || port < 0 || authenticationType == null)
145                                 return null;
146
147                         IDictionaryEnumerator e = cacheForHost.GetEnumerator ();
148                         while (e.MoveNext ()) {
149                                 CredentialCacheForHostKey key = e.Key as CredentialCacheForHostKey;
150                                 
151                                 if (String.Compare (key.AuthType, authenticationType, true) != 0)
152                                         continue;
153                                 
154                                 if (key.Host != host)
155                                         continue;
156                                 
157                                 if (key.Port != port)
158                                         continue;
159                                 
160                                 result = (NetworkCredential) e.Value;
161                         }
162                         
163                         return result;
164                 }
165
166                 public void Add (string host, int port, string authenticationType, NetworkCredential credential)
167                 {
168                         if (host == null)
169                                 throw new ArgumentNullException("host");
170
171                         if (port < 0)
172                                 throw new ArgumentOutOfRangeException("port");
173
174                         if (authenticationType == null)
175                                 throw new ArgumentOutOfRangeException("authenticationType");
176
177                         cacheForHost.Add (new CredentialCacheForHostKey (host, port, authenticationType), credential);
178                 }
179
180                 public void Remove (string host, int port, string authenticationType)
181                 {
182                         if (host == null)
183                                 return;
184
185                         if (authenticationType == null)
186                                 return;
187
188                         cacheForHost.Remove (new CredentialCacheForHostKey (host, port, authenticationType));
189                 }
190 #endif
191
192                 class CredentialCacheKey {
193                         Uri uriPrefix;
194                         string authType;
195                         string absPath;
196                         int len;
197                         int hash;
198                         
199                         internal CredentialCacheKey (Uri uriPrefix, string authType)
200                         {
201                                 this.uriPrefix = uriPrefix;
202                                 this.authType = authType;
203                                 
204                                 this.absPath = uriPrefix.AbsolutePath;
205                                 this.absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));                                
206
207                                 this.len = uriPrefix.AbsoluteUri.Length;
208                                 this.hash = uriPrefix.GetHashCode () 
209                                           + authType.GetHashCode ();
210                         }
211                         
212                         public int Length {
213                                 get { return len; }
214                         }                       
215                         
216                         public string AbsPath {
217                                 get { return absPath; }
218                         }
219                         
220                         public Uri UriPrefix {
221                                 get { return uriPrefix; }
222                         }
223                         
224                         public string AuthType {
225                                 get { return authType; }
226                         }
227                         
228                         public override int GetHashCode ()
229                         {
230                                 return hash;
231                         }
232                         
233                         public override bool Equals (object obj)
234                         {
235                                 CredentialCacheKey key = obj as CredentialCacheKey;
236                                 return ((key != null) && (this.hash == key.hash));
237                         }
238                         
239                         public override string ToString ()
240                         {
241                                 return absPath + " : " + authType + " : len=" + len;
242                         }
243                 }
244
245 #if NET_2_0
246                 class CredentialCacheForHostKey {
247                         string host;
248                         int port;
249                         string authType;
250                         int hash;
251
252                         internal CredentialCacheForHostKey (string host, int port, string authType)
253                         {
254                                 this.host = host;
255                                 this.port = port;
256                                 this.authType = authType;
257
258                                 this.hash = host.GetHashCode ()
259                                         + port.GetHashCode ()
260                                         + authType.GetHashCode ();
261                         }
262
263                         public string Host {
264                                 get { return host; }
265                         }
266
267                         public int Port {
268                                 get { return port; }
269                         }
270
271                         public string AuthType {
272                                 get { return authType; }
273                         }
274
275                 public override int GetHashCode ()
276                 {
277                         return hash;
278                 }
279
280                 public override bool Equals (object obj)
281                 {
282                         CredentialCacheForHostKey key = obj as CredentialCacheForHostKey;
283                         return ((key != null) && (this.hash == key.hash));
284                 }
285
286                 public override string ToString ()
287                 {
288                         return host + " : " + authType;
289                 }
290         }
291 #endif
292 }
293 }
294
295