2005-05-16 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Mon, 16 May 2005 19:39:00 +0000 (19:39 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Mon, 16 May 2005 19:39:00 +0000 (19:39 -0000)
* 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

mono/tests/cas/appdomain/ChangeLog [new file with mode: 0644]
mono/tests/cas/appdomain/Makefile [new file with mode: 0644]
mono/tests/cas/appdomain/README [new file with mode: 0644]
mono/tests/cas/appdomain/makepol.cs [new file with mode: 0644]
mono/tests/cas/appdomain/sandbox.cs [new file with mode: 0644]
mono/tests/cas/appdomain/whoami.cs [new file with mode: 0644]

diff --git a/mono/tests/cas/appdomain/ChangeLog b/mono/tests/cas/appdomain/ChangeLog
new file mode 100644 (file)
index 0000000..1791ac2
--- /dev/null
@@ -0,0 +1,9 @@
+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.
diff --git a/mono/tests/cas/appdomain/Makefile b/mono/tests/cas/appdomain/Makefile
new file mode 100644 (file)
index 0000000..ace2890
--- /dev/null
@@ -0,0 +1,69 @@
+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 $^
diff --git a/mono/tests/cas/appdomain/README b/mono/tests/cas/appdomain/README
new file mode 100644 (file)
index 0000000..45e6a87
--- /dev/null
@@ -0,0 +1,37 @@
+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).
diff --git a/mono/tests/cas/appdomain/makepol.cs b/mono/tests/cas/appdomain/makepol.cs
new file mode 100644 (file)
index 0000000..6a67c44
--- /dev/null
@@ -0,0 +1,111 @@
+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;
+       }
+}
diff --git a/mono/tests/cas/appdomain/sandbox.cs b/mono/tests/cas/appdomain/sandbox.cs
new file mode 100644 (file)
index 0000000..e682edc
--- /dev/null
@@ -0,0 +1,59 @@
+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);
+               }
+       }
+}
diff --git a/mono/tests/cas/appdomain/whoami.cs b/mono/tests/cas/appdomain/whoami.cs
new file mode 100644 (file)
index 0000000..a89489c
--- /dev/null
@@ -0,0 +1,17 @@
+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;
+               }
+       }
+}