Skip to content

Commit bbf2f26

Browse files
authored
fix: add adaptive timeouts to missing portions of enumeration (#261)
* fix: add adaptive timeouts to missing portions of enumeration * chore: add a comment about these nested result objects * fix: return a APIResult
1 parent dec61f6 commit bbf2f26

3 files changed

Lines changed: 19 additions & 6 deletions

File tree

src/CommonLib/IRegistryKey.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ public static async Task<SHRegistryKey> Connect(RegistryHive hive, string machin
3939
var remoteKey = await _adaptiveTimeout.ExecuteWithTimeout((_) => RegistryKey.OpenRemoteBaseKey(hive, machineName));
4040
if (remoteKey.IsSuccess)
4141
return new SHRegistryKey(remoteKey.Value);
42-
else
43-
throw new TimeoutException($"Failed to connect to registry on {machineName}: {remoteKey.Error}");
42+
throw new TimeoutException($"Failed to connect to registry on {machineName}: {remoteKey.Error}");
4443
}
4544

4645
public void Dispose() {

src/CommonLib/Processors/RegistryProcessor.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class RegistryProcessor {
1515
private readonly IPortScanner _portScanner;
1616
private readonly ICollectionStrategy<RegistryQueryResult, RegistryQuery>[] _strategies;
1717
private readonly RegistryQuery[] _queries;
18+
private readonly AdaptiveTimeout _registryAdaptiveTimeout = new(maxTimeout:TimeSpan.FromMinutes(2), Logging.LogProvider.CreateLogger(nameof(ReadRegistrySettings)));
1819

1920
public RegistryProcessor(ILogger log, string domain) {
2021
_log = log ?? Logging.LogProvider.CreateLogger("RegistryProcessor");
@@ -54,9 +55,15 @@ public async Task<APIResult<RegistryData>> ReadRegistrySettings(string targetMac
5455

5556
try {
5657
var registryCollector = new StrategyExecutor();
57-
var collectedData = await registryCollector
58+
var result = await _registryAdaptiveTimeout.ExecuteWithTimeout(async (_) => await registryCollector
5859
.CollectAsync(targetMachine, _queries, _strategies)
59-
.ConfigureAwait(false);
60+
.ConfigureAwait(false));
61+
62+
if (!result.IsSuccess) {
63+
return APIResult<RegistryData>.Failure($"Timeout when grabbing registry data from {targetMachine}");
64+
}
65+
66+
var collectedData = result.Value;
6067

6168
foreach (var key in collectedData.Results ?? []) {
6269
if (!key.ValueExists)

src/CommonLib/Processors/WebClientServiceProcessor.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace SharpHoundCommonLib.Processors {
1616
/// <param name="log"></param>
1717
public class WebClientServiceProcessor(ILogger log = null) {
1818
private readonly ILogger _log = log ?? Logging.LogProvider.CreateLogger("WebClientServiceProcessor");
19+
private readonly AdaptiveTimeout _createFileAdaptiveTimeout = new(maxTimeout:TimeSpan.FromMinutes(2), Logging.LogProvider.CreateLogger(nameof(IsWebClientRunning)));
1920

2021
// Define constants
2122
public const uint MAXIMUM_ALLOWED = 0x02000000;
@@ -78,15 +79,21 @@ public async Task<APIResult<bool>> IsWebClientRunning(string computerName) {
7879
// When the service is running, this named pipe is present
7980
var pipePath = @$"\\{computerName}\pipe\DAV RPC SERVICE";
8081

81-
return await Task.Run(() => {
82+
var result = await _createFileAdaptiveTimeout.ExecuteWithTimeout((_) => {
8283
try {
8384
var exists = TestPathExists(pipePath);
84-
8585
return APIResult<bool>.Success(exists);
8686
} catch (Exception ex) {
8787
return APIResult<bool>.Failure(ex.ToString());
8888
}
8989
});
90+
91+
//TODO: Not a big fan of nested result objects. We should look at this later to see if we can simplify the interface
92+
if (result.IsSuccess) {
93+
return result.Value;
94+
}
95+
96+
return APIResult<bool>.Failure($"Failed to check pipe on {computerName} due to timeout: {pipePath}");
9097
}
9198
}
9299
}

0 commit comments

Comments
 (0)