?
=?iso-8859-1?Q?Peter_Str=F8iman?=
Hi.
I have an application where I dynamically compile code. The code is stored in a database, and is at runtime compiled to an assembly file. I then load the assembly file and call some methods in this file.
I would like to limit the amount of functionality that these assemblies can access. E.g. I don't want any file system access to be available. The assemblies should however be able to access other assemblies that does have this ability. E.g. I could reference an assembly that writes to a logfile. Thus the dynamically compiled assembly can not directly access the log file, but the referenced assembly can.
Here is a simplified version of the code I use. The class Script is a class that contains the code coming from the database. It specifies a language that I use to determine which code provider to create. And it contains a name that is used to determine the output file name of the generated assembly.
For the assembly to work, it must contain a class that is a subclass of my class ScriptObject. A reference to the assembly that defines this class is passed to the compiler. This is done in order for me to be able to initialise members that are then avaible to the code.
Anybody have any clues to how I can implement code permissions for my generated assembly.
One idea I was thinking about was to sign my generated assembly with a specific key-file, and then adjust the framework configuration to give assemblies signed with this specific key limited permissions. Would that work?
Thanks in advance,
Peter Strøiman
public override object Execute(string EventName, ref object[] Arguments, System.Collections.IDictionary projectVars, System.Collections.IDictionary userVars)
{
Assembly assembly = CompileScript( Script );
foreach( Type type in assembly.GetTypes() )
{
if ( type.IsSubclassOf( typeof( ScriptObject ) ) )
{
MemberInfo[] members = type.GetMember( EventName );
if ( members.Length > 0 )
{
ScriptObject scriptObject = (ScriptObject)type.GetConstructor( Type.EmptyTypes ).Invoke( new object[0] );
// Here I initialise the object.
return type.InvokeMember( EventName, BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.InvokeMethod | BindingFlags.IgnoreCase,
null, scriptObject, Arguments );
}
}
}
return null;
}
public Assembly CompileScript( Script script )
{
string[] references = GetReferences( script, names );
CodeDomProvider codeProvider = CreateDomProvider( script );
ICodeCompiler compiler = codeProvider.CreateCompiler();
string fileName = GetOutputFileName( script );
CompilerParameters cp = new CompilerParameters(
references, fileName, false );
CompilerResults cr = compiler.CompileAssemblyFromSource( cp, script.Code );
if ( cr.Errors.Count > 0 )
{
// Handle compiler error.
}
if ( cr.NativeCompilerReturnValue != 0 )
{
// Handle compiler errors again.
}
return Assembly.LoadFrom( fileName );
}
I have an application where I dynamically compile code. The code is stored in a database, and is at runtime compiled to an assembly file. I then load the assembly file and call some methods in this file.
I would like to limit the amount of functionality that these assemblies can access. E.g. I don't want any file system access to be available. The assemblies should however be able to access other assemblies that does have this ability. E.g. I could reference an assembly that writes to a logfile. Thus the dynamically compiled assembly can not directly access the log file, but the referenced assembly can.
Here is a simplified version of the code I use. The class Script is a class that contains the code coming from the database. It specifies a language that I use to determine which code provider to create. And it contains a name that is used to determine the output file name of the generated assembly.
For the assembly to work, it must contain a class that is a subclass of my class ScriptObject. A reference to the assembly that defines this class is passed to the compiler. This is done in order for me to be able to initialise members that are then avaible to the code.
Anybody have any clues to how I can implement code permissions for my generated assembly.
One idea I was thinking about was to sign my generated assembly with a specific key-file, and then adjust the framework configuration to give assemblies signed with this specific key limited permissions. Would that work?
Thanks in advance,
Peter Strøiman
public override object Execute(string EventName, ref object[] Arguments, System.Collections.IDictionary projectVars, System.Collections.IDictionary userVars)
{
Assembly assembly = CompileScript( Script );
foreach( Type type in assembly.GetTypes() )
{
if ( type.IsSubclassOf( typeof( ScriptObject ) ) )
{
MemberInfo[] members = type.GetMember( EventName );
if ( members.Length > 0 )
{
ScriptObject scriptObject = (ScriptObject)type.GetConstructor( Type.EmptyTypes ).Invoke( new object[0] );
// Here I initialise the object.
return type.InvokeMember( EventName, BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.InvokeMethod | BindingFlags.IgnoreCase,
null, scriptObject, Arguments );
}
}
}
return null;
}
public Assembly CompileScript( Script script )
{
string[] references = GetReferences( script, names );
CodeDomProvider codeProvider = CreateDomProvider( script );
ICodeCompiler compiler = codeProvider.CreateCompiler();
string fileName = GetOutputFileName( script );
CompilerParameters cp = new CompilerParameters(
references, fileName, false );
CompilerResults cr = compiler.CompileAssemblyFromSource( cp, script.Code );
if ( cr.Errors.Count > 0 )
{
// Handle compiler error.
}
if ( cr.NativeCompilerReturnValue != 0 )
{
// Handle compiler errors again.
}
return Assembly.LoadFrom( fileName );
}