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