* ChangeLog: New. Track changes.
* Makefile: New. Build sandboxes and tests.
* makepol.cs: New.
* README: New. Instruction about the sandboxes and tests.
* sandbox.cs: New. Creates a policy (XML) restricted sandbox to
execute assemblies.
* whoami.cs: New. Sample to run under a sandbox.
svn path=/trunk/mono/; revision=44583
--- /dev/null
+2005-05-16 Sebastien Pouliot <sebastien@ximian.com>
+
+ * ChangeLog: New. Track changes.
+ * Makefile: New. Build sandboxes and tests.
+ * makepol.cs: New.
+ * README: New. Instruction about the sandboxes and tests.
+ * sandbox.cs: New. Creates a policy (XML) restricted sandbox to
+ execute assemblies.
+ * whoami.cs: New. Sample to run under a sandbox.
--- /dev/null
+RUNTIME = mono --debug --security
+CSCOMPILE = mcs -debug
+PROFILE = net_1_1
+
+all: makepol.exe internet.xml intranet.xml \
+ sandbox.exe stacktrace.exe whoami.exe
+
+aot: makepol.exe.so sandbox.exe.so stacktrace.exe.so whoami.exe.so
+
+FULLTRUST_TEST_FILES = sandbox
+
+UNHANDLED_TEST_FILES =
+
+run: all
+ @for i in $(FULLTRUST_TEST_FILES); do \
+ $(RUNTIME) $$i.exe x; \
+ done;
+ @for i in $(INTERNET_TEST_FILES); do \
+ MONO_CAS_ZONE=Internet $(RUNTIME) $$i.exe; \
+ done;
+
+test: all
+ @failed=0; \
+ passed=0; \
+ for i in $(FULLTRUST_TEST_FILES); do \
+ $(RUNTIME) $$i.exe > /dev/null; \
+ if [ "$$?" = "0" ]; then \
+ echo -e "fulltrust-$$i\tpass"; \
+ passed=`expr $${passed} + 1`; \
+ else \
+ echo -e "fulltrust-$$i\tFAIL ($$?)"; \
+ failed=`expr $${failed} + 1`; \
+ failed_tests="$${failed_tests} fulltrust-$$i"; \
+ fi; \
+ done; \
+ for i in $(UNHANDLED_TEST_FILES); do \
+ $(RUNTIME) $$i.exe > /dev/null; \
+ if [ "$$?" = "0" ]; then \
+ echo -e "unhandled-$$i\tFAIL ($$?)"; \
+ failed=`expr $${failed} + 1`; \
+ failed_tests="$${failed_tests} unhandled-$$i"; \
+ else \
+ echo -e "unhandled-$$i\tpass"; \
+ passed=`expr $${passed} + 1`; \
+ fi; \
+ done; \
+ echo -e "\n$${passed} test(s) passed. $${failed} test(s) failed."; \
+ if [ "$${failed}" != "0" ]; then \
+ echo -e "Failed tests are:"; \
+ for i in $${failed_tests}; \
+ do echo -e "\t$${i}"; \
+ done; \
+ exit 1; \
+ fi
+
+clean:
+ rm -f *.exe* *.dll* *.snk
+
+%.xml: makepol.exe
+ $(RUNTIME) makepol.exe
+
+%.exe: %.cs
+ $(CSCOMPILE) $^ /out:$@
+
+makepol.exe: makepol.cs
+ $(CSCOMPILE) $^ /out:$@ -r:System.dll -r:System.Drawing.dll
+
+%.exe.so: %.exe
+ $(RUNTIME) --aot $^
--- /dev/null
+AppDomain sandboxes
+
+
+* makepol.cs: Create some XML policy files to be used with the sandboxes.
+* sandbox.cs: Create a policy-restricted appdomain to execute assemblies.
+
+
+Samples
+
+* whoami.cs: Sample code that can be executed under a sandbox.
+
+
+Generated files
+
+* Mono doesn't (at least currently) ship with XML policy files. So the
+makepol.exe tool creates policies similar (i.e. not all 100% identical) to the
+ones shipped with version 1.1 of the MS framework.
+
+
+More informations:
+
+* http://blogs.msdn.com/shawnfa/archive/2004/10/25/247379.aspx
+
+
+Expected Results
+
+ FullTrust Intranet Internet Execution Nothing
+sandbox ok ok ok ok fail [1]
+whoami ok ok fail fail fail [1]
+sandbox whoami ok fail fail fail fail [1]
+
+
+
+Notes
+
+[1] This should be a "PolicyException: Execution permission cannot be
+ acquired." but it's a SecurityException on Mono (atm).
--- /dev/null
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Drawing.Printing;
+using System.Net;
+using System.Security;
+using System.Security.Permissions;
+using System.Security.Policy;
+
+class Program {
+
+ static PermissionSet CreatePermissionSet (string name)
+ {
+ return new NamedPermissionSet (name, PermissionState.None);
+ }
+
+ static void Save (string filename, PermissionSet ps)
+ {
+ using (StreamWriter sw = new StreamWriter (filename)) {
+ sw.WriteLine (ps.ToXml ().ToString ());
+ sw.Close ();
+ }
+ }
+
+ public static void FullTrust ()
+ {
+ PermissionSet ps = new NamedPermissionSet ("FullTrust", PermissionState.Unrestricted);
+ Save ("fulltrust.xml", ps);
+ }
+
+ public static void LocalIntranet ()
+ {
+ PermissionSet ps = CreatePermissionSet ("LocalIntranet");
+
+ ps.AddPermission (new EnvironmentPermission (EnvironmentPermissionAccess.Read, "USERNAME;USER"));
+
+ ps.AddPermission (new FileDialogPermission (PermissionState.Unrestricted));
+
+ IsolatedStorageFilePermission isfp = new IsolatedStorageFilePermission (PermissionState.None);
+ isfp.UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByUser;
+ isfp.UserQuota = Int64.MaxValue;
+ ps.AddPermission (isfp);
+
+ ps.AddPermission (new ReflectionPermission (ReflectionPermissionFlag.ReflectionEmit));
+
+ SecurityPermissionFlag spf = SecurityPermissionFlag.Execution | SecurityPermissionFlag.Assertion;
+ ps.AddPermission (new SecurityPermission (spf));
+
+ ps.AddPermission (new UIPermission (PermissionState.Unrestricted));
+
+ ps.AddPermission (new DnsPermission (PermissionState.Unrestricted));
+
+ ps.AddPermission (new PrintingPermission (PrintingPermissionLevel.DefaultPrinting));
+
+ ps.AddPermission (new EventLogPermission (EventLogPermissionAccess.Instrument, "."));
+
+ Save ("intranet.xml", ps);
+ }
+
+ public static void Internet ()
+ {
+ PermissionSet ps = CreatePermissionSet ("Internet");
+
+ ps.AddPermission (new FileDialogPermission (FileDialogPermissionAccess.Open));
+
+ IsolatedStorageFilePermission isfp = new IsolatedStorageFilePermission (PermissionState.None);
+ isfp.UsageAllowed = IsolatedStorageContainment.DomainIsolationByUser;
+ isfp.UserQuota = 10240;
+ ps.AddPermission (isfp);
+
+ ps.AddPermission (new SecurityPermission (SecurityPermissionFlag.Execution));
+
+ ps.AddPermission (new UIPermission (UIPermissionWindow.SafeTopLevelWindows, UIPermissionClipboard.OwnClipboard));
+
+ ps.AddPermission (new PrintingPermission (PrintingPermissionLevel.SafePrinting));
+
+ Save ("internet.xml", ps);
+ }
+
+ public static void Execution ()
+ {
+ PermissionSet ps = CreatePermissionSet ("Execution");
+
+ ps.AddPermission (new SecurityPermission (SecurityPermissionFlag.Execution));
+
+ Save ("execution.xml", ps);
+ }
+
+ public static void Nothing ()
+ {
+ PermissionSet ps = CreatePermissionSet ("Nothing");
+ Save ("nothing.xml", ps);
+ }
+
+ static int Main (string[] args)
+ {
+ Console.WriteLine ("NOTE: All files are for test purposes only!");
+ Console.WriteLine ("Creating the FullTrust default permissions file...");
+ FullTrust ();
+ Console.WriteLine ("Creating the Local Intranet default permissions file...");
+ LocalIntranet ();
+ Console.WriteLine ("Creating the Internet default permissions file...");
+ Internet ();
+ Console.WriteLine ("Creating the Execution default permissions file...");
+ Execution ();
+ Console.WriteLine ("Creating the Nothing default permissions file...");
+ Nothing ();
+ Console.WriteLine ("Completed.");
+ return 0;
+ }
+}
--- /dev/null
+using System;
+using System.Collections;
+using System.Security;
+using System.Security.Permissions;
+using System.Security.Policy;
+
+class Program {
+
+ // note: you cannot load a file directly into a PermissionSet
+ // but we can hack around this by using PermissionSetAttribute ;-)
+ static PermissionSet LoadFromFile (string filename)
+ {
+ // the SecurityAction is meaningless here
+ PermissionSetAttribute psa = new PermissionSetAttribute (SecurityAction.Demand);
+ psa.File = filename;
+ return psa.CreatePermissionSet ();
+ }
+
+ // source: http://blogs.msdn.com/shawnfa/archive/2004/10/25/247379.aspx
+ static AppDomain CreateRestrictedDomain (string filename)
+ {
+ PermissionSet emptySet = new PermissionSet (PermissionState.None);
+ PolicyStatement emptyPolicy = new PolicyStatement (emptySet);
+ UnionCodeGroup root = new UnionCodeGroup (new AllMembershipCondition (), emptyPolicy);
+
+ PermissionSet userSet = LoadFromFile (filename);
+ PolicyStatement userPolicy = new PolicyStatement (userSet);
+ root.AddChild (new UnionCodeGroup (new AllMembershipCondition (), userPolicy));
+
+ PolicyLevel pl = PolicyLevel.CreateAppDomainLevel ();
+ pl.RootCodeGroup = root;
+
+ AppDomain ad = AppDomain.CreateDomain ("Restricted");
+ ad.SetAppDomainPolicy (pl);
+ return ad;
+ }
+
+ static int Main (string[] args)
+ {
+ switch (args.Length) {
+ case 0:
+ Console.WriteLine ("Create a restricted sandbox to execute an assembly.");
+ Console.WriteLine ("Usage: mono sandbox.exe [permissionset.xml] assembly.exe [parameters ...]");
+ return 0;
+ case 1:
+ Console.WriteLine ("Using default (current) appdomain to load '{0}'...", args [0]);
+ return AppDomain.CurrentDomain.ExecuteAssembly (args [0]);
+ case 2:
+ AppDomain ad = CreateRestrictedDomain (args [0]);
+ return ad.ExecuteAssembly (args [1]);
+ default:
+ ad = CreateRestrictedDomain (args [0]);
+ string[] newargs = new string [args.Length - 2];
+ for (int i=2; i < args.Length; i++)
+ newargs [i-2] = args [i];
+ return ad.ExecuteAssembly (args [1], null, newargs);
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Security;
+
+class Program {
+
+ static int Main (string[] args)
+ {
+ try {
+ Console.WriteLine (Environment.UserName);
+ return 0;
+ }
+ catch (SecurityException se) {
+ Console.WriteLine ("---{0}{1}{0}---", Environment.NewLine, se);
+ return 1;
+ }
+ }
+}