2 // permview.cs: Managed Permission Viewer for .NET assemblies
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
11 using System
.Collections
;
13 using System
.Reflection
;
14 using System
.Security
;
15 using System
.Security
.Permissions
;
20 [assembly
: AssemblyTitle ("Mono PermView")]
21 [assembly
: AssemblyDescription ("Managed Permission Viewer for .NET assemblies")]
23 namespace Mono
.Tools
{
25 class SecurityElementComparer
: IComparer
{
27 public int Compare (object x
, object y
)
29 SecurityElement sx
= (x
as SecurityElement
);
30 SecurityElement sy
= (y
as SecurityElement
);
32 return (sy
== null) ? 0 : -1;
36 // compare by name (type name, method name, action name)
37 return String
.Compare (sx
.Attribute ("Name"), sy
.Attribute ("Name"));
43 private const string NotSpecified
= "\tNot specified.";
45 static private void Help ()
47 Console
.WriteLine ("Usage: permview [options] assembly{0}", Environment
.NewLine
);
48 Console
.WriteLine ("where options are:");
49 Console
.WriteLine (" -output filename Output information into specified file.");
50 Console
.WriteLine (" -decl Show declarative security attributes on classes and methods.");
51 Console
.WriteLine (" -xml Output in XML format");
52 Console
.WriteLine (" -help Show help informations (this text)");
56 static bool declarative
= false;
57 static bool xmloutput
= false;
59 static TextWriter
ProcessOptions (string[] args
)
61 TextWriter tw
= Console
.Out
;
62 for (int i
=0; i
< args
.Length
- 1; i
++) {
63 switch (args
[i
].ToUpper ()) {
72 tw
= (TextWriter
) new StreamWriter (args
[++i
]);
94 static bool ProcessAssemblyOnly (TextWriter tw
, AssemblyDefinition ad
)
97 string minimal
= NotSpecified
+ Environment
.NewLine
;
98 string optional
= NotSpecified
+ Environment
.NewLine
;
99 string refused
= NotSpecified
+ Environment
.NewLine
;
101 foreach (SecurityDeclaration decl
in ad
.SecurityDeclarations
) {
102 switch (decl
.Action
) {
103 case Mono
.Cecil
.SecurityAction
.RequestMinimum
:
104 minimal
= decl
.PermissionSet
.ToString ();
106 case Mono
.Cecil
.SecurityAction
.RequestOptional
:
107 optional
= decl
.PermissionSet
.ToString ();
109 case Mono
.Cecil
.SecurityAction
.RequestRefuse
:
110 refused
= decl
.PermissionSet
.ToString ();
113 tw
.WriteLine ("Invalid assembly level declaration {0}{1}{2}",
114 decl
.Action
, Environment
.NewLine
, decl
.PermissionSet
);
120 tw
.WriteLine ("Minimal Permission Set:");
121 tw
.WriteLine (minimal
);
122 tw
.WriteLine ("Optional Permission Set:");
123 tw
.WriteLine (optional
);
124 tw
.WriteLine ("Refused Permission Set:");
125 tw
.WriteLine (refused
);
129 static void ShowSecurity (TextWriter tw
, string header
, SecurityDeclarationCollection declarations
)
131 foreach (SecurityDeclaration declsec
in declarations
) {
132 tw
.WriteLine ("{0} {1} Permission Set:{2}{3}", header
,
133 declsec
.Action
, Environment
.NewLine
, declsec
.PermissionSet
);
137 static bool ProcessAssemblyComplete (TextWriter tw
, AssemblyDefinition ad
)
139 if (ad
.SecurityDeclarations
.Count
> 0) {
140 ShowSecurity (tw
, "Assembly", ad
.SecurityDeclarations
);
143 foreach (ModuleDefinition module
in ad
.Modules
) {
145 foreach (TypeDefinition type
in module
.Types
) {
147 if (type
.SecurityDeclarations
.Count
> 0) {
148 ShowSecurity (tw
, "Class " + type
.ToString (), ad
.SecurityDeclarations
);
151 foreach (MethodDefinition method
in type
.Methods
) {
152 if (method
.SecurityDeclarations
.Count
> 0) {
153 ShowSecurity (tw
, "Method " + method
.ToString (), method
.SecurityDeclarations
);
161 static void AddAttribute (SecurityElement se
, string attr
, string value)
163 value = value.Replace ("&", "&");
164 se
.AddAttribute (attr
, value);
167 static SecurityElement
AddSecurityXml (SecurityDeclarationCollection declarations
)
169 ArrayList list
= new ArrayList ();
170 foreach (SecurityDeclaration declsec
in declarations
) {
171 SecurityElement child
= new SecurityElement ("Action");
172 AddAttribute (child
, "Name", declsec
.Action
.ToString ());
173 child
.AddChild (declsec
.PermissionSet
.ToXml ());
177 list
.Sort (Comparer
);
179 SecurityElement se
= new SecurityElement ("Actions");
180 foreach (SecurityElement child
in list
) {
186 static SecurityElementComparer comparer
;
187 static IComparer Comparer
{
189 if (comparer
== null)
190 comparer
= new SecurityElementComparer ();
195 static bool ProcessAssemblyXml (TextWriter tw
, AssemblyDefinition ad
)
197 SecurityElement se
= new SecurityElement ("Assembly");
198 se
.AddAttribute ("Name", ad
.Name
.FullName
);
200 if (ad
.SecurityDeclarations
.Count
> 0) {
201 se
.AddChild (AddSecurityXml (ad
.SecurityDeclarations
));
204 ArrayList tlist
= new ArrayList ();
205 ArrayList mlist
= new ArrayList ();
207 foreach (ModuleDefinition module
in ad
.Modules
) {
209 foreach (TypeDefinition type
in module
.Types
) {
211 SecurityElement klass
= new SecurityElement ("Class");
212 SecurityElement methods
= new SecurityElement ("Methods");
214 SecurityElement typelem
= null;
215 if (type
.SecurityDeclarations
.Count
> 0) {
216 typelem
= AddSecurityXml (type
.SecurityDeclarations
);
222 foreach (MethodDefinition method
in type
.Methods
) {
223 if (method
.SecurityDeclarations
.Count
> 0) {
224 SecurityElement meth
= new SecurityElement ("Method");
225 AddAttribute (meth
, "Name", method
.ToString ());
226 meth
.AddChild (AddSecurityXml (method
.SecurityDeclarations
));
232 mlist
.Sort (Comparer
);
233 foreach (SecurityElement method
in mlist
) {
234 methods
.AddChild (method
);
237 if ((typelem
!= null) || ((methods
.Children
!= null) && (methods
.Children
.Count
> 0))) {
238 AddAttribute (klass
, "Name", type
.ToString ());
240 klass
.AddChild (typelem
);
241 if ((methods
.Children
!= null) && (methods
.Children
.Count
> 0))
242 klass
.AddChild (methods
);
248 tlist
.Sort (Comparer
);
249 foreach (SecurityElement type
in tlist
) {
254 tw
.WriteLine (se
.ToString ());
259 static int Main (string[] args
)
262 Console
.WriteLine (new AssemblyInfo ().ToString ());
263 if (args
.Length
== 0) {
268 TextWriter tw
= ProcessOptions (args
);
272 string assemblyName
= args
[args
.Length
- 1];
273 AssemblyDefinition ad
= AssemblyFactory
.GetAssembly (assemblyName
);
275 bool complete
= false;
278 // full output (assembly+classes+methods)
279 complete
= ProcessAssemblyComplete (tw
, ad
);
280 } else if (xmloutput
) {
281 // full output in XML (for easier diffs after c14n)
282 complete
= ProcessAssemblyXml (tw
, ad
);
284 // default (assembly only)
285 complete
= ProcessAssemblyOnly (tw
, ad
);
289 Console
.Error
.WriteLine ("Couldn't reflect informations.");
293 Console
.Error
.WriteLine ("Couldn't load assembly '{0}'.", assemblyName
);
298 catch (Exception e
) {
299 Console
.Error
.WriteLine ("Error: " + e
.ToString ());