/mcs/tools/security/permview.cs
C# | 411 lines | 327 code | 69 blank | 15 comment | 58 complexity | c3478b6a0346eb5411c07baa000dfb07 MD5 | raw file
- //
- // permview.cs: Managed Permission Viewer for .NET assemblies
- //
- // Author:
- // Sebastien Pouliot <sebastien@ximian.com>
- //
- // Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
- //
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Reflection;
- using System.Security;
- using SSP = System.Security.Permissions;
- using System.Text;
- using Mono.Cecil;
- [assembly: AssemblyTitle ("Mono PermView")]
- [assembly: AssemblyDescription ("Managed Permission Viewer for .NET assemblies")]
- namespace Mono.Tools {
- static class SecurityDeclarationRocks {
- public static PermissionSet ToPermissionSet (this SecurityDeclaration self)
- {
- if (self == null)
- throw new ArgumentNullException ("self");
- PermissionSet set;
- if (TryProcessPermissionSetAttribute (self, out set))
- return set;
- return CreatePermissionSet (self);
- }
- static bool TryProcessPermissionSetAttribute (SecurityDeclaration declaration, out PermissionSet set)
- {
- set = null;
- if (!declaration.HasSecurityAttributes && declaration.SecurityAttributes.Count != 1)
- return false;
- var security_attribute = declaration.SecurityAttributes [0];
- var attribute_type = security_attribute.AttributeType;
- if (attribute_type.Name != "PermissionSetAttribute" || attribute_type.Namespace != "System.Security.Permissions")
- return false;
- var named_argument = security_attribute.Properties [0];
- if (named_argument.Name != "XML")
- throw new NotSupportedException ();
- var attribute = new SSP.PermissionSetAttribute ((SSP.SecurityAction) declaration.Action);
- attribute.XML = (string) named_argument.Argument.Value;
- set = attribute.CreatePermissionSet ();
- return true;
- }
- static PermissionSet CreatePermissionSet (SecurityDeclaration declaration)
- {
- var set = new PermissionSet (SSP.PermissionState.None);
- foreach (var attribute in declaration.SecurityAttributes) {
- var permission = CreatePermission (declaration, attribute);
- set.AddPermission (permission);
- }
- return set;
- }
- static IPermission CreatePermission (SecurityDeclaration declaration, SecurityAttribute attribute)
- {
- var attribute_type = Type.GetType (attribute.AttributeType.FullName);
- if (attribute_type == null)
- throw new ArgumentException ();
- var security_attribute = CreateSecurityAttribute (attribute_type, declaration);
- if (security_attribute == null)
- throw new InvalidOperationException ();
- CompleteSecurityAttribute (security_attribute, attribute);
- return security_attribute.CreatePermission ();
- }
- static void CompleteSecurityAttribute (SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)
- {
- if (attribute.HasFields)
- CompleteSecurityAttributeFields (security_attribute, attribute);
- if (attribute.HasProperties)
- CompleteSecurityAttributeProperties (security_attribute, attribute);
- }
- static void CompleteSecurityAttributeFields (SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)
- {
- var type = security_attribute.GetType ();
- foreach (var named_argument in attribute.Fields)
- type.GetField (named_argument.Name).SetValue (security_attribute, named_argument.Argument.Value);
- }
- static void CompleteSecurityAttributeProperties (SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)
- {
- var type = security_attribute.GetType ();
- foreach (var named_argument in attribute.Properties)
- type.GetProperty (named_argument.Name).SetValue (security_attribute, named_argument.Argument.Value, null);
- }
- static SSP.SecurityAttribute CreateSecurityAttribute (Type attribute_type, SecurityDeclaration declaration)
- {
- SSP.SecurityAttribute security_attribute;
- try {
- security_attribute = (SSP.SecurityAttribute) Activator.CreateInstance (
- attribute_type, new object [] { (SSP.SecurityAction) declaration.Action });
- } catch (MissingMethodException) {
- security_attribute = (SSP.SecurityAttribute) Activator.CreateInstance (attribute_type, new object [0]);
- }
- return security_attribute;
- }
- }
- class SecurityElementComparer : IComparer {
- public int Compare (object x, object y)
- {
- SecurityElement sx = (x as SecurityElement);
- SecurityElement sy = (y as SecurityElement);
- if (sx == null)
- return (sy == null) ? 0 : -1;
- else if (sy == null)
- return 1;
- // compare by name (type name, method name, action name)
- return String.Compare (sx.Attribute ("Name"), sy.Attribute ("Name"));
- }
- }
- class PermView {
- private const string NotSpecified = "\tNot specified.";
- static private void Help ()
- {
- Console.WriteLine ("Usage: permview [options] assembly{0}", Environment.NewLine);
- Console.WriteLine ("where options are:");
- Console.WriteLine (" -output filename Output information into specified file.");
- Console.WriteLine (" -decl Show declarative security attributes on classes and methods.");
- Console.WriteLine (" -xml Output in XML format");
- Console.WriteLine (" -help Show help informations (this text)");
- Console.WriteLine ();
- }
- static bool declarative = false;
- static bool xmloutput = false;
- static TextWriter ProcessOptions (string[] args)
- {
- TextWriter tw = Console.Out;
- for (int i=0; i < args.Length - 1; i++) {
- switch (args [i].ToUpper ()) {
- case "/DECL":
- case "-DECL":
- case "--DECL":
- declarative = true;
- break;
- case "/OUTPUT":
- case "-OUTPUT":
- case "--OUTPUT":
- tw = (TextWriter) new StreamWriter (args [++i]);
- break;
- case "/XML":
- case "-XML":
- case "--XML":
- xmloutput = true;
- break;
- case "/HELP":
- case "/H":
- case "-HELP":
- case "-H":
- case "--HELP":
- case "--H":
- case "-?":
- case "--?":
- Help ();
- return null;
- }
- }
- return tw;
- }
- static bool ProcessAssemblyOnly (TextWriter tw, AssemblyDefinition ad)
- {
- bool result = true;
- string minimal = NotSpecified + Environment.NewLine;
- string optional = NotSpecified + Environment.NewLine;
- string refused = NotSpecified + Environment.NewLine;
- foreach (SecurityDeclaration decl in ad.SecurityDeclarations) {
- switch (decl.Action) {
- case Mono.Cecil.SecurityAction.RequestMinimum:
- minimal = decl.ToPermissionSet ().ToString ();
- break;
- case Mono.Cecil.SecurityAction.RequestOptional:
- optional = decl.ToPermissionSet ().ToString ();
- break;
- case Mono.Cecil.SecurityAction.RequestRefuse:
- refused = decl.ToPermissionSet ().ToString ();
- break;
- default:
- tw.WriteLine ("Invalid assembly level declaration {0}{1}{2}",
- decl.Action, Environment.NewLine, decl.ToPermissionSet ());
- result = false;
- break;
- }
- }
- tw.WriteLine ("Minimal Permission Set:");
- tw.WriteLine (minimal);
- tw.WriteLine ("Optional Permission Set:");
- tw.WriteLine (optional);
- tw.WriteLine ("Refused Permission Set:");
- tw.WriteLine (refused);
- return result;
- }
- static void ShowSecurity (TextWriter tw, string header, IEnumerable<SecurityDeclaration> declarations)
- {
- foreach (SecurityDeclaration declsec in declarations) {
- tw.WriteLine ("{0} {1} Permission Set:{2}{3}", header,
- declsec.Action, Environment.NewLine, declsec.ToPermissionSet ());
- }
- }
- static bool ProcessAssemblyComplete (TextWriter tw, AssemblyDefinition ad)
- {
- if (ad.SecurityDeclarations.Count > 0) {
- ShowSecurity (tw, "Assembly", ad.SecurityDeclarations);
- }
- foreach (ModuleDefinition module in ad.Modules) {
- foreach (TypeDefinition type in module.Types) {
- if (type.SecurityDeclarations.Count > 0) {
- ShowSecurity (tw, "Class " + type.ToString (), ad.SecurityDeclarations);
- }
- foreach (MethodDefinition method in type.Methods) {
- if (method.SecurityDeclarations.Count > 0) {
- ShowSecurity (tw, "Method " + method.ToString (), method.SecurityDeclarations);
- }
- }
- }
- }
- return true;
- }
- static void AddAttribute (SecurityElement se, string attr, string value)
- {
- value = value.Replace ("&", "&");
- se.AddAttribute (attr, value);
- }
- static SecurityElement AddSecurityXml (IEnumerable<SecurityDeclaration> declarations)
- {
- ArrayList list = new ArrayList ();
- foreach (SecurityDeclaration declsec in declarations) {
- SecurityElement child = new SecurityElement ("Action");
- AddAttribute (child, "Name", declsec.Action.ToString ());
- child.AddChild (declsec.ToPermissionSet ().ToXml ());
- list.Add (child);
- }
- // sort actions
- list.Sort (Comparer);
- SecurityElement se = new SecurityElement ("Actions");
- foreach (SecurityElement child in list) {
- se.AddChild (child);
- }
- return se;
- }
- static SecurityElementComparer comparer;
- static IComparer Comparer {
- get {
- if (comparer == null)
- comparer = new SecurityElementComparer ();
- return comparer;
- }
- }
- static bool ProcessAssemblyXml (TextWriter tw, AssemblyDefinition ad)
- {
- SecurityElement se = new SecurityElement ("Assembly");
- se.AddAttribute ("Name", ad.Name.FullName);
- if (ad.SecurityDeclarations.Count > 0) {
- se.AddChild (AddSecurityXml (ad.SecurityDeclarations));
- }
- ArrayList tlist = new ArrayList ();
- ArrayList mlist = new ArrayList ();
- foreach (ModuleDefinition module in ad.Modules) {
- foreach (TypeDefinition type in module.Types) {
- SecurityElement klass = new SecurityElement ("Class");
- SecurityElement methods = new SecurityElement ("Methods");
- SecurityElement typelem = null;
- if (type.SecurityDeclarations.Count > 0) {
- typelem = AddSecurityXml (type.SecurityDeclarations);
- }
- if (mlist.Count > 0)
- mlist.Clear ();
- foreach (MethodDefinition method in type.Methods) {
- if (method.SecurityDeclarations.Count > 0) {
- SecurityElement meth = new SecurityElement ("Method");
- AddAttribute (meth, "Name", method.ToString ());
- meth.AddChild (AddSecurityXml (method.SecurityDeclarations));
- mlist.Add (meth);
- }
- }
- // sort methods
- mlist.Sort (Comparer);
- foreach (SecurityElement method in mlist) {
- methods.AddChild (method);
- }
- if ((typelem != null) || ((methods.Children != null) && (methods.Children.Count > 0))) {
- AddAttribute (klass, "Name", type.ToString ());
- if (typelem != null)
- klass.AddChild (typelem);
- if ((methods.Children != null) && (methods.Children.Count > 0))
- klass.AddChild (methods);
- tlist.Add (klass);
- }
- }
- // sort types
- tlist.Sort (Comparer);
- foreach (SecurityElement type in tlist) {
- se.AddChild (type);
- }
- }
- tw.WriteLine (se.ToString ());
- return true;
- }
- [STAThread]
- static int Main (string[] args)
- {
- try {
- Console.WriteLine (new AssemblyInfo ().ToString ());
- if (args.Length == 0) {
- Help ();
- return 0;
- }
- TextWriter tw = ProcessOptions (args);
- if (tw == null)
- return 0;
- string assemblyName = args [args.Length - 1];
- AssemblyDefinition ad = AssemblyDefinition.ReadAssembly (assemblyName);
- if (ad != null) {
- bool complete = false;
-
- if (declarative) {
- // full output (assembly+classes+methods)
- complete = ProcessAssemblyComplete (tw, ad);
- } else if (xmloutput) {
- // full output in XML (for easier diffs after c14n)
- complete = ProcessAssemblyXml (tw, ad);
- } else {
- // default (assembly only)
- complete = ProcessAssemblyOnly (tw, ad);
- }
- if (!complete) {
- Console.Error.WriteLine ("Couldn't reflect informations.");
- return 1;
- }
- } else {
- Console.Error.WriteLine ("Couldn't load assembly '{0}'.", assemblyName);
- return 2;
- }
- tw.Close ();
- }
- catch (Exception e) {
- Console.Error.WriteLine ("Error: " + e.ToString ());
- Help ();
- return 3;
- }
- return 0;
- }
- }
- }