C# 3.0 updates
[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
42                 public CredentialCache () 
43                 {
44                         cache = new Hashtable ();
45                 }
46                 
47                 [MonoTODO ("Need EnvironmentPermission implementation first")]
48                 public static ICredentials DefaultCredentials {
49                         get {
50                                 // This is used for NTLM, Kerberos and Negotiate under MS
51                                 return empty;
52                         }
53                 }
54
55 #if NET_2_0
56                 // MS does might return a special ICredentials which does not allow getting the
57                 // username/password information out of it for non-internal classes.
58                 public static NetworkCredential DefaultNetworkCredentials {
59                         get { return empty; }
60                 }
61 #endif
62
63                 public NetworkCredential GetCredential (Uri uriPrefix, string authType)
64                 {
65                         int longestPrefix = -1;
66                         NetworkCredential result = null;
67                         
68                         if (uriPrefix == null || authType == null)
69                                 return null;
70                                 
71                         string absPath = uriPrefix.AbsolutePath;
72                         absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));
73                         
74                         IDictionaryEnumerator e = cache.GetEnumerator ();
75                         while (e.MoveNext ()) {
76                                 CredentialCacheKey key = e.Key as CredentialCacheKey;
77                                 
78                                 if (key.Length <= longestPrefix) 
79                                         continue;
80                                 
81                                 if (String.Compare (key.AuthType, authType, true) != 0)
82                                         continue;
83                                 
84                                 Uri cachedUri = key.UriPrefix;
85                                 
86                                 if (cachedUri.Scheme != uriPrefix.Scheme)
87                                         continue;
88                                         
89                                 if (cachedUri.Port != uriPrefix.Port)
90                                         continue;
91                                         
92                                 if (cachedUri.Host != uriPrefix.Host)
93                                         continue;
94                                                                 
95                                 if (!absPath.StartsWith (key.AbsPath))
96                                         continue;
97                                         
98                                 longestPrefix = key.Length;
99                                 result = (NetworkCredential) e.Value;
100                         }
101                         
102                         return result;
103                 }
104
105                 public IEnumerator GetEnumerator ()
106                 {
107                         return cache.Values.GetEnumerator ();
108                 }               
109                 
110                 public void Add (Uri uriPrefix, string authType, NetworkCredential cred)
111                 {
112                         if (uriPrefix == null) 
113                                 throw new ArgumentNullException ("uriPrefix");
114
115                         if (authType == null) 
116                                 throw new ArgumentNullException ("authType");
117                         
118                         // throws ArgumentException when same key already exists.
119                         cache.Add (new CredentialCacheKey (uriPrefix, authType), cred);
120                 }
121                 
122                 public void Remove (Uri uriPrefix, string authType)
123                 {
124                         if (uriPrefix == null) 
125                                 throw new ArgumentNullException ("uriPrefix");
126
127                         if (authType == null) 
128                                 throw new ArgumentNullException ("authType");
129
130                         cache.Remove (new CredentialCacheKey (uriPrefix, authType));
131                 }
132                 
133 #if NET_2_0
134                 [MonoNotSupported ("")]
135                 public void Add (string host, int port, string authenticationType, NetworkCredential credential)
136                 {
137                         throw new NotImplementedException ();
138                 }
139
140                 [MonoNotSupported ("")]
141                 public NetworkCredential GetCredential (string host, int port, string authenticationType)
142                 {
143                         throw new NotImplementedException ();
144                 }
145
146                 [MonoNotSupported ("")]
147                 public void Remove (string host, int port, string authenticationType)
148                 {
149                         throw new NotImplementedException ();
150                 }
151 #endif
152
153                 class CredentialCacheKey {
154                         Uri uriPrefix;
155                         string authType;
156                         string absPath;
157                         int len;
158                         int hash;
159                         
160                         internal CredentialCacheKey (Uri uriPrefix, string authType)
161                         {
162                                 this.uriPrefix = uriPrefix;
163                                 this.authType = authType;
164                                 
165                                 this.absPath = uriPrefix.AbsolutePath;
166                                 this.absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));                                
167
168                                 this.len = uriPrefix.AbsoluteUri.Length;
169                                 this.hash = uriPrefix.GetHashCode () 
170                                           + authType.GetHashCode ();
171                         }
172                         
173                         public int Length {
174                                 get { return len; }
175                         }                       
176                         
177                         public string AbsPath {
178                                 get { return absPath; }
179                         }
180                         
181                         public Uri UriPrefix {
182                                 get { return uriPrefix; }
183                         }
184                         
185                         public string AuthType {
186                                 get { return authType; }
187                         }
188                         
189                         public override int GetHashCode ()
190                         {
191                                 return hash;
192                         }
193                         
194                         public override bool Equals (object obj)
195                         {
196                                 CredentialCacheKey key = obj as CredentialCacheKey;
197                                 return ((key != null) && (this.hash == key.hash));
198                         }
199                         
200                         public override string ToString ()
201                         {
202                                 return absPath + " : " + authType + " : len=" + len;
203                         }
204                 }
205         } 
206 }
207
208