Skip to main content

Permission

Struct Permission 

pub struct Permission {
    pub class_name: String,
    pub assembly_name: String,
    pub named_arguments: Vec<NamedArgument>,
}
Expand description

Represents a .NET security permission within a permission set.

A Permission represents a single security permission in the .NET Code Access Security (CAS) system. Each permission corresponds to a specific .NET Framework security class that defines access controls for system resources (like file I/O, network access, reflection capabilities, etc.).

§Structure

Each permission contains:

  • Class Name: The fully qualified .NET type name (e.g., “System.Security.Permissions.FileIOPermission”)
  • Assembly Name: The assembly containing the permission class (typically “mscorlib” or “System”)
  • Named Arguments: Collection of property/field configurations specific to the permission type

§Examples

§Creating a File I/O Permission

use dotscope::metadata::security::{Permission, NamedArgument, ArgumentType, ArgumentValue};

let permission = Permission::new(
    "System.Security.Permissions.FileIOPermission".to_string(),
    "mscorlib".to_string(),
    vec![
        NamedArgument::new(
            "Read".to_string(),
            ArgumentType::String,
            ArgumentValue::String("C:\\Data".to_string())
        ),
    ]
);

assert!(permission.is_file_io());

§Analyzing Permission Properties

// Check permission type
if permission.is_file_io() {
    if let Some(paths) = permission.get_file_read_paths() {
        println!("Read access to: {:?}", paths);
    }
}

// Get specific arguments
if let Some(arg) = permission.get_argument("Read") {
    println!("Read argument: {}", arg);
}

§Binary Format Support

Permissions are parsed from DeclSecurity metadata using the binary format defined in ECMA-335. The format includes the permission class name, assembly name, and a variable number of named arguments with their types and values.

§Thread Safety

Permission instances are immutable after creation and safe to share across threads. All accessor methods are read-only and do not modify the internal state.

  • class_name - The full name of the permission class (e.g., “System.Security.Permissions.FileIOPermission”)
  • assembly_name - The assembly containing the permission class (e.g., “mscorlib”)
  • named_arguments - Collection of named property or field settings for this permission

§Notes

In older .NET Framework versions, these permissions were extensively used to control security. While less common in modern .NET, they may still be encountered in legacy assemblies.

Fields§

§class_name: String

The fully qualified .NET type name of the permission class.

Examples include:

  • "System.Security.Permissions.FileIOPermission"
  • "System.Security.Permissions.SecurityPermission"
  • "System.Security.Permissions.ReflectionPermission"
  • "System.Security.Permissions.RegistryPermission"
§assembly_name: String

The assembly containing the permission class.

Typically “mscorlib” for core .NET Framework permissions, but may be “System” or other assemblies for specialized permission types.

§named_arguments: Vec<NamedArgument>

Collection of named property/field arguments that configure this permission.

Each named argument represents a property or field setting on the permission instance, such as file paths for FileIOPermission or flags for SecurityPermission. The collection may be empty for permissions that grant unrestricted access.

Implementations§

§

impl Permission

pub fn new( class_name: String, assembly_name: String, named_arguments: Vec<NamedArgument>, ) -> Self

Creates a new permission instance.

§Arguments
  • class_name - The fully qualified .NET type name of the permission class
  • assembly_name - The assembly containing the permission class
  • named_arguments - Collection of named property/field settings for this permission
§Examples
use dotscope::metadata::security::{Permission, NamedArgument, ArgumentType, ArgumentValue};

let permission = Permission::new(
    "System.Security.Permissions.FileIOPermission".to_string(),
    "mscorlib".to_string(),
    vec![
        NamedArgument::new(
            "Read".to_string(),
            ArgumentType::String,
            ArgumentValue::String("C:\\Data".to_string())
        ),
    ]
);

pub fn is_file_io(&self) -> bool

Checks if this is a FileIOPermission.

FileIOPermissions control access to file system resources including read, write, append, and path discovery operations.

§Returns

true if this permission’s class name matches the FileIOPermission type.

§Examples
use dotscope::metadata::security::Permission;

if permission.is_file_io() {
    println!("This permission controls file system access");
}

pub fn is_security(&self) -> bool

Checks if this is a SecurityPermission.

SecurityPermissions control access to security-sensitive operations such as executing unmanaged code, skipping verification, controlling threads, and other runtime security features.

§Returns

true if this permission’s class name matches the SecurityPermission type.

§Examples
use dotscope::metadata::security::Permission;

if permission.is_security() {
    if let Some(flags) = permission.get_security_flags() {
        println!("Security flags: {:?}", flags);
    }
}

pub fn is_reflection(&self) -> bool

Checks if this is a ReflectionPermission.

ReflectionPermissions control access to reflection capabilities such as emitting IL code, invoking non-public members, and accessing type information.

§Returns

true if this permission’s class name matches the ReflectionPermission type.

§Examples
use dotscope::metadata::security::Permission;

if permission.is_reflection() {
    println!("This permission controls reflection operations");
}

pub fn is_registry(&self) -> bool

Checks if this is a RegistryPermission.

RegistryPermissions control access to Windows registry operations including reading and writing registry keys and values.

§Returns

true if this permission’s class name matches the RegistryPermission type.

§Examples
use dotscope::metadata::security::Permission;

if permission.is_registry() {
    println!("This permission controls registry access");
}

pub fn is_ui(&self) -> bool

Checks if this is a UIPermission.

UIPermissions control access to user interface operations such as clipboard access, safe printing, and window manipulation.

§Returns

true if this permission’s class name matches the UIPermission type.

§Examples
use dotscope::metadata::security::Permission;

if permission.is_ui() {
    println!("This permission controls UI operations");
}

pub fn is_environment(&self) -> bool

Checks if this is an EnvironmentPermission.

EnvironmentPermissions control access to environment variable operations including reading and writing system and user environment variables.

§Returns

true if this permission’s class name matches the EnvironmentPermission type.

§Examples
use dotscope::metadata::security::Permission;

if permission.is_environment() {
    println!("This permission controls environment variable access");
}

pub fn get_argument(&self, name: &str) -> Option<&NamedArgument>

Retrieves a named argument by name.

Named arguments represent property or field assignments on the permission instance. Common argument names include “Read”, “Write”, “Unrestricted”, “Flags”, etc.

§Arguments
  • name - The name of the argument to search for (case-sensitive)
§Returns

Some(&NamedArgument) if an argument with the specified name exists, None otherwise.

§Examples
use dotscope::metadata::security::{Permission, NamedArgument, ArgumentType, ArgumentValue};

if let Some(read_arg) = permission.get_argument("Read") {
    println!("Read argument: {}", read_arg);
}

assert!(permission.get_argument("NonExistent").is_none());

pub fn get_file_read_paths(&self) -> Option<Vec<String>>

Extracts file paths granted read access from a FileIOPermission.

This method specifically looks for the “Read” argument in FileIOPermissions and extracts the file paths specified for read access. The paths can be specified as a single string or an array of strings.

§Returns
  • Some(Vec<String>) containing the read paths if this is a FileIOPermission with a “Read” argument
  • None if this is not a FileIOPermission or has no “Read” argument
§Examples
use dotscope::metadata::security::{Permission, NamedArgument, ArgumentType, ArgumentValue};

if let Some(paths) = permission.get_file_read_paths() {
    for path in paths {
        println!("Read access to: {}", path);
    }
}
§Path Format

The returned paths are exactly as specified in the permission metadata, which may include wildcards, UNC paths, or relative paths depending on how the permission was originally configured.

pub fn get_file_write_paths(&self) -> Option<Vec<String>>

Extracts file paths granted write access from a FileIOPermission.

This method specifically looks for the “Write” argument in FileIOPermissions and extracts the file paths specified for write access. The paths can be specified as a single string or an array of strings.

§Returns
  • Some(Vec<String>) containing the write paths if this is a FileIOPermission with a “Write” argument
  • None if this is not a FileIOPermission or has no “Write” argument
§Examples
use dotscope::metadata::security::{Permission, NamedArgument, ArgumentType, ArgumentValue};

let permission = Permission::new(
    "System.Security.Permissions.FileIOPermission".to_string(),
    "mscorlib".to_string(),
    vec![NamedArgument::new(
        "Write".to_string(),
        ArgumentType::String,
        ArgumentValue::String("C:\\Logs".to_string())
    )]
);

if let Some(paths) = permission.get_file_write_paths() {
    for path in paths {
        println!("Write access to: {}", path);
    }
}
§Security Implications

Write permissions are more sensitive than read permissions as they allow modification of the file system. The paths should be carefully validated in security-sensitive contexts.

pub fn get_file_path_discovery(&self) -> Option<Vec<String>>

Extracts file paths granted path discovery access from a FileIOPermission.

Path discovery permission allows code to determine if a file or directory exists and to retrieve path information, but not to read the actual contents. This method looks for the “PathDiscovery” argument in FileIOPermissions.

§Returns
  • Some(Vec<String>) containing the path discovery paths if this is a FileIOPermission with a “PathDiscovery” argument
  • None if this is not a FileIOPermission or has no “PathDiscovery” argument
§Examples
use dotscope::metadata::security::{Permission, NamedArgument, ArgumentType, ArgumentValue};

let permission = Permission::new(
    "System.Security.Permissions.FileIOPermission".to_string(),
    "mscorlib".to_string(),
    vec![NamedArgument::new(
        "PathDiscovery".to_string(),
        ArgumentType::String,
        ArgumentValue::String("C:\\Program Files".to_string())
    )]
);

if let Some(paths) = permission.get_file_path_discovery() {
    for path in paths {
        println!("Path discovery access to: {}", path);
    }
}
§Use Cases

Path discovery is often used by applications that need to check for the existence of files or directories without actually reading their contents, such as installers or configuration utilities.

pub fn is_unrestricted(&self) -> bool

Determines if this permission grants unrestricted access.

Many .NET permission classes support an “Unrestricted” property that, when set to true, grants full access to the protected resource without any limitations. This effectively bypasses all specific permission checks for that resource type.

§Returns

true if the permission has an “Unrestricted” argument set to true, false otherwise.

§Examples
use dotscope::metadata::security::{Permission, NamedArgument, ArgumentType, ArgumentValue};

let unrestricted_permission = Permission::new(
    "System.Security.Permissions.FileIOPermission".to_string(),
    "mscorlib".to_string(),
    vec![NamedArgument::new(
        "Unrestricted".to_string(),
        ArgumentType::Boolean,
        ArgumentValue::Boolean(true)
    )]
);

if unrestricted_permission.is_unrestricted() {
    println!("This permission grants unrestricted access");
}
§Security Implications

Unrestricted permissions are very powerful and should be carefully monitored in security audits, as they effectively disable all access controls for the associated resource type.

pub fn get_security_flags(&self) -> Option<SecurityPermissionFlags>

Extracts security permission flags from a SecurityPermission.

SecurityPermissions use a flags enumeration to specify which security-sensitive operations are allowed. This method parses the “Flags” argument and returns the corresponding crate::metadata::security::SecurityPermissionFlags.

§Returns
  • Some(SecurityPermissionFlags) if this is a SecurityPermission with valid flags
  • None if this is not a SecurityPermission or has no flags argument
§Supported Flag Formats

The method supports multiple flag formats commonly found in .NET metadata:

  • Integer values: Direct bitwise flag values
  • Enum values: Typed enum representations
  • String values: Comma-separated flag names (e.g., “Execution,UnmanagedCode”)
§Examples
use dotscope::metadata::security::{Permission, NamedArgument, ArgumentType, ArgumentValue, SecurityPermissionFlags};

let permission = Permission::new(
    "System.Security.Permissions.SecurityPermission".to_string(),
    "mscorlib".to_string(),
    vec![NamedArgument::new(
        "Flags".to_string(),
        ArgumentType::Int32,
        ArgumentValue::Int32(0x0002) // UnmanagedCode flag
    )]
);

if let Some(flags) = permission.get_security_flags() {
    if flags.contains(SecurityPermissionFlags::SECURITY_FLAG_UNSAFE_CODE) {
        println!("This permission allows unsafe code execution");
    }
}
§Common Security Flags
  • Execution: Allows code execution
  • UnmanagedCode: Allows calling unmanaged code
  • SkipVerification: Allows skipping IL verification
  • Assertion: Allows asserting permissions
  • ControlThread: Allows thread manipulation
  • ControlPolicy: Allows security policy control

Trait Implementations§

§

impl Clone for Permission

§

fn clone(&self) -> Permission

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Permission

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
§

impl Display for Permission

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AsAny for T
where T: Any,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Source§

fn type_name(&self) -> &'static str

Gets the type name of self
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: AsAny + ?Sized,

Source§

fn is<T>(&self) -> bool
where T: AsAny,

Returns true if the boxed type is the same as T. Read more
Source§

fn downcast_ref<T>(&self) -> Option<&T>
where T: AsAny,

Forward to the method defined on the type Any.
Source§

fn downcast_mut<T>(&mut self) -> Option<&mut T>
where T: AsAny,

Forward to the method defined on the type Any.
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, A> IntoAst<A> for T
where T: Into<A>, A: Ast,

Source§

fn into_ast(self, _a: &A) -> A

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToCompactString for T
where T: Display,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T> TryClone for T
where T: Clone,

Source§

fn try_clone(&self) -> Result<T, Error>

Clones self, possibly returning an error.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more