202 lines
4.6 KiB
C#
202 lines
4.6 KiB
C#
|
//
|
||
|
// Author:
|
||
|
// Jb Evain (jbevain@gmail.com)
|
||
|
//
|
||
|
// Copyright (c) 2008 - 2015 Jb Evain
|
||
|
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||
|
//
|
||
|
// Licensed under the MIT/X11 license.
|
||
|
//
|
||
|
|
||
|
using MonoFN.Collections.Generic;
|
||
|
using System;
|
||
|
using System.Diagnostics;
|
||
|
using System.Threading;
|
||
|
|
||
|
namespace MonoFN.Cecil {
|
||
|
|
||
|
public enum SecurityAction : ushort {
|
||
|
Request = 1,
|
||
|
Demand = 2,
|
||
|
Assert = 3,
|
||
|
Deny = 4,
|
||
|
PermitOnly = 5,
|
||
|
LinkDemand = 6,
|
||
|
InheritDemand = 7,
|
||
|
RequestMinimum = 8,
|
||
|
RequestOptional = 9,
|
||
|
RequestRefuse = 10,
|
||
|
PreJitGrant = 11,
|
||
|
PreJitDeny = 12,
|
||
|
NonCasDemand = 13,
|
||
|
NonCasLinkDemand = 14,
|
||
|
NonCasInheritance = 15
|
||
|
}
|
||
|
|
||
|
public interface ISecurityDeclarationProvider : IMetadataTokenProvider {
|
||
|
|
||
|
bool HasSecurityDeclarations { get; }
|
||
|
Collection<SecurityDeclaration> SecurityDeclarations { get; }
|
||
|
}
|
||
|
|
||
|
[DebuggerDisplay ("{AttributeType}")]
|
||
|
public sealed class SecurityAttribute : ICustomAttribute {
|
||
|
|
||
|
TypeReference attribute_type;
|
||
|
|
||
|
internal Collection<CustomAttributeNamedArgument> fields;
|
||
|
internal Collection<CustomAttributeNamedArgument> properties;
|
||
|
|
||
|
public TypeReference AttributeType {
|
||
|
get { return attribute_type; }
|
||
|
set { attribute_type = value; }
|
||
|
}
|
||
|
|
||
|
public bool HasFields {
|
||
|
get { return !fields.IsNullOrEmpty (); }
|
||
|
}
|
||
|
|
||
|
public Collection<CustomAttributeNamedArgument> Fields {
|
||
|
get {
|
||
|
if (fields == null)
|
||
|
Interlocked.CompareExchange (ref fields, new Collection<CustomAttributeNamedArgument> (), null);
|
||
|
|
||
|
return fields;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool HasProperties {
|
||
|
get { return !properties.IsNullOrEmpty (); }
|
||
|
}
|
||
|
|
||
|
public Collection<CustomAttributeNamedArgument> Properties {
|
||
|
get {
|
||
|
if (properties == null)
|
||
|
Interlocked.CompareExchange (ref properties, new Collection<CustomAttributeNamedArgument> (), null);
|
||
|
|
||
|
return properties;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public SecurityAttribute (TypeReference attributeType)
|
||
|
{
|
||
|
this.attribute_type = attributeType;
|
||
|
}
|
||
|
|
||
|
bool ICustomAttribute.HasConstructorArguments {
|
||
|
get { return false; }
|
||
|
}
|
||
|
|
||
|
Collection<CustomAttributeArgument> ICustomAttribute.ConstructorArguments {
|
||
|
get { throw new NotSupportedException (); }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public sealed class SecurityDeclaration {
|
||
|
|
||
|
readonly internal uint signature;
|
||
|
byte [] blob;
|
||
|
readonly ModuleDefinition module;
|
||
|
|
||
|
internal bool resolved;
|
||
|
SecurityAction action;
|
||
|
internal Collection<SecurityAttribute> security_attributes;
|
||
|
|
||
|
public SecurityAction Action {
|
||
|
get { return action; }
|
||
|
set { action = value; }
|
||
|
}
|
||
|
|
||
|
public bool HasSecurityAttributes {
|
||
|
get {
|
||
|
Resolve ();
|
||
|
|
||
|
return !security_attributes.IsNullOrEmpty ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Collection<SecurityAttribute> SecurityAttributes {
|
||
|
get {
|
||
|
Resolve ();
|
||
|
|
||
|
if (security_attributes == null)
|
||
|
Interlocked.CompareExchange (ref security_attributes, new Collection<SecurityAttribute> (), null);
|
||
|
|
||
|
return security_attributes;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal bool HasImage {
|
||
|
get { return module != null && module.HasImage; }
|
||
|
}
|
||
|
|
||
|
internal SecurityDeclaration (SecurityAction action, uint signature, ModuleDefinition module)
|
||
|
{
|
||
|
this.action = action;
|
||
|
this.signature = signature;
|
||
|
this.module = module;
|
||
|
}
|
||
|
|
||
|
public SecurityDeclaration (SecurityAction action)
|
||
|
{
|
||
|
this.action = action;
|
||
|
this.resolved = true;
|
||
|
}
|
||
|
|
||
|
public SecurityDeclaration (SecurityAction action, byte [] blob)
|
||
|
{
|
||
|
this.action = action;
|
||
|
this.resolved = false;
|
||
|
this.blob = blob;
|
||
|
}
|
||
|
|
||
|
public byte [] GetBlob ()
|
||
|
{
|
||
|
if (blob != null)
|
||
|
return blob;
|
||
|
|
||
|
if (!HasImage || signature == 0)
|
||
|
throw new NotSupportedException ();
|
||
|
|
||
|
return module.Read (ref blob, this, (declaration, reader) => reader.ReadSecurityDeclarationBlob (declaration.signature));
|
||
|
}
|
||
|
|
||
|
void Resolve ()
|
||
|
{
|
||
|
if (resolved || !HasImage)
|
||
|
return;
|
||
|
|
||
|
lock (module.SyncRoot) {
|
||
|
|
||
|
if (resolved)
|
||
|
return;
|
||
|
|
||
|
module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationSignature (declaration));
|
||
|
resolved = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static partial class Mixin {
|
||
|
|
||
|
public static bool GetHasSecurityDeclarations (
|
||
|
this ISecurityDeclarationProvider self,
|
||
|
ModuleDefinition module)
|
||
|
{
|
||
|
return module.HasImage () && module.Read (self, (provider, reader) => reader.HasSecurityDeclarations (provider));
|
||
|
}
|
||
|
|
||
|
public static Collection<SecurityDeclaration> GetSecurityDeclarations (
|
||
|
this ISecurityDeclarationProvider self,
|
||
|
ref Collection<SecurityDeclaration> variable,
|
||
|
ModuleDefinition module)
|
||
|
{
|
||
|
if (module.HasImage)
|
||
|
return module.Read (ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations (provider));
|
||
|
|
||
|
Interlocked.CompareExchange (ref variable, new Collection<SecurityDeclaration> (), null);
|
||
|
return variable;
|
||
|
}
|
||
|
}
|
||
|
}
|