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 _logger; public TestController(ICredentialService credentialService, ILogger logger) { _credentialService = credentialService; _logger = logger; } [HttpGet("test-power/{ip}")] public async Task 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(); 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 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 { { "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 }); } } }