PageRenderTime 172ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/tools/security/permview.cs

https://github.com/hollow87/mono
C# | 411 lines | 327 code | 69 blank | 15 comment | 58 complexity | c3478b6a0346eb5411c07baa000dfb07 MD5 | raw file
  1. //
  2. // permview.cs: Managed Permission Viewer for .NET assemblies
  3. //
  4. // Author:
  5. // Sebastien Pouliot <sebastien@ximian.com>
  6. //
  7. // Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Collections.Generic;
  12. using System.IO;
  13. using System.Reflection;
  14. using System.Security;
  15. using SSP = System.Security.Permissions;
  16. using System.Text;
  17. using Mono.Cecil;
  18. [assembly: AssemblyTitle ("Mono PermView")]
  19. [assembly: AssemblyDescription ("Managed Permission Viewer for .NET assemblies")]
  20. namespace Mono.Tools {
  21. static class SecurityDeclarationRocks {
  22. public static PermissionSet ToPermissionSet (this SecurityDeclaration self)
  23. {
  24. if (self == null)
  25. throw new ArgumentNullException ("self");
  26. PermissionSet set;
  27. if (TryProcessPermissionSetAttribute (self, out set))
  28. return set;
  29. return CreatePermissionSet (self);
  30. }
  31. static bool TryProcessPermissionSetAttribute (SecurityDeclaration declaration, out PermissionSet set)
  32. {
  33. set = null;
  34. if (!declaration.HasSecurityAttributes && declaration.SecurityAttributes.Count != 1)
  35. return false;
  36. var security_attribute = declaration.SecurityAttributes [0];
  37. var attribute_type = security_attribute.AttributeType;
  38. if (attribute_type.Name != "PermissionSetAttribute" || attribute_type.Namespace != "System.Security.Permissions")
  39. return false;
  40. var named_argument = security_attribute.Properties [0];
  41. if (named_argument.Name != "XML")
  42. throw new NotSupportedException ();
  43. var attribute = new SSP.PermissionSetAttribute ((SSP.SecurityAction) declaration.Action);
  44. attribute.XML = (string) named_argument.Argument.Value;
  45. set = attribute.CreatePermissionSet ();
  46. return true;
  47. }
  48. static PermissionSet CreatePermissionSet (SecurityDeclaration declaration)
  49. {
  50. var set = new PermissionSet (SSP.PermissionState.None);
  51. foreach (var attribute in declaration.SecurityAttributes) {
  52. var permission = CreatePermission (declaration, attribute);
  53. set.AddPermission (permission);
  54. }
  55. return set;
  56. }
  57. static IPermission CreatePermission (SecurityDeclaration declaration, SecurityAttribute attribute)
  58. {
  59. var attribute_type = Type.GetType (attribute.AttributeType.FullName);
  60. if (attribute_type == null)
  61. throw new ArgumentException ();
  62. var security_attribute = CreateSecurityAttribute (attribute_type, declaration);
  63. if (security_attribute == null)
  64. throw new InvalidOperationException ();
  65. CompleteSecurityAttribute (security_attribute, attribute);
  66. return security_attribute.CreatePermission ();
  67. }
  68. static void CompleteSecurityAttribute (SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)
  69. {
  70. if (attribute.HasFields)
  71. CompleteSecurityAttributeFields (security_attribute, attribute);
  72. if (attribute.HasProperties)
  73. CompleteSecurityAttributeProperties (security_attribute, attribute);
  74. }
  75. static void CompleteSecurityAttributeFields (SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)
  76. {
  77. var type = security_attribute.GetType ();
  78. foreach (var named_argument in attribute.Fields)
  79. type.GetField (named_argument.Name).SetValue (security_attribute, named_argument.Argument.Value);
  80. }
  81. static void CompleteSecurityAttributeProperties (SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)
  82. {
  83. var type = security_attribute.GetType ();
  84. foreach (var named_argument in attribute.Properties)
  85. type.GetProperty (named_argument.Name).SetValue (security_attribute, named_argument.Argument.Value, null);
  86. }
  87. static SSP.SecurityAttribute CreateSecurityAttribute (Type attribute_type, SecurityDeclaration declaration)
  88. {
  89. SSP.SecurityAttribute security_attribute;
  90. try {
  91. security_attribute = (SSP.SecurityAttribute) Activator.CreateInstance (
  92. attribute_type, new object [] { (SSP.SecurityAction) declaration.Action });
  93. } catch (MissingMethodException) {
  94. security_attribute = (SSP.SecurityAttribute) Activator.CreateInstance (attribute_type, new object [0]);
  95. }
  96. return security_attribute;
  97. }
  98. }
  99. class SecurityElementComparer : IComparer {
  100. public int Compare (object x, object y)
  101. {
  102. SecurityElement sx = (x as SecurityElement);
  103. SecurityElement sy = (y as SecurityElement);
  104. if (sx == null)
  105. return (sy == null) ? 0 : -1;
  106. else if (sy == null)
  107. return 1;
  108. // compare by name (type name, method name, action name)
  109. return String.Compare (sx.Attribute ("Name"), sy.Attribute ("Name"));
  110. }
  111. }
  112. class PermView {
  113. private const string NotSpecified = "\tNot specified.";
  114. static private void Help ()
  115. {
  116. Console.WriteLine ("Usage: permview [options] assembly{0}", Environment.NewLine);
  117. Console.WriteLine ("where options are:");
  118. Console.WriteLine (" -output filename Output information into specified file.");
  119. Console.WriteLine (" -decl Show declarative security attributes on classes and methods.");
  120. Console.WriteLine (" -xml Output in XML format");
  121. Console.WriteLine (" -help Show help informations (this text)");
  122. Console.WriteLine ();
  123. }
  124. static bool declarative = false;
  125. static bool xmloutput = false;
  126. static TextWriter ProcessOptions (string[] args)
  127. {
  128. TextWriter tw = Console.Out;
  129. for (int i=0; i < args.Length - 1; i++) {
  130. switch (args [i].ToUpper ()) {
  131. case "/DECL":
  132. case "-DECL":
  133. case "--DECL":
  134. declarative = true;
  135. break;
  136. case "/OUTPUT":
  137. case "-OUTPUT":
  138. case "--OUTPUT":
  139. tw = (TextWriter) new StreamWriter (args [++i]);
  140. break;
  141. case "/XML":
  142. case "-XML":
  143. case "--XML":
  144. xmloutput = true;
  145. break;
  146. case "/HELP":
  147. case "/H":
  148. case "-HELP":
  149. case "-H":
  150. case "--HELP":
  151. case "--H":
  152. case "-?":
  153. case "--?":
  154. Help ();
  155. return null;
  156. }
  157. }
  158. return tw;
  159. }
  160. static bool ProcessAssemblyOnly (TextWriter tw, AssemblyDefinition ad)
  161. {
  162. bool result = true;
  163. string minimal = NotSpecified + Environment.NewLine;
  164. string optional = NotSpecified + Environment.NewLine;
  165. string refused = NotSpecified + Environment.NewLine;
  166. foreach (SecurityDeclaration decl in ad.SecurityDeclarations) {
  167. switch (decl.Action) {
  168. case Mono.Cecil.SecurityAction.RequestMinimum:
  169. minimal = decl.ToPermissionSet ().ToString ();
  170. break;
  171. case Mono.Cecil.SecurityAction.RequestOptional:
  172. optional = decl.ToPermissionSet ().ToString ();
  173. break;
  174. case Mono.Cecil.SecurityAction.RequestRefuse:
  175. refused = decl.ToPermissionSet ().ToString ();
  176. break;
  177. default:
  178. tw.WriteLine ("Invalid assembly level declaration {0}{1}{2}",
  179. decl.Action, Environment.NewLine, decl.ToPermissionSet ());
  180. result = false;
  181. break;
  182. }
  183. }
  184. tw.WriteLine ("Minimal Permission Set:");
  185. tw.WriteLine (minimal);
  186. tw.WriteLine ("Optional Permission Set:");
  187. tw.WriteLine (optional);
  188. tw.WriteLine ("Refused Permission Set:");
  189. tw.WriteLine (refused);
  190. return result;
  191. }
  192. static void ShowSecurity (TextWriter tw, string header, IEnumerable<SecurityDeclaration> declarations)
  193. {
  194. foreach (SecurityDeclaration declsec in declarations) {
  195. tw.WriteLine ("{0} {1} Permission Set:{2}{3}", header,
  196. declsec.Action, Environment.NewLine, declsec.ToPermissionSet ());
  197. }
  198. }
  199. static bool ProcessAssemblyComplete (TextWriter tw, AssemblyDefinition ad)
  200. {
  201. if (ad.SecurityDeclarations.Count > 0) {
  202. ShowSecurity (tw, "Assembly", ad.SecurityDeclarations);
  203. }
  204. foreach (ModuleDefinition module in ad.Modules) {
  205. foreach (TypeDefinition type in module.Types) {
  206. if (type.SecurityDeclarations.Count > 0) {
  207. ShowSecurity (tw, "Class " + type.ToString (), ad.SecurityDeclarations);
  208. }
  209. foreach (MethodDefinition method in type.Methods) {
  210. if (method.SecurityDeclarations.Count > 0) {
  211. ShowSecurity (tw, "Method " + method.ToString (), method.SecurityDeclarations);
  212. }
  213. }
  214. }
  215. }
  216. return true;
  217. }
  218. static void AddAttribute (SecurityElement se, string attr, string value)
  219. {
  220. value = value.Replace ("&", "&amp;");
  221. se.AddAttribute (attr, value);
  222. }
  223. static SecurityElement AddSecurityXml (IEnumerable<SecurityDeclaration> declarations)
  224. {
  225. ArrayList list = new ArrayList ();
  226. foreach (SecurityDeclaration declsec in declarations) {
  227. SecurityElement child = new SecurityElement ("Action");
  228. AddAttribute (child, "Name", declsec.Action.ToString ());
  229. child.AddChild (declsec.ToPermissionSet ().ToXml ());
  230. list.Add (child);
  231. }
  232. // sort actions
  233. list.Sort (Comparer);
  234. SecurityElement se = new SecurityElement ("Actions");
  235. foreach (SecurityElement child in list) {
  236. se.AddChild (child);
  237. }
  238. return se;
  239. }
  240. static SecurityElementComparer comparer;
  241. static IComparer Comparer {
  242. get {
  243. if (comparer == null)
  244. comparer = new SecurityElementComparer ();
  245. return comparer;
  246. }
  247. }
  248. static bool ProcessAssemblyXml (TextWriter tw, AssemblyDefinition ad)
  249. {
  250. SecurityElement se = new SecurityElement ("Assembly");
  251. se.AddAttribute ("Name", ad.Name.FullName);
  252. if (ad.SecurityDeclarations.Count > 0) {
  253. se.AddChild (AddSecurityXml (ad.SecurityDeclarations));
  254. }
  255. ArrayList tlist = new ArrayList ();
  256. ArrayList mlist = new ArrayList ();
  257. foreach (ModuleDefinition module in ad.Modules) {
  258. foreach (TypeDefinition type in module.Types) {
  259. SecurityElement klass = new SecurityElement ("Class");
  260. SecurityElement methods = new SecurityElement ("Methods");
  261. SecurityElement typelem = null;
  262. if (type.SecurityDeclarations.Count > 0) {
  263. typelem = AddSecurityXml (type.SecurityDeclarations);
  264. }
  265. if (mlist.Count > 0)
  266. mlist.Clear ();
  267. foreach (MethodDefinition method in type.Methods) {
  268. if (method.SecurityDeclarations.Count > 0) {
  269. SecurityElement meth = new SecurityElement ("Method");
  270. AddAttribute (meth, "Name", method.ToString ());
  271. meth.AddChild (AddSecurityXml (method.SecurityDeclarations));
  272. mlist.Add (meth);
  273. }
  274. }
  275. // sort methods
  276. mlist.Sort (Comparer);
  277. foreach (SecurityElement method in mlist) {
  278. methods.AddChild (method);
  279. }
  280. if ((typelem != null) || ((methods.Children != null) && (methods.Children.Count > 0))) {
  281. AddAttribute (klass, "Name", type.ToString ());
  282. if (typelem != null)
  283. klass.AddChild (typelem);
  284. if ((methods.Children != null) && (methods.Children.Count > 0))
  285. klass.AddChild (methods);
  286. tlist.Add (klass);
  287. }
  288. }
  289. // sort types
  290. tlist.Sort (Comparer);
  291. foreach (SecurityElement type in tlist) {
  292. se.AddChild (type);
  293. }
  294. }
  295. tw.WriteLine (se.ToString ());
  296. return true;
  297. }
  298. [STAThread]
  299. static int Main (string[] args)
  300. {
  301. try {
  302. Console.WriteLine (new AssemblyInfo ().ToString ());
  303. if (args.Length == 0) {
  304. Help ();
  305. return 0;
  306. }
  307. TextWriter tw = ProcessOptions (args);
  308. if (tw == null)
  309. return 0;
  310. string assemblyName = args [args.Length - 1];
  311. AssemblyDefinition ad = AssemblyDefinition.ReadAssembly (assemblyName);
  312. if (ad != null) {
  313. bool complete = false;
  314. if (declarative) {
  315. // full output (assembly+classes+methods)
  316. complete = ProcessAssemblyComplete (tw, ad);
  317. } else if (xmloutput) {
  318. // full output in XML (for easier diffs after c14n)
  319. complete = ProcessAssemblyXml (tw, ad);
  320. } else {
  321. // default (assembly only)
  322. complete = ProcessAssemblyOnly (tw, ad);
  323. }
  324. if (!complete) {
  325. Console.Error.WriteLine ("Couldn't reflect informations.");
  326. return 1;
  327. }
  328. } else {
  329. Console.Error.WriteLine ("Couldn't load assembly '{0}'.", assemblyName);
  330. return 2;
  331. }
  332. tw.Close ();
  333. }
  334. catch (Exception e) {
  335. Console.Error.WriteLine ("Error: " + e.ToString ());
  336. Help ();
  337. return 3;
  338. }
  339. return 0;
  340. }
  341. }
  342. }