big changes
This commit is contained in:
+126
@@ -0,0 +1,126 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ZA.CoreService.ESBCertificateManager.Services;
|
||||
|
||||
public sealed class WindowsCredentialManagerSecretProvider
|
||||
: ISecretProvider
|
||||
{
|
||||
private const uint GenericCredentialType = 1;
|
||||
private const int ErrorNotFound = 1168;
|
||||
|
||||
public StoredCredential GetCredential(
|
||||
string credentialReference)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(credentialReference))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Die CredentialReference ist nicht konfiguriert.",
|
||||
nameof(credentialReference));
|
||||
}
|
||||
|
||||
bool success = CredRead(
|
||||
credentialReference,
|
||||
GenericCredentialType,
|
||||
0,
|
||||
out IntPtr credentialPointer);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
int errorCode = Marshal.GetLastWin32Error();
|
||||
|
||||
if (errorCode == ErrorNotFound)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Die Windows-Anmeldeinformation " +
|
||||
$"'{credentialReference}' wurde nicht gefunden.");
|
||||
}
|
||||
|
||||
throw new Win32Exception(
|
||||
errorCode,
|
||||
"Die Windows-Anmeldeinformation konnte nicht gelesen werden.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
NativeCredential nativeCredential =
|
||||
Marshal.PtrToStructure<NativeCredential>(
|
||||
credentialPointer);
|
||||
|
||||
string userName =
|
||||
Marshal.PtrToStringUni(nativeCredential.UserName)
|
||||
?? string.Empty;
|
||||
|
||||
string secret = string.Empty;
|
||||
|
||||
if (nativeCredential.CredentialBlob != IntPtr.Zero
|
||||
&& nativeCredential.CredentialBlobSize > 0)
|
||||
{
|
||||
int characterCount = checked(
|
||||
(int)nativeCredential.CredentialBlobSize / 2);
|
||||
|
||||
secret = Marshal.PtrToStringUni(
|
||||
nativeCredential.CredentialBlob,
|
||||
characterCount)
|
||||
?? string.Empty;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(userName))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Die Windows-Anmeldeinformation " +
|
||||
$"'{credentialReference}' enthält keinen Benutzernamen.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(secret))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Die Windows-Anmeldeinformation " +
|
||||
$"'{credentialReference}' enthält kein Kennwort.");
|
||||
}
|
||||
|
||||
return new StoredCredential(
|
||||
userName,
|
||||
secret);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CredFree(credentialPointer);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(
|
||||
"advapi32.dll",
|
||||
EntryPoint = "CredReadW",
|
||||
CharSet = CharSet.Unicode,
|
||||
SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool CredRead(
|
||||
string target,
|
||||
uint type,
|
||||
int reservedFlag,
|
||||
out IntPtr credentialPointer);
|
||||
|
||||
[DllImport("advapi32.dll")]
|
||||
private static extern void CredFree(
|
||||
IntPtr credentialPointer);
|
||||
|
||||
[StructLayout(
|
||||
LayoutKind.Sequential,
|
||||
CharSet = CharSet.Unicode)]
|
||||
private struct NativeCredential
|
||||
{
|
||||
public uint Flags;
|
||||
public uint Type;
|
||||
public IntPtr TargetName;
|
||||
public IntPtr Comment;
|
||||
public long LastWritten;
|
||||
public uint CredentialBlobSize;
|
||||
public IntPtr CredentialBlob;
|
||||
public uint Persist;
|
||||
public uint AttributeCount;
|
||||
public IntPtr Attributes;
|
||||
public IntPtr TargetAlias;
|
||||
public IntPtr UserName;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user