mirror of
https://github.com/iterate-ch/cyberduck.git
synced 2026-05-26 19:10:49 +00:00
Add Utils-project for cleaning up stale credentials
This commit is contained in:
+8
-1
@@ -1,6 +1,6 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 18
|
# Visual Studio Version 18
|
||||||
VisualStudioVersion = 18.2.11415.280 d18.0
|
VisualStudioVersion = 18.2.11415.280
|
||||||
MinimumVisualStudioVersion = 15.0.26124.0
|
MinimumVisualStudioVersion = 15.0.26124.0
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8B08EF96-10D6-4F35-94C1-986F9F0F1506}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8B08EF96-10D6-4F35-94C1-986F9F0F1506}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -61,6 +61,8 @@ Project("{DAEA77DE-8320-43BA-BA7C-EF5C12478AB5}") = "Cyberduck.Cryptomator", "cr
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{DAEA77DE-8320-43BA-BA7C-EF5C12478AB5}") = "Cyberduck.Cli", "cli\dll\Cyberduck.Cli.ikvmproj", "{2D33598A-21A1-4117-82DC-250F4CE8D5E5}"
|
Project("{DAEA77DE-8320-43BA-BA7C-EF5C12478AB5}") = "Cyberduck.Cli", "cli\dll\Cyberduck.Cli.ikvmproj", "{2D33598A-21A1-4117-82DC-250F4CE8D5E5}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test-utils", "windows\src\test\utils\test-utils.csproj", "{BBCC0F0C-0135-AAAB-DB32-CC4E28BC88E0}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
@@ -141,6 +143,10 @@ Global
|
|||||||
{2D33598A-21A1-4117-82DC-250F4CE8D5E5}.Debug|x64.Build.0 = Debug|Any CPU
|
{2D33598A-21A1-4117-82DC-250F4CE8D5E5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{2D33598A-21A1-4117-82DC-250F4CE8D5E5}.Release|x64.ActiveCfg = Release|Any CPU
|
{2D33598A-21A1-4117-82DC-250F4CE8D5E5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{2D33598A-21A1-4117-82DC-250F4CE8D5E5}.Release|x64.Build.0 = Release|Any CPU
|
{2D33598A-21A1-4117-82DC-250F4CE8D5E5}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{BBCC0F0C-0135-AAAB-DB32-CC4E28BC88E0}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{BBCC0F0C-0135-AAAB-DB32-CC4E28BC88E0}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{BBCC0F0C-0135-AAAB-DB32-CC4E28BC88E0}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{BBCC0F0C-0135-AAAB-DB32-CC4E28BC88E0}.Release|x64.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -168,6 +174,7 @@ Global
|
|||||||
{9C7B827F-AE30-44C4-A210-E49DF883C720} = {72B4BA09-65D8-4C49-930E-B14104B2AB1B}
|
{9C7B827F-AE30-44C4-A210-E49DF883C720} = {72B4BA09-65D8-4C49-930E-B14104B2AB1B}
|
||||||
{7EFC0398-8F4D-4850-BBE3-A0CC85410559} = {72B4BA09-65D8-4C49-930E-B14104B2AB1B}
|
{7EFC0398-8F4D-4850-BBE3-A0CC85410559} = {72B4BA09-65D8-4C49-930E-B14104B2AB1B}
|
||||||
{2D33598A-21A1-4117-82DC-250F4CE8D5E5} = {72B4BA09-65D8-4C49-930E-B14104B2AB1B}
|
{2D33598A-21A1-4117-82DC-250F4CE8D5E5} = {72B4BA09-65D8-4C49-930E-B14104B2AB1B}
|
||||||
|
{BBCC0F0C-0135-AAAB-DB32-CC4E28BC88E0} = {8B08EF96-10D6-4F35-94C1-986F9F0F1506}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {289E6003-15D5-4377-ADA6-2E7093785BCD}
|
SolutionGuid = {289E6003-15D5-4377-ADA6-2E7093785BCD}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
<PackageVersion Include="ReactiveUI" Version="17.1.50" />
|
<PackageVersion Include="ReactiveUI" Version="17.1.50" />
|
||||||
<PackageVersion Include="ReactiveUI.WPF" Version="17.1.50" />
|
<PackageVersion Include="ReactiveUI.WPF" Version="17.1.50" />
|
||||||
<PackageVersion Include="StructureMap" Version="2.6.4.1" />
|
<PackageVersion Include="StructureMap" Version="2.6.4.1" />
|
||||||
|
<PackageVersion Include="System.CommandLine" Version="2.0.3" />
|
||||||
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
|
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
|
||||||
<PackageVersion Include="System.Memory" Version="4.5.5" />
|
<PackageVersion Include="System.Memory" Version="4.5.5" />
|
||||||
<PackageVersion Include="System.Runtime.Caching" Version="8.0.0" />
|
<PackageVersion Include="System.Runtime.Caching" Version="8.0.0" />
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Windows.Win32;
|
||||||
|
using Windows.Win32.Security.Credentials;
|
||||||
|
using static Program;
|
||||||
|
|
||||||
|
namespace test_utils;
|
||||||
|
|
||||||
|
internal static class CredDeleteCommand
|
||||||
|
{
|
||||||
|
internal static unsafe void Invoke(ParseResult result)
|
||||||
|
{
|
||||||
|
var patternValues = result.GetValue(Program.CredMatch);
|
||||||
|
Regex[] patterns = null;
|
||||||
|
if (patternValues is not null)
|
||||||
|
{
|
||||||
|
patterns = new Regex[patternValues.Length];
|
||||||
|
var patternWriter = ((Span<Regex>)patterns).GetEnumerator();
|
||||||
|
foreach (var item in patternValues)
|
||||||
|
{
|
||||||
|
patternWriter.MoveNext();
|
||||||
|
patternWriter.Current = new Regex(item, RegexOptions.Compiled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CREDENTIALW** credentials = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!PInvoke.CredEnumerate(null, out var count, out credentials))
|
||||||
|
{
|
||||||
|
throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ref readonly var credential in new ReadOnlySpan<PCREDENTIALW>(credentials, (int)count))
|
||||||
|
{
|
||||||
|
bool? matched;
|
||||||
|
if ((matched = patterns?.Any(credential.Value.TargetName.ToString().Match)) is false)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"{credential.Value.TargetName} ({credential.Value.UserName})");
|
||||||
|
if (matched is true)
|
||||||
|
{
|
||||||
|
if (!PInvoke.CredDelete(credential.Value.TargetName, credential.Value.Type, 0))
|
||||||
|
{
|
||||||
|
Console.WriteLine($" Failure deleting: {Marshal.GetLastPInvokeErrorMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
PInvoke.CredFree(credentials);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool Match(this string text, Regex pattern) => pattern.IsMatch(text);
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
CredDelete
|
||||||
|
CredEnumerate
|
||||||
|
CredFree
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System.CommandLine;
|
||||||
|
using test_utils;
|
||||||
|
using Windows.Win32.Security.Credentials;
|
||||||
|
|
||||||
|
RootCommand command = [];
|
||||||
|
|
||||||
|
Command credDeleteCommand = new("cred-delete", "Lists Credentials, and optionally deletes them when matching.");
|
||||||
|
command.Add(credDeleteCommand);
|
||||||
|
credDeleteCommand.SetAction(CredDeleteCommand.Invoke);
|
||||||
|
credDeleteCommand.Add(CredMatch = new("--match")
|
||||||
|
{
|
||||||
|
AllowMultipleArgumentsPerToken = true,
|
||||||
|
Arity = ArgumentArity.ZeroOrMore,
|
||||||
|
Description = "When specified, Cred-Delete will delete items matching any of the Regex patterns."
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return command.Parse(args).Invoke();
|
||||||
|
|
||||||
|
partial class Program
|
||||||
|
{
|
||||||
|
internal static Option<string[]> CredMatch;
|
||||||
|
|
||||||
|
internal readonly unsafe struct PCREDENTIALW
|
||||||
|
{
|
||||||
|
private readonly CREDENTIALW* _ptr;
|
||||||
|
|
||||||
|
public readonly ref CREDENTIALW Value => ref *_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.Net.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0-win</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Windows.CsWin32" />
|
||||||
|
<PackageReference Include="System.CommandLine" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Reference in New Issue
Block a user