Skip to content

Commit

Permalink
fix: change from static to instance so tests work
Browse files Browse the repository at this point in the history
  • Loading branch information
rvazarkar committed Oct 8, 2024
1 parent 21b8253 commit 6927f71
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 56 deletions.
12 changes: 6 additions & 6 deletions src/CommonLib/Processors/ACLProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
namespace SharpHoundCommonLib.Processors {
public class ACLProcessor {
private static readonly Dictionary<Label, string> BaseGuids;
private static readonly ConcurrentDictionary<string, string> GuidMap = new();
private readonly ConcurrentDictionary<string, string> _guidMap = new();
private readonly ILogger _log;
private readonly ILdapUtils _utils;
private static readonly ConcurrentHashSet BuiltDomainCaches = new(StringComparer.OrdinalIgnoreCase);
private readonly ConcurrentHashSet _builtDomainCaches = new(StringComparer.OrdinalIgnoreCase);

static ACLProcessor() {
//Create a dictionary with the base GUIDs of each object type
Expand Down Expand Up @@ -76,7 +76,7 @@ private async Task BuildGuidCache(string domain) {

if (name is LDAPProperties.LAPSPassword or LDAPProperties.LegacyLAPSPassword) {
_log.LogInformation("Found GUID for ACL Right {Name}: {Guid} in domain {Domain}", name, guid, domain);
GuidMap.TryAdd(guid, name);
_guidMap.TryAdd(guid, name);
}
} else {
_log.LogDebug("Error while building GUID cache for {Domain}: {Message}", domain, result.Error);
Expand Down Expand Up @@ -227,8 +227,8 @@ public IEnumerable<string> GetInheritedAceHashes(byte[] ntSecurityDescriptor, st
public async IAsyncEnumerable<ACE> ProcessACL(byte[] ntSecurityDescriptor, string objectDomain,
Label objectType,
bool hasLaps, string objectName = "") {
if (!BuiltDomainCaches.Contains(objectDomain)) {
BuiltDomainCaches.Add(objectDomain);
if (!_builtDomainCaches.Contains(objectDomain)) {
_builtDomainCaches.Add(objectDomain);
await BuildGuidCache(objectDomain);
}

Expand Down Expand Up @@ -299,7 +299,7 @@ public async IAsyncEnumerable<ACE> ProcessACL(byte[] ntSecurityDescriptor, strin
aceInheritanceHash = CalculateInheritanceHash(ir, aceRights, aceType, ace.InheritedObjectType());
}

GuidMap.TryGetValue(aceType, out var mappedGuid);
_guidMap.TryGetValue(aceType, out var mappedGuid);

_log.LogTrace("Processing ACE with rights {Rights} and guid {GUID} on object {Name}", aceRights,
aceType, objectName);
Expand Down
100 changes: 50 additions & 50 deletions test/unit/ACLProcessorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1019,56 +1019,56 @@ public async Task ACLProcessor_ProcessACL_GenericWrite_Computer_WriteAllowedToAc
Assert.Equal(actual.RightName, expectedRightName);
}

// [Fact]
// public async Task ACLProcessor_ProcessACL_LAPS_Computer() {
// var expectedPrincipalType = Label.Group;
// var expectedPrincipalSID = "S-1-5-21-3130019616-2776909439-2417379446-512";
// var expectedRightName = EdgeNames.ReadLAPSPassword;
//
// var mockLDAPUtils = new Mock<ILdapUtils>();
// var mockSecurityDescriptor = new Mock<ActiveDirectorySecurityDescriptor>(MockBehavior.Loose, null);
// var mockRule = new Mock<ActiveDirectoryRuleDescriptor>(MockBehavior.Loose, null);
// var collection = new List<ActiveDirectoryRuleDescriptor>();
// mockRule.Setup(x => x.AccessControlType()).Returns(AccessControlType.Allow);
// mockRule.Setup(x => x.IsAceInheritedFrom(It.IsAny<string>())).Returns(true);
// mockRule.Setup(x => x.IdentityReference()).Returns(expectedPrincipalSID);
// mockRule.Setup(x => x.ActiveDirectoryRights()).Returns(ActiveDirectoryRights.ExtendedRight);
// var lapsGuid = Guid.NewGuid();
// mockRule.Setup(x => x.ObjectType()).Returns(lapsGuid);
// collection.Add(mockRule.Object);
//
// mockSecurityDescriptor.Setup(m => m.GetAccessRules(It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<Type>()))
// .Returns(collection);
// mockSecurityDescriptor.Setup(m => m.GetOwner(It.IsAny<Type>())).Returns((string)null);
// mockLDAPUtils.Setup(x => x.MakeSecurityDescriptor()).Returns(mockSecurityDescriptor.Object);
// mockLDAPUtils.Setup(x => x.ResolveIDAndType(It.IsAny<string>(), It.IsAny<string>()))
// .ReturnsAsync((true, new TypedPrincipal(expectedPrincipalSID, expectedPrincipalType)));
//
// //Return a directory object from pagedquery for the schemaid to simulate LAPS
// var searchResults = new[]
// {
// LdapResult<IDirectoryObject>.Ok(new MockDirectoryObject(
// "abc123"
// , new Dictionary<string, object>()
// {
// {LDAPProperties.SchemaIDGUID, lapsGuid.ToByteArray()},
// {LDAPProperties.Name, LDAPProperties.LegacyLAPSPassword}
// }, null,null)),
// };
// mockLDAPUtils.Setup(x => x.PagedQuery(It.IsAny<LdapQueryParameters>(), It.IsAny<CancellationToken>()))
// .Returns(searchResults.ToAsyncEnumerable);
//
// var processor = new ACLProcessor(mockLDAPUtils.Object);
// var bytes = Utils.B64ToBytes(UnProtectedUserNtSecurityDescriptor);
// var result = await processor.ProcessACL(bytes, _testDomainName, Label.Computer, true).ToArrayAsync();
//
// Assert.Single(result);
// var actual = result.First();
// Assert.Equal(actual.PrincipalType, expectedPrincipalType);
// Assert.Equal(actual.PrincipalSID, expectedPrincipalSID);
// Assert.False(actual.IsInherited);
// Assert.Equal(actual.RightName, expectedRightName);
// }
[Fact]
public async Task ACLProcessor_ProcessACL_LAPS_Computer() {
var expectedPrincipalType = Label.Group;
var expectedPrincipalSID = "S-1-5-21-3130019616-2776909439-2417379446-512";
var expectedRightName = EdgeNames.ReadLAPSPassword;

var mockLDAPUtils = new Mock<ILdapUtils>();
var mockSecurityDescriptor = new Mock<ActiveDirectorySecurityDescriptor>(MockBehavior.Loose, null);
var mockRule = new Mock<ActiveDirectoryRuleDescriptor>(MockBehavior.Loose, null);
var collection = new List<ActiveDirectoryRuleDescriptor>();
mockRule.Setup(x => x.AccessControlType()).Returns(AccessControlType.Allow);
mockRule.Setup(x => x.IsAceInheritedFrom(It.IsAny<string>())).Returns(true);
mockRule.Setup(x => x.IdentityReference()).Returns(expectedPrincipalSID);
mockRule.Setup(x => x.ActiveDirectoryRights()).Returns(ActiveDirectoryRights.ExtendedRight);
var lapsGuid = Guid.NewGuid();
mockRule.Setup(x => x.ObjectType()).Returns(lapsGuid);
collection.Add(mockRule.Object);

mockSecurityDescriptor.Setup(m => m.GetAccessRules(It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<Type>()))
.Returns(collection);
mockSecurityDescriptor.Setup(m => m.GetOwner(It.IsAny<Type>())).Returns((string)null);
mockLDAPUtils.Setup(x => x.MakeSecurityDescriptor()).Returns(mockSecurityDescriptor.Object);
mockLDAPUtils.Setup(x => x.ResolveIDAndType(It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync((true, new TypedPrincipal(expectedPrincipalSID, expectedPrincipalType)));

//Return a directory object from pagedquery for the schemaid to simulate LAPS
var searchResults = new[]
{
LdapResult<IDirectoryObject>.Ok(new MockDirectoryObject(
"abc123"
, new Dictionary<string, object>()
{
{LDAPProperties.SchemaIDGUID, lapsGuid.ToByteArray()},
{LDAPProperties.Name, LDAPProperties.LegacyLAPSPassword}
}, null,null)),
};
mockLDAPUtils.Setup(x => x.PagedQuery(It.IsAny<LdapQueryParameters>(), It.IsAny<CancellationToken>()))
.Returns(searchResults.ToAsyncEnumerable);

var processor = new ACLProcessor(mockLDAPUtils.Object);
var bytes = Utils.B64ToBytes(UnProtectedUserNtSecurityDescriptor);
var result = await processor.ProcessACL(bytes, _testDomainName, Label.Computer, true).ToArrayAsync();

Assert.Single(result);
var actual = result.First();
Assert.Equal(actual.PrincipalType, expectedPrincipalType);
Assert.Equal(actual.PrincipalSID, expectedPrincipalSID);
Assert.False(actual.IsInherited);
Assert.Equal(actual.RightName, expectedRightName);
}

[Fact]
public void GetInheritedAceHashes_NullSD_Empty() {
Expand Down

0 comments on commit 6927f71

Please sign in to comment.