[System]: WebRequest.GetSystemProxy(): Return custom proxy for monodroid.
[mono.git] / mcs / class / System / System.Net / WebPermission.cs
1 //
2 // System.Net.WebPermission.cs
3 //
4 // Author:
5 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
6 //   (based on SocketPermission.cs)
7 //
8 // (C) 2003 Andreas Nahr
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System;
33 using System.Collections;
34 using System.Security;
35 using System.Security.Permissions;
36 using System.Text.RegularExpressions;
37
38 namespace System.Net {
39
40         internal enum WebPermissionInfoType {
41                 InfoString,
42                 InfoUnexecutedRegex,
43                 InfoRegex,
44         }
45
46         internal class WebPermissionInfo {
47                 WebPermissionInfoType _type;
48                 object _info;
49
50                 public WebPermissionInfo (WebPermissionInfoType type, string info)
51                 {
52                         _type = type;
53                         _info = (string) info;
54                 }
55
56                 public WebPermissionInfo (Regex regex)
57                 {
58                         _type = WebPermissionInfoType.InfoRegex;
59                         _info = (object) regex;
60                 }
61
62                 public string Info {
63                         get {
64                                 if (_type == WebPermissionInfoType.InfoRegex)
65                                         return null;
66                                 return (string) _info;
67                         }
68                 }
69         }
70
71         // (based on SocketPermission.cs - Please look there to implement missing members!)
72         [MonoTODO ("Most private members that include functionallity are not implemented!")]
73         [Serializable]
74         public sealed class WebPermission : CodeAccessPermission, IUnrestrictedPermission
75         {
76                 // Fields
77                 ArrayList m_acceptList = new ArrayList ();
78                 ArrayList m_connectList = new ArrayList ();
79                 bool m_noRestriction = false;
80
81                 // Constructors
82                 public WebPermission () : base () 
83                 {                               
84                 }
85
86                 public WebPermission (PermissionState state) : base () 
87                 {                                               
88                         m_noRestriction = (state == PermissionState.Unrestricted);
89                 }
90
91                 public WebPermission (NetworkAccess access, string uriString) : base () 
92                 {
93                         AddPermission (access, uriString);
94                 }               
95
96                 public WebPermission (NetworkAccess access, Regex uriRegex) : base () 
97                 {
98                         AddPermission (access, uriRegex);
99                 }
100
101                 // Properties
102                 public IEnumerator AcceptList {
103                         get { return m_acceptList.GetEnumerator (); }
104                 }
105
106                 public IEnumerator ConnectList {
107                         get { return m_connectList.GetEnumerator (); }
108                 }
109
110                 // Methods
111
112                 public void AddPermission (NetworkAccess access, string uriString)
113                 {
114                         WebPermissionInfo info = new WebPermissionInfo (WebPermissionInfoType.InfoString, uriString); 
115                         AddPermission (access, info);
116                 }
117
118                 public void AddPermission (NetworkAccess access, Regex uriRegex)
119                 {
120                         WebPermissionInfo info = new WebPermissionInfo (uriRegex); 
121                         AddPermission (access, info);
122                 }
123
124                 internal void AddPermission (NetworkAccess access, WebPermissionInfo info)
125                 {
126                         switch (access) {
127                                 case NetworkAccess.Accept:
128                                         m_acceptList.Add (info);
129                                         break;
130                                 case NetworkAccess.Connect:
131                                         m_connectList.Add (info);
132                                         break;
133                                 default:
134                                         string msg = Locale.GetText ("Unknown NetworkAccess value {0}.");
135                                         throw new ArgumentException (String.Format (msg, access), "access");
136                         }
137                 }
138
139                 public override IPermission Copy ()
140                 {
141                         WebPermission permission;
142                         permission = new WebPermission (m_noRestriction ? 
143                                                 PermissionState.Unrestricted : 
144                                                 PermissionState.None);
145
146                         // as EndpointPermission's are immutable it's safe to do a shallow copy.
147                         permission.m_connectList = (ArrayList) 
148                         this.m_connectList.Clone ();
149                         permission.m_acceptList = (ArrayList) this.m_acceptList.Clone ();
150                         return permission;
151                 }
152
153                 public override IPermission Intersect (IPermission target)
154                 {
155                         if (target == null) 
156                                 return null;
157                         WebPermission perm = target as WebPermission;
158                         if (perm == null) 
159                                 throw new ArgumentException ("Argument not of type WebPermission");
160                         if (m_noRestriction) 
161                                 return IntersectEmpty (perm) ? null : perm.Copy ();
162                         if (perm.m_noRestriction)
163                                 return IntersectEmpty (this) ? null : this.Copy ();
164                         WebPermission newperm = new WebPermission (PermissionState.None);
165                         Intersect (this.m_connectList, perm.m_connectList, newperm.m_connectList);
166                         Intersect (this.m_acceptList, perm.m_acceptList, newperm.m_acceptList);
167                         return IntersectEmpty (newperm) ? null : newperm;
168                 }
169
170                 private bool IntersectEmpty (WebPermission permission)
171                 {
172                         return !permission.m_noRestriction && 
173                                (permission.m_connectList.Count == 0) &&
174                                (permission.m_acceptList.Count == 0);
175                 }
176
177                 [MonoTODO]
178                 private void Intersect (ArrayList list1, ArrayList list2, ArrayList result)
179                 {
180                         throw new NotImplementedException ();
181                 }
182
183                 public override bool IsSubsetOf (IPermission target) 
184                 {
185                         if (target == null)
186                                 return (!m_noRestriction && m_connectList.Count == 0 && m_acceptList.Count == 0);
187                         WebPermission perm = target as WebPermission;
188                         if (perm == null) 
189                                 throw new ArgumentException ("Parameter target must be of type WebPermission");
190                         if (perm.m_noRestriction)
191                                 return true;
192                         if (this.m_noRestriction)
193                                 return false;
194                         if (this.m_acceptList.Count == 0 && this.m_connectList.Count == 0)
195                                 return true;
196                         if (perm.m_acceptList.Count == 0 && perm.m_connectList.Count == 0)
197                                 return false;
198                         return IsSubsetOf (this.m_connectList, perm.m_connectList)
199                             && IsSubsetOf (this.m_acceptList, perm.m_acceptList);
200                 }
201
202
203                 [MonoTODO]
204                 private bool IsSubsetOf (ArrayList list1, ArrayList list2)
205                 {
206                         throw new NotImplementedException ();
207                 }
208
209                 public bool IsUnrestricted ()
210                 {
211                         return m_noRestriction;
212                 }
213
214                 public override SecurityElement ToXml ()
215                 {
216                         SecurityElement root = new SecurityElement ("IPermission");
217                         root.AddAttribute ("class", this.GetType ().AssemblyQualifiedName);
218                         root.AddAttribute ("version", "1");
219                         if (m_noRestriction) {
220                                 root.AddAttribute ("Unrestricted", "true");
221                                 return root;
222                         }                               
223                         if (this.m_connectList.Count > 0)
224                                 ToXml (root, "ConnectAccess", m_connectList.GetEnumerator ());
225                         if (this.m_acceptList.Count > 0) 
226                                 ToXml (root, "AcceptAccess", m_acceptList.GetEnumerator ());
227                         return root;
228                 }
229
230                 private void ToXml (SecurityElement root, string childName, IEnumerator enumerator)
231                 {
232                         SecurityElement child = new SecurityElement (childName, null);
233
234                         root.AddChild (child);
235                         while (enumerator.MoveNext ()){
236                                 WebPermissionInfo x = enumerator.Current as WebPermissionInfo;
237
238                                 if (x == null) continue;
239
240                                 SecurityElement uri = new SecurityElement ("URI");
241                                 uri.AddAttribute ("uri", x.Info);
242                                 child.AddChild (uri);
243                         }
244                 }
245
246                 public override void FromXml (SecurityElement securityElement)
247                 {
248                         if (securityElement == null)
249                                 throw new ArgumentNullException ("securityElement");
250
251                         // LAMESPEC: it says to throw an ArgumentNullException in this case
252                         if (securityElement.Tag != "IPermission")
253                                 throw new ArgumentException ("securityElement");
254
255                         string unrestricted = securityElement.Attribute ("Unrestricted");
256                         if (unrestricted != null) {
257                                 this.m_noRestriction = (String.Compare (unrestricted, "true", true) == 0);
258                                 if (this.m_noRestriction)
259                                         return;
260                         }
261                         this.m_noRestriction = false;
262                         this.m_connectList = new ArrayList ();
263                         this.m_acceptList = new ArrayList ();
264                         ArrayList children = securityElement.Children;
265                         foreach (SecurityElement child in children) {
266                                 if (child.Tag == "ConnectAccess") 
267                                         FromXml (child.Children, NetworkAccess.Connect);
268                                 else if (child.Tag == "AcceptAccess")
269                                         FromXml (child.Children, NetworkAccess.Accept);
270                         }
271                 }
272
273                 private void FromXml (ArrayList endpoints, NetworkAccess access)
274                 {
275                         throw new NotImplementedException ();
276                 }
277
278                 public override IPermission Union (IPermission target) 
279                 {
280                         // LAMESPEC: according to spec we should throw an 
281                         // exception when target is null. We'll follow the
282                         // behaviour of MS.Net instead of the spec, also
283                         // because it matches the Intersect behaviour.
284
285                         if (target == null)
286                                 return null;
287                                 // throw new ArgumentNullException ("target");
288
289                         WebPermission perm = target as WebPermission;
290                         if (perm == null)
291                                 throw new ArgumentException ("Argument not of type WebPermission");
292                         if (this.m_noRestriction || perm.m_noRestriction) 
293                                 return new WebPermission (PermissionState.Unrestricted);
294
295                         WebPermission copy = (WebPermission) perm.Copy ();
296                         copy.m_acceptList.InsertRange (copy.m_acceptList.Count, this.m_acceptList);
297                         copy.m_connectList.InsertRange (copy.m_connectList.Count, this.m_connectList);
298
299                         return copy;
300                 }
301         }
302