266 lines
11 KiB
C#
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 });
|
|
}
|
|
}
|
|
}
|