1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.Generic; 6 using System.Security.Principal; 7 using Xunit; 8 9 namespace System.Security.AccessControl.Tests 10 { 11 public class ObjectAce_Tests : QualifiedAce_Tests 12 { VerifyObjectAce(ObjectAce ace, AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque)13 protected static void VerifyObjectAce(ObjectAce ace, AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) 14 { 15 Assert.Equal(aceFlags, ace.AceFlags); 16 Assert.Equal(accessMask, ace.AccessMask); 17 Assert.Equal(sid, ace.SecurityIdentifier); 18 Assert.Equal(opaque, ace.GetOpaque()); 19 Assert.Equal(qualifier, ace.AceQualifier); 20 Assert.Equal(isCallback, ace.IsCallback); 21 Assert.Equal(flags, ace.ObjectAceFlags); 22 Assert.Equal(type, ace.ObjectAceType); 23 Assert.Equal(inheritedType, ace.InheritedObjectAceType); 24 } 25 ObjectAce_CreateTestData(int intFlags, int intQualifier, int accessMask, string stringsid, int intObjectAceFlags, string stringType, string stringInheritedType, bool isCallback, int opaqueLength, int offset)26 private static object[] ObjectAce_CreateTestData(int intFlags, int intQualifier, int accessMask, string stringsid, int intObjectAceFlags, string stringType, string stringInheritedType, bool isCallback, int opaqueLength, int offset) 27 { 28 AceFlags aceFlags = (AceFlags)intFlags; 29 AceQualifier qualifier = (AceQualifier)intQualifier; 30 SecurityIdentifier sid = new SecurityIdentifier(stringsid); 31 ObjectAceFlags flags = (ObjectAceFlags)intObjectAceFlags; 32 Guid type = new Guid(stringType); 33 Guid inheritedType = new Guid(stringInheritedType); 34 byte[] opaque = new byte[opaqueLength]; 35 36 ObjectAce ace = new ObjectAce(aceFlags, qualifier, accessMask, sid, flags, type, inheritedType, isCallback, opaque); 37 VerifyObjectAce(ace, aceFlags, qualifier, accessMask, sid, flags, type, inheritedType, isCallback, opaque); 38 39 byte[] binaryForm = new byte[ace.BinaryLength + offset]; 40 switch (qualifier) 41 { 42 case AceQualifier.AccessAllowed: 43 binaryForm[offset + 0] = isCallback ? (byte)AceType.AccessAllowedCallbackObject : (byte)AceType.AccessAllowedObject; 44 break; 45 case AceQualifier.AccessDenied: 46 binaryForm[offset + 0] = isCallback ? (byte)AceType.AccessDeniedCallbackObject : (byte)AceType.AccessDeniedObject; 47 break; 48 case AceQualifier.SystemAudit: 49 binaryForm[offset + 0] = isCallback ? (byte)AceType.SystemAuditCallbackObject : (byte)AceType.SystemAuditObject; 50 break; 51 case AceQualifier.SystemAlarm: 52 binaryForm[offset + 0] = isCallback ? (byte)AceType.SystemAlarmCallbackObject : (byte)AceType.SystemAlarmObject; 53 break; 54 default: 55 return null; 56 } 57 binaryForm[offset + 1] = (byte)aceFlags; 58 binaryForm[offset + 2] = (byte)(ace.BinaryLength >> 0); 59 binaryForm[offset + 3] = (byte)(ace.BinaryLength >> 8); 60 61 int baseOffset = offset + 4; 62 int offsetLocal = 0; 63 64 unchecked 65 { 66 binaryForm[baseOffset + 0] = (byte)(accessMask >> 0); 67 binaryForm[baseOffset + 1] = (byte)(accessMask >> 8); 68 binaryForm[baseOffset + 2] = (byte)(accessMask >> 16); 69 binaryForm[baseOffset + 3] = (byte)(accessMask >> 24); 70 } 71 offsetLocal += 4; 72 73 binaryForm[baseOffset + offsetLocal + 0] = (byte)(((uint)flags) >> 0); 74 binaryForm[baseOffset + offsetLocal + 1] = (byte)(((uint)flags) >> 8); 75 binaryForm[baseOffset + offsetLocal + 2] = (byte)(((uint)flags) >> 16); 76 binaryForm[baseOffset + offsetLocal + 3] = (byte)(((uint)flags) >> 24); 77 78 offsetLocal += 4; 79 80 if ((flags & ObjectAceFlags.ObjectAceTypePresent) != 0) 81 { 82 type.ToByteArray().CopyTo(binaryForm, baseOffset + offsetLocal); 83 offsetLocal += 16; 84 } 85 86 if ((flags & ObjectAceFlags.InheritedObjectAceTypePresent) != 0) 87 { 88 inheritedType.ToByteArray().CopyTo(binaryForm, baseOffset + offsetLocal); 89 offsetLocal += 16; 90 } 91 92 sid.GetBinaryForm(binaryForm, baseOffset + offsetLocal); 93 offsetLocal += sid.BinaryLength; 94 opaque.CopyTo(binaryForm, baseOffset + offsetLocal); 95 96 return new object[] { ace, binaryForm, offset }; 97 } 98 99 ObjectAce_TestObjects()100 public static IEnumerable<object[]> ObjectAce_TestObjects() 101 { 102 yield return ObjectAce_CreateTestData(0, 0, 1, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", false, 8, 0); 103 yield return ObjectAce_CreateTestData(1, 1, 0, "S-1-5-11", 2, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", false, 8, 0); 104 yield return ObjectAce_CreateTestData(2, 2, -1, "S-1-5-11", 3, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 105 yield return ObjectAce_CreateTestData(4, 3, 0, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 106 yield return ObjectAce_CreateTestData(8, 3, 1, "S-1-5-11", 2, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 107 yield return ObjectAce_CreateTestData(16, 0, 3, "S-1-5-11", 0, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 108 yield return ObjectAce_CreateTestData(32, 1, 3, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 109 yield return ObjectAce_CreateTestData(64, 2, 3, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 110 yield return ObjectAce_CreateTestData(128, 3, 3, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 111 yield return ObjectAce_CreateTestData(15, 3, 3, "S-1-5-11", 2, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 112 yield return ObjectAce_CreateTestData(192, 3, 3, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 113 yield return ObjectAce_CreateTestData(2, 1, 999999, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0); 114 yield return ObjectAce_CreateTestData(2, 1, 2, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 8, 0); 115 } 116 117 [Fact] ObjectAce_Constructor_Invalid()118 public void ObjectAce_Constructor_Invalid() 119 { 120 AssertExtensions.Throws<ArgumentNullException>("securityIdentifier", () => new ObjectAce((AceFlags)0, (AceQualifier)0, 1, null, (ObjectAceFlags)1, new Guid("{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}"), new Guid("{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}"), true, new byte[4])); 121 AssertExtensions.Throws<ArgumentOutOfRangeException>("qualifier", () => ObjectAce_CreateTestData(8, 4, 1, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0)); 122 AssertExtensions.Throws<ArgumentOutOfRangeException>("qualifier", () => ObjectAce_CreateTestData(8, -1, 1, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 4, 0)); 123 AssertExtensions.Throws<ArgumentOutOfRangeException>("opaque", () => ObjectAce_CreateTestData(2, 1, 2, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 1, 0)); 124 AssertExtensions.Throws<ArgumentOutOfRangeException>("opaque", () => ObjectAce_CreateTestData(2, 1, 2, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", true, 17, 0)); 125 } 126 127 [Fact] ObjectAce_CreateBinaryForm_Invalid()128 public void ObjectAce_CreateBinaryForm_Invalid() 129 { 130 ObjectAce ace = (ObjectAce)ObjectAce_CreateTestData(0, 0, 1, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", false, 8, 0)[0]; 131 AssertExtensions.Throws<ArgumentNullException>("binaryForm", () => ObjectAce.CreateFromBinaryForm(null, 1)); 132 AssertExtensions.Throws<ArgumentOutOfRangeException>("offset", () => ObjectAce.CreateFromBinaryForm(new byte[1], -1)); 133 AssertExtensions.Throws<ArgumentException>("binaryForm", () => ObjectAce.CreateFromBinaryForm(new byte[ace.BinaryLength + 1], 2)); 134 AssertExtensions.Throws<ArgumentException>("binaryForm", () => ObjectAce.CreateFromBinaryForm(new byte[ace.BinaryLength], 1)); 135 } 136 137 [Fact] ObjectAce_GetBinaryForm_Invalid()138 public void ObjectAce_GetBinaryForm_Invalid() 139 { 140 ObjectAce ace = (ObjectAce)ObjectAce_CreateTestData(0, 0, 1, "S-1-5-11", 1, "{73D03E18-5C03-422c-9EC7-C4C5B1CB1612}", "{3CFD5DF9-9146-43c8-BF99-78E7E2DE4BAF}", false, 8, 0)[0]; 141 AssertExtensions.Throws<ArgumentNullException>("binaryForm", () => ace.GetBinaryForm(null, 1)); 142 AssertExtensions.Throws<ArgumentOutOfRangeException>("offset", () => ace.GetBinaryForm(new byte[1], -1)); 143 AssertExtensions.Throws<ArgumentOutOfRangeException>("binaryForm", () => ace.GetBinaryForm(new byte[ace.BinaryLength + 1], 2)); 144 AssertExtensions.Throws<ArgumentOutOfRangeException>("binaryForm", () => ace.GetBinaryForm(new byte[ace.BinaryLength], 1)); 145 } 146 147 [Theory] 148 [MemberData(nameof(ObjectAce_TestObjects))] ObjectAce_GetBinaryForm(GenericAce testAce, byte[] expectedBinaryForm, int testOffset)149 public void ObjectAce_GetBinaryForm(GenericAce testAce, byte[] expectedBinaryForm, int testOffset) 150 { 151 byte[] resultBinaryForm = new byte[testAce.BinaryLength + testOffset]; 152 testAce.GetBinaryForm(resultBinaryForm, testOffset); 153 GenericAce_VerifyBinaryForms(expectedBinaryForm, resultBinaryForm, testOffset); 154 } 155 156 [Theory] 157 [MemberData(nameof(ObjectAce_TestObjects))] ObjectAce_CreateFromBinaryForm(GenericAce expectedAce, byte[] testBinaryForm, int testOffset)158 public void ObjectAce_CreateFromBinaryForm(GenericAce expectedAce, byte[] testBinaryForm, int testOffset) 159 { 160 GenericAce resultAce = ObjectAce.CreateFromBinaryForm(testBinaryForm, testOffset); 161 GenericAce_VerifyAces(expectedAce, resultAce); 162 } 163 } 164 } 165