SocketPermission.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. //
  2. // System.Net.SocketPermission.cs
  3. //
  4. // Author:
  5. // Lawrence Pit ([email protected])
  6. //
  7. using System;
  8. using System.Collections;
  9. using System.Security;
  10. using System.Security.Permissions;
  11. namespace System.Net
  12. {
  13. [Serializable]
  14. public sealed class SocketPermission : CodeAccessPermission, IUnrestrictedPermission
  15. {
  16. // Fields
  17. ArrayList m_acceptList = new ArrayList ();
  18. ArrayList m_connectList = new ArrayList ();
  19. bool m_noRestriction;
  20. // Constructors
  21. public SocketPermission (PermissionState state) : base ()
  22. {
  23. m_noRestriction = (state == PermissionState.Unrestricted);
  24. }
  25. public SocketPermission (NetworkAccess access, TransportType transport,
  26. string hostName, int portNumber) : base ()
  27. {
  28. m_noRestriction = false;
  29. AddPermission (access, transport, hostName, portNumber);
  30. }
  31. // Fields
  32. public const int AllPorts = -1;
  33. // Properties
  34. public IEnumerator AcceptList {
  35. get { return m_acceptList.GetEnumerator (); }
  36. }
  37. public IEnumerator ConnectList {
  38. get { return m_connectList.GetEnumerator (); }
  39. }
  40. // Methods
  41. public void AddPermission (NetworkAccess access, TransportType transport,
  42. string hostName, int portNumber)
  43. {
  44. if (m_noRestriction)
  45. return;
  46. EndpointPermission permission = new EndpointPermission (hostName, portNumber, transport);
  47. if (access == NetworkAccess.Accept)
  48. m_acceptList.Add (permission);
  49. else
  50. m_connectList.Add (permission);
  51. }
  52. public override IPermission Copy ()
  53. {
  54. SocketPermission permission;
  55. permission = new SocketPermission (m_noRestriction ?
  56. PermissionState.Unrestricted :
  57. PermissionState.None);
  58. // as EndpointPermission's are immutable it's safe to do a shallow copy.
  59. permission.m_connectList = (ArrayList) this.m_connectList.Clone ();
  60. permission.m_acceptList = (ArrayList) this.m_acceptList.Clone ();
  61. return permission;
  62. }
  63. public override IPermission Intersect (IPermission target)
  64. {
  65. if (target == null)
  66. return null;
  67. SocketPermission perm = target as SocketPermission;
  68. if (perm == null)
  69. throw new ArgumentException ("Argument not of type SocketPermission");
  70. if (m_noRestriction)
  71. return IntersectEmpty (perm) ? null : perm.Copy ();
  72. if (perm.m_noRestriction)
  73. return IntersectEmpty (this) ? null : this.Copy ();
  74. SocketPermission newperm = new SocketPermission (PermissionState.None);
  75. Intersect (this.m_connectList, perm.m_connectList, newperm.m_connectList);
  76. Intersect (this.m_acceptList, perm.m_acceptList, newperm.m_acceptList);
  77. return IntersectEmpty (newperm) ? null : newperm;
  78. }
  79. private bool IntersectEmpty (SocketPermission permission)
  80. {
  81. return !permission.m_noRestriction &&
  82. (permission.m_connectList.Count == 0) &&
  83. (permission.m_acceptList.Count == 0);
  84. }
  85. private void Intersect (ArrayList list1, ArrayList list2, ArrayList result)
  86. {
  87. foreach (EndpointPermission perm1 in list1) {
  88. foreach (EndpointPermission perm2 in list2) {
  89. EndpointPermission perm = perm1.Intersect (perm2);
  90. if (perm != null) {
  91. // instead of the below it's also okay to simply do:
  92. // result.Add (perm);
  93. // below is only done to avoid double entries
  94. bool replaced = false;
  95. for (int i = 0; i < result.Count; i++) {
  96. EndpointPermission res = (EndpointPermission) result [i];
  97. EndpointPermission resperm = perm.Intersect (res);
  98. if (resperm != null) {
  99. result [i] = resperm;
  100. replaced = true;
  101. break;
  102. }
  103. }
  104. if (!replaced)
  105. result.Add (perm);
  106. }
  107. }
  108. }
  109. }
  110. public override bool IsSubsetOf (IPermission target)
  111. {
  112. if (target == null)
  113. return (!m_noRestriction && m_connectList.Count == 0 && m_acceptList.Count == 0);
  114. SocketPermission perm = target as SocketPermission;
  115. if (perm == null)
  116. throw new ArgumentException ("Parameter target must be of type SocketPermission");
  117. if (perm.m_noRestriction)
  118. return true;
  119. if (this.m_noRestriction)
  120. return false;
  121. if (this.m_acceptList.Count == 0 && this.m_connectList.Count == 0)
  122. return true;
  123. if (perm.m_acceptList.Count == 0 && perm.m_connectList.Count == 0)
  124. return false;
  125. return IsSubsetOf (this.m_connectList, perm.m_connectList)
  126. && IsSubsetOf (this.m_acceptList, perm.m_acceptList);
  127. }
  128. private bool IsSubsetOf (ArrayList list1, ArrayList list2)
  129. {
  130. foreach (EndpointPermission perm1 in list1) {
  131. bool issubset = false;
  132. foreach (EndpointPermission perm2 in list2)
  133. if (perm1.IsSubsetOf (perm2)) {
  134. issubset = true;
  135. break;
  136. }
  137. if (!issubset)
  138. return false;
  139. }
  140. return true;
  141. }
  142. public bool IsUnrestricted ()
  143. {
  144. return m_noRestriction;
  145. }
  146. /*
  147. SocketPermission s = new SocketPermission (NetworkAccess.Connect, TransportType.Tcp, "www.google.com", 80);
  148. s.AddPermission (NetworkAccess.Accept, TransportType.All, "localhost", 8080);
  149. s.AddPermission (NetworkAccess.Accept, TransportType.All, "localhost", SocketPermission.AllPorts);
  150. // s = new SocketPermission (PermissionState.None);
  151. SecurityElement sec = s.ToXml ();
  152. Console.WriteLine (sec.ToString ());
  153. This is sample xml output:
  154. <IPermission class="System.Net.SocketPermission, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  155. version="1">
  156. <ConnectAccess>
  157. <ENDPOINT host="www.google.com"
  158. transport="Tcp"
  159. port="80"/>
  160. </ConnectAccess>
  161. <AcceptAccess>
  162. <ENDPOINT host="localhost"
  163. transport="All"
  164. port="8080"/>
  165. <ENDPOINT host="localhost"
  166. transport="All"
  167. port="All"/>
  168. </AcceptAccess>
  169. </IPermission>
  170. This is a sample unrestricted socketpermission, no matter how many permissions you add:
  171. <IPermission class="System.Net.SocketPermission, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  172. version="1"
  173. Unrestricted="true"/>
  174. This is a sample constructed restricted socketpermission with no permissions added:
  175. <IPermission class="System.Net.SocketPermission, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  176. version="1"/>
  177. */
  178. public override SecurityElement ToXml ()
  179. {
  180. SecurityElement root = new SecurityElement ("IPermission");
  181. root.AddAttribute ("class", this.GetType ().AssemblyQualifiedName);
  182. root.AddAttribute ("version", "1");
  183. if (m_noRestriction) {
  184. root.AddAttribute ("Unrestricted", "true");
  185. return root;
  186. }
  187. if (this.m_connectList.Count > 0)
  188. ToXml (root, "ConnectAccess", m_connectList.GetEnumerator ());
  189. if (this.m_acceptList.Count > 0)
  190. ToXml (root, "AcceptAccess", m_acceptList.GetEnumerator ());
  191. return root;
  192. }
  193. private void ToXml (SecurityElement root, string childName, IEnumerator enumerator)
  194. {
  195. SecurityElement child = new SecurityElement (childName);
  196. while (enumerator.MoveNext ()) {
  197. EndpointPermission perm = enumerator.Current as EndpointPermission;
  198. SecurityElement grandchild = new SecurityElement ("ENDPOINT");
  199. grandchild.AddAttribute ("host", perm.Hostname);
  200. grandchild.AddAttribute ("transport", perm.Transport.ToString ());
  201. grandchild.AddAttribute ("port",
  202. perm.Port == AllPorts
  203. ? "All"
  204. : ((Int32) perm.Port).ToString ());
  205. child.AddChild (grandchild);
  206. }
  207. root.AddChild (child);
  208. }
  209. public override void FromXml (SecurityElement securityElement)
  210. {
  211. if (securityElement == null)
  212. throw new ArgumentNullException ("securityElement");
  213. // LAMESPEC: it says to throw an ArgumentNullException in this case
  214. if (securityElement.Tag != "IPermission")
  215. throw new ArgumentException ("securityElement");
  216. string classStr = securityElement.Attribute ("class");
  217. if (classStr == null || !classStr.StartsWith (this.GetType ().FullName + ","))
  218. throw new ArgumentException ("securityElement");
  219. string unrestricted = securityElement.Attribute ("Unrestricted");
  220. if (unrestricted != null) {
  221. this.m_noRestriction = (String.Compare (unrestricted, "true", true) == 0);
  222. if (this.m_noRestriction)
  223. return;
  224. }
  225. this.m_noRestriction = false;
  226. this.m_connectList = new ArrayList ();
  227. this.m_acceptList = new ArrayList ();
  228. ArrayList children = securityElement.Children;
  229. foreach (SecurityElement child in children) {
  230. if (child.Tag == "ConnectAccess")
  231. FromXml (child.Children, NetworkAccess.Connect);
  232. else if (child.Tag == "AcceptAccess")
  233. FromXml (child.Children, NetworkAccess.Accept);
  234. }
  235. }
  236. private void FromXml (ArrayList endpoints, NetworkAccess access)
  237. {
  238. foreach (SecurityElement endpoint in endpoints) {
  239. if (endpoint.Tag != "ENDPOINT")
  240. continue;
  241. string hostname = endpoint.Attribute ("host");
  242. TransportType transport =
  243. (TransportType) Enum.Parse (typeof (TransportType),
  244. endpoint.Attribute ("transport"),
  245. true);
  246. string p = endpoint.Attribute ("port");
  247. int port = 0;
  248. if (p == "All")
  249. port = SocketPermission.AllPorts;
  250. else
  251. port = Int32.Parse (p);
  252. AddPermission (access, transport, hostname, port);
  253. }
  254. }
  255. public override IPermission Union (IPermission target)
  256. {
  257. // LAMESPEC: according to spec we should throw an
  258. // exception when target is null. We'll follow the
  259. // behaviour of MS.Net instead of the spec, also
  260. // because it matches the Intersect behaviour.
  261. if (target == null)
  262. return null;
  263. // throw new ArgumentNullException ("target");
  264. SocketPermission perm = target as SocketPermission;
  265. if (perm == null)
  266. throw new ArgumentException ("Argument not of type SocketPermission");
  267. if (this.m_noRestriction || perm.m_noRestriction)
  268. return new SocketPermission (PermissionState.Unrestricted);
  269. SocketPermission copy = (SocketPermission) perm.Copy ();
  270. copy.m_acceptList.InsertRange (copy.m_acceptList.Count, this.m_acceptList);
  271. copy.m_connectList.InsertRange (copy.m_connectList.Count, this.m_connectList);
  272. return copy;
  273. }
  274. }
  275. }