PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/System/System.Net/SocketPermission.cs

https://github.com/iainlane/mono
C# | 354 lines | 217 code | 54 blank | 83 comment | 67 complexity | 2518bd8957c2a38832d706e6d14b0375 MD5 | raw file
  1. //
  2. // System.Net.SocketPermission.cs
  3. //
  4. // Author:
  5. // Lawrence Pit (loz@cable.a2000.nl)
  6. //
  7. //
  8. // Permission is hereby granted, free of charge, to any person obtaining
  9. // a copy of this software and associated documentation files (the
  10. // "Software"), to deal in the Software without restriction, including
  11. // without limitation the rights to use, copy, modify, merge, publish,
  12. // distribute, sublicense, and/or sell copies of the Software, and to
  13. // permit persons to whom the Software is furnished to do so, subject to
  14. // the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be
  17. // included in all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  22. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  23. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  24. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  25. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. //
  27. using System.Collections;
  28. using System.Security;
  29. using System.Security.Permissions;
  30. namespace System.Net {
  31. [Serializable]
  32. public sealed class SocketPermission : CodeAccessPermission, IUnrestrictedPermission
  33. {
  34. // Fields
  35. ArrayList m_acceptList = new ArrayList ();
  36. ArrayList m_connectList = new ArrayList ();
  37. bool m_noRestriction;
  38. // Constructors
  39. public SocketPermission (PermissionState state) : base ()
  40. {
  41. m_noRestriction = (state == PermissionState.Unrestricted);
  42. }
  43. public SocketPermission (NetworkAccess access, TransportType transport,
  44. string hostName, int portNumber) : base ()
  45. {
  46. m_noRestriction = false;
  47. AddPermission (access, transport, hostName, portNumber);
  48. }
  49. // Fields
  50. public const int AllPorts = -1;
  51. // Properties
  52. public IEnumerator AcceptList {
  53. get { return m_acceptList.GetEnumerator (); }
  54. }
  55. public IEnumerator ConnectList {
  56. get { return m_connectList.GetEnumerator (); }
  57. }
  58. // Methods
  59. public void AddPermission (NetworkAccess access, TransportType transport,
  60. string hostName, int portNumber)
  61. {
  62. if (m_noRestriction)
  63. return;
  64. EndpointPermission permission = new EndpointPermission (hostName, portNumber, transport);
  65. if (access == NetworkAccess.Accept)
  66. m_acceptList.Add (permission);
  67. else
  68. m_connectList.Add (permission);
  69. }
  70. public override IPermission Copy ()
  71. {
  72. SocketPermission permission;
  73. permission = new SocketPermission (m_noRestriction ?
  74. PermissionState.Unrestricted :
  75. PermissionState.None);
  76. // as EndpointPermission's are immutable it's safe to do a shallow copy.
  77. permission.m_connectList = (ArrayList) this.m_connectList.Clone ();
  78. permission.m_acceptList = (ArrayList) this.m_acceptList.Clone ();
  79. return permission;
  80. }
  81. public override IPermission Intersect (IPermission target)
  82. {
  83. if (target == null)
  84. return null;
  85. SocketPermission perm = target as SocketPermission;
  86. if (perm == null)
  87. throw new ArgumentException ("Argument not of type SocketPermission");
  88. if (m_noRestriction)
  89. return IntersectEmpty (perm) ? null : perm.Copy ();
  90. if (perm.m_noRestriction)
  91. return IntersectEmpty (this) ? null : this.Copy ();
  92. SocketPermission newperm = new SocketPermission (PermissionState.None);
  93. Intersect (this.m_connectList, perm.m_connectList, newperm.m_connectList);
  94. Intersect (this.m_acceptList, perm.m_acceptList, newperm.m_acceptList);
  95. return IntersectEmpty (newperm) ? null : newperm;
  96. }
  97. private bool IntersectEmpty (SocketPermission permission)
  98. {
  99. return !permission.m_noRestriction &&
  100. (permission.m_connectList.Count == 0) &&
  101. (permission.m_acceptList.Count == 0);
  102. }
  103. private void Intersect (ArrayList list1, ArrayList list2, ArrayList result)
  104. {
  105. foreach (EndpointPermission perm1 in list1) {
  106. foreach (EndpointPermission perm2 in list2) {
  107. EndpointPermission perm = perm1.Intersect (perm2);
  108. if (perm != null) {
  109. // instead of the below it's also okay to simply do:
  110. // result.Add (perm);
  111. // below is only done to avoid double entries
  112. bool replaced = false;
  113. for (int i = 0; i < result.Count; i++) {
  114. EndpointPermission res = (EndpointPermission) result [i];
  115. EndpointPermission resperm = perm.Intersect (res);
  116. if (resperm != null) {
  117. result [i] = resperm;
  118. replaced = true;
  119. break;
  120. }
  121. }
  122. if (!replaced)
  123. result.Add (perm);
  124. }
  125. }
  126. }
  127. }
  128. public override bool IsSubsetOf (IPermission target)
  129. {
  130. if (target == null)
  131. return (!m_noRestriction && m_connectList.Count == 0 && m_acceptList.Count == 0);
  132. SocketPermission perm = target as SocketPermission;
  133. if (perm == null)
  134. throw new ArgumentException ("Parameter target must be of type SocketPermission");
  135. if (perm.m_noRestriction)
  136. return true;
  137. if (this.m_noRestriction)
  138. return false;
  139. if (this.m_acceptList.Count == 0 && this.m_connectList.Count == 0)
  140. return true;
  141. if (perm.m_acceptList.Count == 0 && perm.m_connectList.Count == 0)
  142. return false;
  143. return IsSubsetOf (this.m_connectList, perm.m_connectList)
  144. && IsSubsetOf (this.m_acceptList, perm.m_acceptList);
  145. }
  146. private bool IsSubsetOf (ArrayList list1, ArrayList list2)
  147. {
  148. foreach (EndpointPermission perm1 in list1) {
  149. bool issubset = false;
  150. foreach (EndpointPermission perm2 in list2)
  151. if (perm1.IsSubsetOf (perm2)) {
  152. issubset = true;
  153. break;
  154. }
  155. if (!issubset)
  156. return false;
  157. }
  158. return true;
  159. }
  160. public bool IsUnrestricted ()
  161. {
  162. return m_noRestriction;
  163. }
  164. /*
  165. SocketPermission s = new SocketPermission (NetworkAccess.Connect, TransportType.Tcp, "www.google.com", 80);
  166. s.AddPermission (NetworkAccess.Accept, TransportType.All, "localhost", 8080);
  167. s.AddPermission (NetworkAccess.Accept, TransportType.All, "localhost", SocketPermission.AllPorts);
  168. // s = new SocketPermission (PermissionState.None);
  169. SecurityElement sec = s.ToXml ();
  170. Console.WriteLine (sec.ToString ());
  171. This is sample xml output:
  172. <IPermission class="System.Net.SocketPermission, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  173. version="1">
  174. <ConnectAccess>
  175. <ENDPOINT host="www.google.com"
  176. transport="Tcp"
  177. port="80"/>
  178. </ConnectAccess>
  179. <AcceptAccess>
  180. <ENDPOINT host="localhost"
  181. transport="All"
  182. port="8080"/>
  183. <ENDPOINT host="localhost"
  184. transport="All"
  185. port="All"/>
  186. </AcceptAccess>
  187. </IPermission>
  188. This is a sample unrestricted socketpermission, no matter how many permissions you add:
  189. <IPermission class="System.Net.SocketPermission, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  190. version="1"
  191. Unrestricted="true"/>
  192. This is a sample constructed restricted socketpermission with no permissions added:
  193. <IPermission class="System.Net.SocketPermission, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  194. version="1"/>
  195. */
  196. public override SecurityElement ToXml ()
  197. {
  198. SecurityElement root = new SecurityElement ("IPermission");
  199. root.AddAttribute ("class", this.GetType ().AssemblyQualifiedName);
  200. root.AddAttribute ("version", "1");
  201. if (m_noRestriction) {
  202. root.AddAttribute ("Unrestricted", "true");
  203. return root;
  204. }
  205. if (this.m_connectList.Count > 0)
  206. ToXml (root, "ConnectAccess", m_connectList.GetEnumerator ());
  207. if (this.m_acceptList.Count > 0)
  208. ToXml (root, "AcceptAccess", m_acceptList.GetEnumerator ());
  209. return root;
  210. }
  211. private void ToXml (SecurityElement root, string childName, IEnumerator enumerator)
  212. {
  213. SecurityElement child = new SecurityElement (childName);
  214. while (enumerator.MoveNext ()) {
  215. EndpointPermission perm = enumerator.Current as EndpointPermission;
  216. SecurityElement grandchild = new SecurityElement ("ENDPOINT");
  217. grandchild.AddAttribute ("host", perm.Hostname);
  218. grandchild.AddAttribute ("transport", perm.Transport.ToString ());
  219. grandchild.AddAttribute ("port",
  220. perm.Port == AllPorts
  221. ? "All"
  222. : ((Int32) perm.Port).ToString ());
  223. child.AddChild (grandchild);
  224. }
  225. root.AddChild (child);
  226. }
  227. public override void FromXml (SecurityElement securityElement)
  228. {
  229. if (securityElement == null)
  230. throw new ArgumentNullException ("securityElement");
  231. // LAMESPEC: it says to throw an ArgumentNullException in this case
  232. if (securityElement.Tag != "IPermission")
  233. throw new ArgumentException ("securityElement");
  234. string unrestricted = securityElement.Attribute ("Unrestricted");
  235. if (unrestricted != null) {
  236. this.m_noRestriction = (String.Compare (unrestricted, "true", true) == 0);
  237. if (this.m_noRestriction)
  238. return;
  239. }
  240. this.m_noRestriction = false;
  241. this.m_connectList = new ArrayList ();
  242. this.m_acceptList = new ArrayList ();
  243. ArrayList children = securityElement.Children;
  244. foreach (SecurityElement child in children) {
  245. if (child.Tag == "ConnectAccess")
  246. FromXml (child.Children, NetworkAccess.Connect);
  247. else if (child.Tag == "AcceptAccess")
  248. FromXml (child.Children, NetworkAccess.Accept);
  249. }
  250. }
  251. private void FromXml (ArrayList endpoints, NetworkAccess access)
  252. {
  253. foreach (SecurityElement endpoint in endpoints) {
  254. if (endpoint.Tag != "ENDPOINT")
  255. continue;
  256. string hostname = endpoint.Attribute ("host");
  257. TransportType transport =
  258. (TransportType) Enum.Parse (typeof (TransportType),
  259. endpoint.Attribute ("transport"),
  260. true);
  261. string p = endpoint.Attribute ("port");
  262. int port = 0;
  263. if (p == "All")
  264. port = SocketPermission.AllPorts;
  265. else
  266. port = Int32.Parse (p);
  267. AddPermission (access, transport, hostname, port);
  268. }
  269. }
  270. public override IPermission Union (IPermission target)
  271. {
  272. // LAMESPEC: according to spec we should throw an
  273. // exception when target is null. We'll follow the
  274. // behaviour of MS.Net instead of the spec, also
  275. // because it matches the Intersect behaviour.
  276. if (target == null)
  277. return null;
  278. // throw new ArgumentNullException ("target");
  279. SocketPermission perm = target as SocketPermission;
  280. if (perm == null)
  281. throw new ArgumentException ("Argument not of type SocketPermission");
  282. if (this.m_noRestriction || perm.m_noRestriction)
  283. return new SocketPermission (PermissionState.Unrestricted);
  284. SocketPermission copy = (SocketPermission) perm.Copy ();
  285. copy.m_acceptList.InsertRange (copy.m_acceptList.Count, this.m_acceptList);
  286. copy.m_connectList.InsertRange (copy.m_connectList.Count, this.m_connectList);
  287. return copy;
  288. }
  289. }
  290. }