< Summary

Class:SharpHoundCommonLib.DirectoryEntryWrapper
Assembly:SharpHoundCommonLib
File(s):D:\a\SharpHoundCommon\SharpHoundCommon\src\CommonLib\DirectoryObjects\DirectoryEntryWrapper.cs
Covered lines:14
Uncovered lines:112
Coverable lines:126
Total lines:188
Line coverage:11.1% (14 of 126)
Covered branches:1
Total branches:44
Branch coverage:2.2% (1 of 44)

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%10100%
TryGetDistinguishedName(...)100%100%
CheckCache(...)0%2075%
TryGetProperty(...)0%600%
TryGetByteProperty(...)0%400%
TryGetArrayProperty(...)0%600%
TryGetByteArrayProperty(...)0%400%
TryGetLongProperty(...)0%400%
TryGetCertificateArrayProperty(...)0%600%
TryGetSecurityIdentifier(...)16.66%6033.33%
TryGetGuid(...)0%200%
GetProperty(...)100%100%
GetByteProperty(...)100%100%
PropertyCount(...)0%200%
PropertyNames()0%200%

File(s)

D:\a\SharpHoundCommon\SharpHoundCommon\src\CommonLib\DirectoryObjects\DirectoryEntryWrapper.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.DirectoryServices;
 4using System.Security.Cryptography.X509Certificates;
 5using System.Security.Principal;
 6using System.Text;
 7
 8namespace SharpHoundCommonLib;
 9
 10public class DirectoryEntryWrapper : IDirectoryObject {
 11    private readonly DirectoryEntry _entry;
 12
 213    public DirectoryEntryWrapper(DirectoryEntry entry) {
 114        _entry = entry;
 115    }
 16
 017    public bool TryGetDistinguishedName(out string value) {
 018        return TryGetProperty(LDAPProperties.DistinguishedName, out value);
 019    }
 20
 121    private bool CheckCache(string propertyName) {
 122        try {
 123            if (!_entry.Properties.Contains(propertyName))
 024                _entry.RefreshCache(new[] { propertyName });
 25
 026            return _entry.Properties.Contains(propertyName);
 27        }
 228        catch {
 129            return false;
 30        }
 131    }
 32
 033    public bool TryGetProperty(string propertyName, out string value) {
 034        value = string.Empty;
 035        if (!CheckCache(propertyName)) {
 036            return false;
 37        }
 38
 039        var s = _entry.Properties[propertyName].Value;
 040        value = s switch {
 041            string st => st,
 042            int i => i.ToString(),
 043            _ => null
 044        };
 45
 046        return value != null;
 047    }
 48
 049    public bool TryGetByteProperty(string propertyName, out byte[] value) {
 050        value = Array.Empty<byte>();
 051        if (!CheckCache(propertyName)) {
 052            return false;
 53        }
 54
 055        var prop = _entry.Properties[propertyName].Value;
 056        if (prop is not byte[] b) return false;
 057        value = b;
 058        return true;
 059    }
 60
 061    public bool TryGetArrayProperty(string propertyName, out string[] value) {
 062        value = Array.Empty<string>();
 063        if (!CheckCache(propertyName)) {
 064            return false;
 65        }
 66
 067        var dest = new List<string>();
 068        foreach (var val in _entry.Properties[propertyName]) {
 069            if (val is string s) {
 070                dest.Add(s);
 071            }
 072        }
 73
 074        value = dest.ToArray();
 075        return true;
 076    }
 77
 078    public bool TryGetByteArrayProperty(string propertyName, out byte[][] value) {
 079        value = Array.Empty<byte[]>();
 080        if (!CheckCache(propertyName)) {
 081            return false;
 82        }
 83
 084        var raw = _entry.Properties[propertyName].Value;
 085        if (raw is not byte[][] b) {
 086            return false;
 87        }
 088        value = b;
 089        return true;
 090    }
 91
 092    public bool TryGetLongProperty(string propertyName, out long value) {
 093        value = 0;
 094        if (!CheckCache(propertyName)) return false;
 95
 096        if (!TryGetProperty(propertyName, out var s)) {
 097            return false;
 98        }
 99
 0100        return long.TryParse(s, out value);
 0101    }
 102
 0103    public bool TryGetCertificateArrayProperty(string propertyName, out X509Certificate2[] value) {
 0104        value = Array.Empty<X509Certificate2>();
 0105        if (!TryGetByteArrayProperty(propertyName, out var bytes)) {
 0106            return false;
 107        }
 108
 0109        if (bytes.Length == 0) {
 0110            return true;
 111        }
 112
 0113        var result = new List<X509Certificate2>();
 114
 0115        foreach (var b in bytes) {
 0116            try {
 0117                var cert = new X509Certificate2(b);
 0118                result.Add(cert);
 0119            }
 0120            catch {
 121                //pass
 0122            }
 0123        }
 124
 0125        value = result.ToArray();
 0126        return true;
 0127    }
 128
 1129    public bool TryGetSecurityIdentifier(out string securityIdentifier) {
 1130        securityIdentifier = string.Empty;
 2131        if (!CheckCache(LDAPProperties.ObjectSID)) {
 1132            return false;
 133        }
 134
 0135        var raw = _entry.Properties[LDAPProperties.ObjectSID][0];
 0136        try {
 0137            securityIdentifier = raw switch {
 0138                byte[] b => new SecurityIdentifier(b, 0).ToString(),
 0139                string st => new SecurityIdentifier(Encoding.ASCII.GetBytes(st), 0).ToString(),
 0140                _ => default
 0141            };
 142
 0143            return securityIdentifier != default;
 144        }
 0145        catch {
 0146            return false;
 147        }
 1148    }
 149
 0150    public bool TryGetGuid(out string guid) {
 0151        guid = string.Empty;
 0152        if (!TryGetByteProperty(LDAPProperties.ObjectGUID, out var raw)) {
 0153            return false;
 154        }
 155
 0156        try {
 0157            guid = new Guid(raw).ToString().ToUpper();
 0158            return true;
 0159        } catch {
 0160            return false;
 161        }
 0162    }
 163
 0164    public string GetProperty(string propertyName) {
 0165        CheckCache(propertyName);
 0166        return _entry.Properties[propertyName].Value as string;
 0167    }
 168
 0169    public byte[] GetByteProperty(string propertyName) {
 0170        CheckCache(propertyName);
 0171        return _entry.Properties[propertyName].Value as byte[];
 0172    }
 173
 0174    public int PropertyCount(string propertyName) {
 0175        if (!CheckCache(propertyName)) {
 0176            return 0;
 177        }
 178
 0179        var prop = _entry.Properties[propertyName];
 0180        return prop.Count;
 181
 0182    }
 183
 0184    public IEnumerable<string> PropertyNames() {
 0185        foreach (var property in _entry.Properties.PropertyNames)
 0186            yield return property.ToString().ToLower();
 0187    }
 188}