// // MonoTests.System.Security.Permissions.FileIOPermissionTest.cs // // Author: // Nick Drochak (ndrochak@gol.com) // // (C) 2001-2002 Nick Drochak II // // Note: Only Unix and Windows file paths are tested. To run the tests on Mac OS's // search for the "FIXME" notes below and adjust accordingly. using System; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using NUnit.Framework; namespace MonoTests.System.Security.Permissions { public class FilePathUtil { [DllImport("kernel32.dll")] private static extern uint GetLongPathName (string shortPath, StringBuilder buffer, uint bufLength); static public string GetLongPathName (string somePath) { StringBuilder buffer = new StringBuilder(260); if (0 != GetLongPathName (somePath, buffer, (uint) buffer.Capacity)) return buffer.ToString (); else return null; } } [TestFixture] public class FileIOPermissionTest : Assertion { string[] pathArrayGood; string[] pathArrayBad; FileIOPermission p; FileIOPermission p2; string[] pathsInPermission; string[] pathArrayGood2; FileIOPermission unrestricted; private string filename; [SetUp] public void SetUp () { Environment.CurrentDirectory = Path.GetTempPath(); filename = Path.GetTempFileName (); p = null; pathsInPermission = null; pathArrayGood = new string[2]; pathArrayBad = new string[2]; pathArrayGood2 = new string[3]; // FIXME: Adjust to run on Mac OS's if (Path.VolumeSeparatorChar == ':') { pathArrayGood[0] = "c:\\temp1"; pathArrayGood[1] = "d:\\temp2"; pathArrayBad[0] = "c:\\temp1"; pathArrayBad[1] = "d:\\temp*"; pathArrayGood2[0] = "c:\\temp1"; pathArrayGood2[1] = "d:\\temp2"; pathArrayGood2[2] = "z:\\something"; } else { pathArrayGood[0] = "/temp1"; pathArrayGood[1] = "/usr/temp2"; pathArrayBad[0] = "/temp1"; pathArrayBad[1] = "/usr/temp*"; pathArrayGood2[0] = "/temp1"; pathArrayGood2[1] = "/usr/temp2"; pathArrayGood2[2] = "/usr/bin/something"; } } [TearDown] public void TearDown () { if (File.Exists (filename)) File.Delete (filename); } [Test] public void ConstructorPermissionState () { p = new FileIOPermission(PermissionState.None); AssertEquals("Should be Restricted", false, p.IsUnrestricted()); p = new FileIOPermission(PermissionState.Unrestricted); AssertEquals("Should be Unrestricted", true, p.IsUnrestricted()); try{ p = new FileIOPermission((PermissionState)77); Fail("Should have thrown an exception on invalid PermissionState"); } catch{ // we should be here if things are working. nothing to do } } [Test] [ExpectedException (typeof (ArgumentNullException))] public void ConstructorString_Null () { p = new FileIOPermission(FileIOPermissionAccess.Append, (string)null); } [Test] [ExpectedException (typeof (ArgumentException))] public void ConstructorString_NotRooted () { p = new FileIOPermission(FileIOPermissionAccess.Append, "this path is not rooted"); } [Test] [ExpectedException (typeof (ArgumentException))] public void ConstructorString_InvalidPath () { p = new FileIOPermission(FileIOPermissionAccess.Append, ""); } [Test] [ExpectedException (typeof (ArgumentException))] public void ConstructorString_Wildcard () { p = new FileIOPermission(FileIOPermissionAccess.Append, "\\\\mycomputer\\test*"); } [Test] [ExpectedException (typeof (ArgumentException))] public void ConstructorString_InvalidAccess () { p = new FileIOPermission((FileIOPermissionAccess)77, "c:\\temp"); } [Test] public void ConstructorString () { string pathToAdd; // FIXME: Adjust to run on Mac OS's if (Path.VolumeSeparatorChar == ':') pathToAdd = "c:\\temp"; else pathToAdd = "/temp"; p = new FileIOPermission(FileIOPermissionAccess.Read, pathToAdd); pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read); Assert("Does not contain correct number of paths. Expected 1 but got: "+pathsInPermission.Length, pathsInPermission.Length == 1); Assert("Does not contain expected path from constructor: "+pathToAdd, pathsInPermission[0] == pathToAdd); } [Test] [ExpectedException (typeof (ArgumentNullException))] public void ConstructorStringArray_Null () { p = new FileIOPermission(FileIOPermissionAccess.Append, (string[])null); } [Test] [ExpectedException (typeof (ArgumentException))] public void ConstructorStringArray_Wildcard () { p = new FileIOPermission(FileIOPermissionAccess.Append, pathArrayBad); } [Test] [ExpectedException (typeof (ArgumentException))] public void ConstructorStringArray_InvalidAccess () { p = new FileIOPermission((FileIOPermissionAccess)77, pathArrayGood); } [Test] public void ConstructorStringArray () { p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood); pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read); Assert("Does not contain correct number of paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2); foreach (string s in pathsInPermission){ Assert("Unexpected path in the Permission: " + s, Array.IndexOf(pathsInPermission, s) >=0); } } [Test] public void AddPathListStringArray () { p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood); pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read); Assert("Does not contain correct number of paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2); foreach (string s in pathsInPermission){ Assert("Unexpected path in the Permission: " + s, Array.IndexOf(pathsInPermission, s) >=0); } p.AddPathList(FileIOPermissionAccess.Append, pathArrayGood); pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read); Assert("Should still contain correct number Read paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2); foreach (string s in pathsInPermission){ Assert("Unexpected path in the Permission: " + s, Array.IndexOf(pathsInPermission, s) >=0); } pathsInPermission = p.GetPathList(FileIOPermissionAccess.Append); Assert("Should contain correct number of Append paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2); foreach (string s in pathsInPermission){ Assert("Unexpected path in the Permission: " + s, Array.IndexOf(pathsInPermission, s) >=0); } } [Test] public void Intersect () { p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood); p.AllFiles = FileIOPermissionAccess.Append; p.AllLocalFiles = FileIOPermissionAccess.Write; unrestricted = new FileIOPermission(PermissionState.Unrestricted); FileIOPermission intersection = (FileIOPermission)p.Intersect(unrestricted); pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read); Assert("Should contain correct number of Read paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2); Assert("Should have Append bit in AllFiles.", (intersection.AllFiles & FileIOPermissionAccess.Append) != 0); Assert("Should have Write bit in AllLocalFiles.", (intersection.AllLocalFiles & FileIOPermissionAccess.Write) != 0); intersection = (FileIOPermission)unrestricted.Intersect(p); pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read); Assert("Should contain correct number of Read paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2); Assert("Should have Append bit in AllFiles.", (intersection.AllFiles & FileIOPermissionAccess.Append) != 0); Assert("Should have Write bit in AllLocalFiles.", (intersection.AllLocalFiles & FileIOPermissionAccess.Write) != 0); p2 = new FileIOPermission(FileIOPermissionAccess.Append | FileIOPermissionAccess.Read, pathArrayGood2); p2.AllFiles = FileIOPermissionAccess.Append | FileIOPermissionAccess.Write; p2.AllLocalFiles = FileIOPermissionAccess.Write | FileIOPermissionAccess.Read; intersection = (FileIOPermission)p.Intersect(p2); pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read); AssertNotNull ("Should have some paths", pathsInPermission); AssertEquals ("Should contain correct number of Read paths", 2, pathsInPermission.Length); AssertEquals ("Should have only Append bit in AllFiles.", FileIOPermissionAccess.Append, intersection.AllFiles); AssertEquals ("Should have only Write bit in AllLocalFiles.", FileIOPermissionAccess.Write, intersection.AllLocalFiles); intersection = (FileIOPermission)p2.Intersect(p); pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read); Assert("Should contain correct number of Read paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2); Assert("Should have only Append bit in AllFiles.", intersection.AllFiles == FileIOPermissionAccess.Append); Assert("Should have only Write bit in AllLocalFiles.", intersection.AllLocalFiles == FileIOPermissionAccess.Write); } [Test] public void IsSubsetOf () { unrestricted = new FileIOPermission(PermissionState.Unrestricted); Assert("IsSubsetOf reflective test failed", unrestricted.IsSubsetOf(unrestricted)); p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood); p.AllFiles = FileIOPermissionAccess.Append; p.AllLocalFiles = FileIOPermissionAccess.Write; Assert("#1 IsSubsetOf reflective test failed", p.IsSubsetOf(p)); Assert("#1 IsSubsetOf false test failed", !unrestricted.IsSubsetOf(p)); Assert("#1 IsSubsetOf true test failed", p.IsSubsetOf(unrestricted)); p2 = new FileIOPermission(FileIOPermissionAccess.Append | FileIOPermissionAccess.Read, pathArrayGood2); p2.AllFiles = FileIOPermissionAccess.Append | FileIOPermissionAccess.Write; p2.AllLocalFiles = FileIOPermissionAccess.Write | FileIOPermissionAccess.Read; Assert("#2 IsSubsetOf reflective test failed", p2.IsSubsetOf(p2)); Assert("#2 IsSubsetOf true test failed", p.IsSubsetOf(p2)); Assert("#2 IsSubsetOf false test failed", !p2.IsSubsetOf(p)); } [Test] public void Union () { unrestricted = new FileIOPermission(PermissionState.Unrestricted); p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood); FileIOPermission union = (FileIOPermission)unrestricted.Union(p); pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read); Assert("Should get an unrestricted permission", union.IsUnrestricted()); Assert("Path list should be empty", pathsInPermission == null); union = (FileIOPermission)p.Union(unrestricted); pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read); Assert("Should get an unrestricted permission", union.IsUnrestricted()); Assert("Path list should be empty", pathsInPermission == null); p2 = new FileIOPermission(FileIOPermissionAccess.Append, pathArrayGood2); union = (FileIOPermission)p.Union(p2); pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read); Assert("Path list should have 2 for Read", pathsInPermission.Length == pathArrayGood.Length); pathsInPermission = union.GetPathList(FileIOPermissionAccess.Append); Assert("Path list should have 3 for Append", pathsInPermission.Length == pathArrayGood2.Length); union = (FileIOPermission)p2.Union(p); pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read); Assert("Path list should have 2 for Read", pathsInPermission.Length == pathArrayGood.Length); pathsInPermission = union.GetPathList(FileIOPermissionAccess.Append); Assert("Path list should have 3 for Append", pathsInPermission.Length == pathArrayGood2.Length); } [Test] public void FromXML () { p = new FileIOPermission(PermissionState.None); SecurityElement esd = new SecurityElement("IPermission"); esd.AddAttribute("class", "FileIOPermission"); esd.AddAttribute("version", "1"); esd.AddAttribute("Unrestricted", "true"); p.FromXml(esd); Assert("Should get an unrestricted permission", p.IsUnrestricted()); esd = new SecurityElement("IPermission"); esd.AddAttribute("class", "FileIOPermission"); esd.AddAttribute("version", "1"); // FIXME: Adjust to run on Mac OS's if (Path.VolumeSeparatorChar == ':') { esd.AddAttribute("Read", "c:\\temp;d:\\temp2"); esd.AddAttribute("Write", "c:\\temp;d:\\temp2;z:\\temp3"); } else { esd.AddAttribute("Read", "/temp;/usr/temp2"); esd.AddAttribute("Write", "/temp;/usr/temp2;/usr/bin/temp3"); } p = new FileIOPermission(PermissionState.None); p.FromXml(esd); pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read); Assert("Path list should have 2 for Read", pathsInPermission.Length == 2); pathsInPermission = p.GetPathList(FileIOPermissionAccess.Write); Assert("Path list should have 2 for Write", pathsInPermission.Length == 3); } [Test] public void ToXML () { p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood); SecurityElement esd = p.ToXml(); Assert("Esd tag incorrect", esd.Tag == "IPermission"); Assert("Esd version incorrect", (String)esd.Attributes["version"] == "1"); string read = (String)esd.Attributes["Read"]; pathsInPermission = read.Split(';'); Assert("Path list should have 2 for Read", pathsInPermission.Length == 2); } [Test] [Ignore("should compatibility go that far ?")] public void ShortToLong () { // on windows this returns a "short" (8.3) path and filename string filename = Path.GetTempFileName (); p = new FileIOPermission(FileIOPermissionAccess.Read, filename); string[] files = p.GetPathList (FileIOPermissionAccess.Read); AssertEquals ("GetPathList.Count", 1, files.Length); // FIXME: here GetTempFileName != GetPathList[0] for MS but == for Mono AssertEquals ("Path.GetFileName(GetTempFileName)==Path.GetFileName(GetPathList[0])", Path.GetFileName (filename), Path.GetFileName (files [0])); // note: this will fail on Linux as kernel32.dll isn't available AssertEquals ("GetLongPathName(GetTempFileName)==GetPathList[0]", FilePathUtil.GetLongPathName (filename), files [0]); } } }