Add native online success smoke probe

This commit is contained in:
2026-08-31 18:02:28 -06:00
parent 1f43f200b4
commit 289a67e371
@@ -23,9 +23,9 @@ internal static class Program
private static int Main(string[] args) private static int Main(string[] args)
{ {
string mode = args.Length == 0 ? "enumeration" : args.Single(); string mode = args.Length == 0 ? "enumeration" : args.Single();
if (mode is not ("enumeration" or "direct-broker" or "online-rejection" or "offline-fallback")) if (mode is not ("enumeration" or "direct-broker" or "online-rejection" or "online-success" or "offline-fallback"))
{ {
Console.Error.WriteLine("Usage: SGU.CredentialProvider.SmokeProbe.exe [enumeration|direct-broker|online-rejection|offline-fallback]"); Console.Error.WriteLine("Usage: SGU.CredentialProvider.SmokeProbe.exe [enumeration|direct-broker|online-rejection|online-success|offline-fallback]");
return 64; return 64;
} }
@@ -135,10 +135,16 @@ internal static class Program
string[] labelArray = labels.ToArray(); string[] labelArray = labels.ToArray();
uint userNameFieldId = checked((uint)Array.IndexOf(labelArray, "Clave institucional")); uint userNameFieldId = checked((uint)Array.IndexOf(labelArray, "Clave institucional"));
uint passwordFieldId = checked((uint)Array.IndexOf(labelArray, "Contraseña")); uint passwordFieldId = checked((uint)Array.IndexOf(labelArray, "Contraseña"));
string userName = "DO000000"; string userName = mode == "online-success"
string password = mode == "offline-fallback" ? Environment.GetEnvironmentVariable("SGU_TEST_USERNAME")
? $"Probe-{Guid.NewGuid():N}-áΩ" ?? throw new InvalidOperationException("SGU_TEST_USERNAME is required for online-success.")
: $"Probe-{Guid.NewGuid():N}"; : "DO000000";
string password = mode == "online-success"
? Environment.GetEnvironmentVariable("SGU_TEST_PASSWORD")
?? throw new InvalidOperationException("SGU_TEST_PASSWORD is required for online-success.")
: mode == "offline-fallback"
? $"Probe-{Guid.NewGuid():N}-áΩ"
: $"Probe-{Guid.NewGuid():N}";
IntPtr vtable = Marshal.ReadIntPtr(credential); IntPtr vtable = Marshal.ReadIntPtr(credential);
SetStringValueDelegate setStringValue = Marshal.GetDelegateForFunctionPointer<SetStringValueDelegate>( SetStringValueDelegate setStringValue = Marshal.GetDelegateForFunctionPointer<SetStringValueDelegate>(
@@ -162,20 +168,20 @@ internal static class Program
if (mode == "online-rejection") if (mode == "online-rejection")
{ {
bool passed = response == (int)SerializationResponse.NoCredentialNotFinished && bool rejectionPassed = response == (int)SerializationResponse.NoCredentialNotFinished &&
serialization.SerializationData == IntPtr.Zero && serialization.SerializationData == IntPtr.Zero &&
statusIcon == (int)StatusIcon.Error && statusIcon == (int)StatusIcon.Error &&
statusText == "Credenciales institucionales inválidas."; statusText == "Credenciales institucionales inválidas.";
Console.WriteLine(JsonSerializer.Serialize(new Console.WriteLine(JsonSerializer.Serialize(new
{ {
passed, passed = rejectionPassed,
mode, mode,
response = (SerializationResponse)response, response = (SerializationResponse)response,
statusIcon = (StatusIcon)statusIcon, statusIcon = (StatusIcon)statusIcon,
statusText, statusText,
credentialReturned = serialization.SerializationData != IntPtr.Zero credentialReturned = serialization.SerializationData != IntPtr.Zero
})); }));
return passed ? 0 : 1; return rejectionPassed ? 0 : 1;
} }
KerberosInteractiveUnlockLogon logon = serialization.SerializationData == IntPtr.Zero KerberosInteractiveUnlockLogon logon = serialization.SerializationData == IntPtr.Zero
@@ -187,17 +193,20 @@ internal static class Program
bool passwordPreserved = string.Equals(packedPassword, password, StringComparison.Ordinal); bool passwordPreserved = string.Equals(packedPassword, password, StringComparison.Ordinal);
packedPassword = string.Empty; packedPassword = string.Empty;
bool fallbackPassed = response == (int)SerializationResponse.ReturnCredentialFinished && bool serializedCredentialPassed = response == (int)SerializationResponse.ReturnCredentialFinished &&
serialization.SerializationData != IntPtr.Zero && serialization.SerializationData != IntPtr.Zero &&
serialization.SerializationSize > 0 && serialization.SerializationSize > 0 &&
statusIcon == (int)StatusIcon.Warning &&
statusText == "Servicio institucional no disponible; Windows validará la última contraseña de dominio registrada." &&
string.Equals(packedDomain, "LCI", StringComparison.Ordinal) && string.Equals(packedDomain, "LCI", StringComparison.Ordinal) &&
string.Equals(packedUserName, userName, StringComparison.Ordinal) && string.Equals(packedUserName, userName, StringComparison.Ordinal) &&
passwordPreserved; passwordPreserved;
bool passed = mode == "online-success"
? serializedCredentialPassed && statusIcon == (int)StatusIcon.None && string.IsNullOrEmpty(statusText)
: serializedCredentialPassed &&
statusIcon == (int)StatusIcon.Warning &&
statusText == "Servicio institucional no disponible; Windows validará la última contraseña de dominio registrada.";
Console.WriteLine(JsonSerializer.Serialize(new Console.WriteLine(JsonSerializer.Serialize(new
{ {
passed = fallbackPassed, passed,
mode, mode,
response = (SerializationResponse)response, response = (SerializationResponse)response,
statusIcon = (StatusIcon)statusIcon, statusIcon = (StatusIcon)statusIcon,
@@ -207,7 +216,7 @@ internal static class Program
passwordPreserved, passwordPreserved,
serializationSize = serialization.SerializationSize serializationSize = serialization.SerializationSize
})); }));
return fallbackPassed ? 0 : 1; return passed ? 0 : 1;
} }
finally finally
{ {