266 lines
11 KiB
C#

using AmtScanner.Api.Services;
using Microsoft.AspNetCore.Mvc;
using System.Security;
using Intel.Management.Wsman;
namespace AmtScanner.Api.Controllers;
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
private readonly ICredentialService _credentialService;
private readonly ILogger<TestController> _logger;
public TestController(ICredentialService credentialService, ILogger<TestController> logger)
{
_credentialService = credentialService;
_logger = logger;
}
[HttpGet("test-power/{ip}")]
public async Task<IActionResult> TestPower(string ip, [FromQuery] string protocol = "http", [FromQuery] int port = 16992)
{
try
{
var credential = await _credentialService.GetDefaultCredentialAsync();
if (credential == null)
{
return BadRequest(new { error = "No default credential found." });
}
var username = credential.Username;
var password = _credentialService.DecryptPassword(credential.Password);
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
securePassword.MakeReadOnly();
var result = new Dictionary<string, object>();
var connection = new WsmanConnection();
connection.Address = $"{protocol}://{ip}:{port}/wsman";
connection.SetCredentials(username, securePassword);
if (protocol == "https")
{
connection.Options.ServerCertificateValidationCallback = (certificate, sslPolicyErrors) =>
{
if (certificate.Subject.Equals(certificate.Issuer))
return true;
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
return true;
return false;
};
}
await Task.Run(() =>
{
try
{
// 方法1: 使用 NewReference 和 Enumerate
_logger.LogInformation("Testing power state query method 1...");
var computerSysRef = connection.NewReference("SELECT * FROM CIM_ComputerSystem WHERE Name='ManagedSystem'");
var associatedPowerMgmtRef = connection.NewReference("CIM_AssociatedPowerManagementService");
associatedPowerMgmtRef.AddSelector("UserOfService", computerSysRef);
foreach (IWsmanItem item in associatedPowerMgmtRef.Enumerate(
"http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter", null))
{
if (item.Object.GetProperty("ServiceProvided").IsA("CIM_PowerManagementService"))
{
var powerState = Convert.ToInt32(item.Object.GetProperty("PowerState").ToString());
result["method1_powerState"] = powerState;
result["method1_success"] = true;
break;
}
}
}
catch (Exception ex)
{
result["method1_error"] = ex.Message;
result["method1_success"] = false;
}
try
{
// 方法2: 直接查询 CIM_PowerManagementService
_logger.LogInformation("Testing power state query method 2...");
var query = connection.ExecQuery("SELECT * FROM CIM_PowerManagementService");
foreach (IWsmanItem item in query)
{
result["method2_found"] = true;
result["method2_xml"] = item.Object.Xml;
break;
}
}
catch (Exception ex)
{
result["method2_error"] = ex.Message;
}
try
{
// 方法3: 查询 AMT_BootCapabilities 测试连接
_logger.LogInformation("Testing AMT_BootCapabilities query...");
var query = connection.ExecQuery("SELECT * FROM AMT_BootCapabilities");
foreach (IWsmanItem item in query)
{
result["method3_found"] = true;
break;
}
}
catch (Exception ex)
{
result["method3_error"] = ex.Message;
}
});
return Ok(result);
}
catch (Exception ex)
{
return StatusCode(500, new { error = ex.Message });
}
}
[HttpGet("test-connection/{ip}")]
public async Task<IActionResult> TestConnection(string ip, [FromQuery] string protocol = "http", [FromQuery] int port = 16992)
{
try
{
var credential = await _credentialService.GetDefaultCredentialAsync();
if (credential == null)
{
return BadRequest(new { error = "No default credential found. Please add a credential first." });
}
var username = credential.Username;
var password = _credentialService.DecryptPassword(credential.Password);
_logger.LogInformation("Testing connection to {Protocol}://{Ip}:{Port} with username: {Username}", protocol, ip, port, username);
// Convert password to SecureString
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
securePassword.MakeReadOnly();
var result = new Dictionary<string, object>
{
{ "ip", ip },
{ "protocol", protocol },
{ "port", port },
{ "username", username },
{ "passwordLength", password.Length }
};
// Create WS-Management connection using Intel SDK
var connection = new WsmanConnection();
connection.Address = $"{protocol}://{ip}:{port}/wsman";
connection.SetCredentials(username, securePassword);
// Accept self-signed certificates for HTTPS connections
if (protocol == "https")
{
connection.Options.ServerCertificateValidationCallback = (certificate, sslPolicyErrors) =>
{
// If certificate is self-signed, ignore all errors
if (certificate.Subject.Equals(certificate.Issuer))
{
return true;
}
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
return true;
}
return false;
};
}
await Task.Run(() =>
{
try
{
// Test connection with Identify
_logger.LogInformation("Sending Identify request to {Ip}", ip);
var identify = connection.Identify();
result["identifySuccess"] = true;
result["identifyResult"] = identify.Xml;
// Query AMT version
_logger.LogInformation("Querying AMT version from {Ip}", ip);
var versionQuery = connection.ExecQuery("SELECT * FROM CIM_SoftwareIdentity WHERE InstanceID='AMT'");
foreach (Intel.Management.Wsman.IWsmanItem item in versionQuery)
{
var versionProp = item.Object.GetProperty("VersionString");
if (!versionProp.IsNull)
{
result["amtVersion"] = versionProp.ToString();
_logger.LogInformation("AMT Version: {Version}", versionProp.ToString());
break;
}
}
// Query AMT general settings
_logger.LogInformation("Querying AMT general settings from {Ip}", ip);
var settingsQuery = connection.ExecQuery("SELECT * FROM AMT_GeneralSettings");
foreach (Intel.Management.Wsman.IWsmanItem item in settingsQuery)
{
var hostnameProp = item.Object.GetProperty("HostName");
if (!hostnameProp.IsNull)
{
result["hostname"] = hostnameProp.ToString();
_logger.LogInformation("Hostname: {Hostname}", hostnameProp.ToString());
}
break;
}
// Query provisioning state
_logger.LogInformation("Querying provisioning state from {Ip}", ip);
var setupQuery = connection.ExecQuery("SELECT * FROM AMT_SetupAndConfigurationService");
foreach (Intel.Management.Wsman.IWsmanItem item in setupQuery)
{
var stateProp = item.Object.GetProperty("ProvisioningState");
if (!stateProp.IsNull)
{
var state = int.Parse(stateProp.ToString());
result["provisioningState"] = state;
result["provisioningStateName"] = state switch
{
0 => "PRE",
1 => "IN",
2 => "POST",
_ => "UNKNOWN"
};
_logger.LogInformation("Provisioning State: {State}", state);
}
break;
}
result["success"] = true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error testing connection to {Ip}", ip);
result["success"] = false;
result["error"] = ex.Message;
result["errorType"] = ex.GetType().Name;
}
});
return Ok(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in test endpoint");
return StatusCode(500, new { error = ex.Message, type = ex.GetType().Name });
}
}
}