diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index 1e8ca4f8..d1cd0a65 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -1,29 +1,41 @@ package hirs.attestationca; import com.google.protobuf.ByteString; - import com.google.protobuf.InvalidProtocolBufferException; +import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2; import hirs.attestationca.exceptions.CertificateProcessingException; import hirs.attestationca.exceptions.IdentityProcessingException; import hirs.attestationca.exceptions.UnexpectedServerException; +import hirs.attestationca.service.SupplyChainValidationService; import hirs.data.persist.AppraisalStatus; -import hirs.data.persist.BIOSComponentInfo; -import hirs.data.persist.BaseboardComponentInfo; -import hirs.data.persist.ChassisComponentInfo; import hirs.data.persist.Device; import hirs.data.persist.DeviceInfoReport; import hirs.data.persist.FirmwareInfo; -import hirs.data.persist.HardDriveComponentInfo; import hirs.data.persist.HardwareInfo; -import hirs.data.persist.MemoryComponentInfo; -import hirs.data.persist.NICComponentInfo; import hirs.data.persist.NetworkInfo; import hirs.data.persist.OSInfo; -import hirs.data.persist.ProcessorComponentInfo; import hirs.data.persist.SupplyChainValidationSummary; import hirs.data.persist.TPMInfo; +import hirs.data.persist.certificate.Certificate; +import hirs.data.persist.certificate.EndorsementCredential; +import hirs.data.persist.certificate.IssuedAttestationCertificate; +import hirs.data.persist.certificate.PlatformCredential; +import hirs.data.service.DeviceRegister; +import hirs.persist.CertificateManager; import hirs.persist.DBManager; +import hirs.persist.DeviceManager; import hirs.persist.TPM2ProvisionerState; +import hirs.structs.converters.SimpleStructBuilder; +import hirs.structs.converters.StructConverter; +import hirs.structs.elements.aca.IdentityRequestEnvelope; +import hirs.structs.elements.aca.IdentityResponseEnvelope; +import hirs.structs.elements.aca.SymmetricAttestation; +import hirs.structs.elements.tpm.EncryptionScheme; +import hirs.structs.elements.tpm.IdentityProof; +import hirs.structs.elements.tpm.IdentityRequest; +import hirs.structs.elements.tpm.SymmetricKey; +import hirs.structs.elements.tpm.SymmetricKeyParams; +import hirs.utils.HexUtils; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.ArrayUtils; import org.apache.logging.log4j.LogManager; @@ -73,28 +85,6 @@ import java.util.Date; import java.util.HashSet; import java.util.Set; -import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2; -import hirs.attestationca.service.SupplyChainValidationService; -import hirs.data.persist.certificate.Certificate; -import hirs.data.persist.certificate.EndorsementCredential; -import hirs.data.persist.certificate.IssuedAttestationCertificate; -import hirs.data.persist.certificate.PlatformCredential; -import hirs.data.service.DeviceRegister; -import hirs.persist.CertificateManager; -import hirs.persist.DeviceManager; -import hirs.structs.converters.SimpleStructBuilder; -import hirs.structs.converters.StructConverter; -import hirs.structs.elements.aca.IdentityRequestEnvelope; -import hirs.structs.elements.aca.IdentityResponseEnvelope; -import hirs.structs.elements.aca.SymmetricAttestation; -import hirs.structs.elements.tpm.EncryptionScheme; -import hirs.structs.elements.tpm.IdentityProof; -import hirs.structs.elements.tpm.IdentityRequest; -import hirs.structs.elements.tpm.SymmetricKey; -import hirs.structs.elements.tpm.SymmetricKeyParams; - -import hirs.utils.HexUtils; - /** * Provides base implementation of common tasks of an ACA that are required for attestation of an * Identity Request. @@ -612,61 +602,7 @@ public abstract class AbstractAttestationCertificateAuthority // Create final report DeviceInfoReport dvReport = new DeviceInfoReport(nw, os, fw, hw, tpm, claim.getClientVersion()); - - for (ProvisionerTpm2.ComponentInfo pbCompInfo : hwProto.getChassisInfoList()) { - dvReport.getChassisInfo().add(new ChassisComponentInfo( - pbCompInfo.getManufacturer(), - pbCompInfo.getModel(), - pbCompInfo.getSerialNumber(), - pbCompInfo.getRevision())); - } - - for (ProvisionerTpm2.ComponentInfo pbCompInfo : hwProto.getBaseboardInfoList()) { - dvReport.getBaseboardInfo().add(new BaseboardComponentInfo( - pbCompInfo.getManufacturer(), - pbCompInfo.getModel(), - pbCompInfo.getSerialNumber(), - pbCompInfo.getRevision())); - } - - for (ProvisionerTpm2.ComponentInfo pbCompInfo : hwProto.getProcessorInfoList()) { - dvReport.getProcessorInfo().add(new ProcessorComponentInfo( - pbCompInfo.getManufacturer(), - pbCompInfo.getModel(), - pbCompInfo.getSerialNumber(), - pbCompInfo.getRevision())); - } - - for (ProvisionerTpm2.ComponentInfo pbCompInfo : hwProto.getBiosOrUefiInfoList()) { - dvReport.getBiosInfo().add(new BIOSComponentInfo( - pbCompInfo.getManufacturer(), - pbCompInfo.getModel(), - pbCompInfo.getRevision())); - } - - for (ProvisionerTpm2.ComponentInfo pbCompInfo : hwProto.getNicInfoList()) { - dvReport.getNicInfo().add(new NICComponentInfo( - pbCompInfo.getManufacturer(), - pbCompInfo.getModel(), - pbCompInfo.getSerialNumber(), - pbCompInfo.getRevision())); - } - - for (ProvisionerTpm2.ComponentInfo pbCompInfo : hwProto.getHardDriveInfoList()) { - dvReport.getHardDriveInfo().add(new HardDriveComponentInfo( - pbCompInfo.getManufacturer(), - pbCompInfo.getModel(), - pbCompInfo.getSerialNumber(), - pbCompInfo.getRevision())); - } - - for (ProvisionerTpm2.ComponentInfo pbCompInfo : hwProto.getMemoryInfoList()) { - dvReport.getMemoryInfo().add(new MemoryComponentInfo( - pbCompInfo.getManufacturer(), - pbCompInfo.getModel(), - pbCompInfo.getSerialNumber(), - pbCompInfo.getRevision())); - } + dvReport.setPaccorOutputString(claim.getPaccorOutput()); return dvReport; } diff --git a/HIRS_Provisioner/src/test/java/hirs/client/collector/DeviceInfoCollectorTest.java b/HIRS_Provisioner/src/test/java/hirs/client/collector/DeviceInfoCollectorTest.java new file mode 100644 index 00000000..88938e6f --- /dev/null +++ b/HIRS_Provisioner/src/test/java/hirs/client/collector/DeviceInfoCollectorTest.java @@ -0,0 +1,376 @@ +package hirs.client.collector; + +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.testng.PowerMockTestCase; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.Enumeration; +import hirs.DeviceInfoReportRequest; +import hirs.collector.CollectorException; +import hirs.data.persist.DeviceInfoReport; +import hirs.data.persist.OSName; + +/** + * Unit tests for DeviceInfoCollector. + */ +@PrepareForTest(DeviceInfoCollector.class) +public class DeviceInfoCollectorTest extends PowerMockTestCase { + + private DeviceInfoCollector collector; + + /** + * Prepares a test environment for each individual test. + * + * @throws CollectorException should not be thrown here as all collection is mocked + */ + @BeforeMethod + public void beforeMethod() throws CollectorException { + collector = spy(new DeviceInfoCollector()); + PowerMockito.mockStatic(DeviceInfoCollector.class); + + // mock out serial number collection as it requires root + when(DeviceInfoCollector.collectDmiDecodeValue( + any(OSName.class), anyString())).thenReturn("some string"); + doReturn("Linux").when(collector).getSystemProperty(eq("os.name")); + } + + /** + * Tests that a DeviceInfoCollector will generate a DeviceInfoReport. + * + * @throws Exception if an error occurs creating mocked output + */ + @Test + public final void testCollect() throws Exception { + final DeviceInfoReportRequest request = new DeviceInfoReportRequest(); + final DeviceInfoReport report = + (DeviceInfoReport) collector.collect(request); + final int numberOfDmiDecodeCalls = 9; + + // the following two lines assert that collectDmiDecodeValue was called 9 times + PowerMockito.verifyStatic(times(numberOfDmiDecodeCalls)); + DeviceInfoCollector.collectDmiDecodeValue(any(OSName.class), anyString()); + + Assert.assertNotNull(report.getNetworkInfo()); + Assert.assertNotNull(report.getOSInfo()); + + // Test the IP address in the report against the system that created it + Enumeration interfaces = + NetworkInterface.getNetworkInterfaces(); + boolean equivalenceFound = false; + while (interfaces.hasMoreElements()) { + NetworkInterface netInt = interfaces.nextElement(); + Enumeration addresses = netInt.getInetAddresses(); + while (addresses.hasMoreElements()) { + InetAddress address = addresses.nextElement(); + if (address.getHostAddress().equals( + report.getNetworkInfo().getIpAddress(). + getHostAddress())) { + equivalenceFound = true; + } + } + } + Assert.assertTrue(equivalenceFound); + } + + + /** + * Tests that hardware and firmware info is set correctly. + * + * @throws CollectorException should not be thrown here as all collection is mocked + */ + @Test + public final void testCollectProperInfo() throws CollectorException { + DeviceInfoCollector mockedCollector = spy(DeviceInfoCollector.class); + PowerMockito.mockStatic(DeviceInfoCollector.class); + + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-manufacturer")).thenReturn("Manufacturer"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-product-name")).thenReturn("Product name"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-serial-number")).thenReturn("Serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "chassis-serial-number")).thenReturn("Chassis serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "baseboard-serial-number")).thenReturn("Baseboard serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-version")).thenReturn("Version"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-vendor")).thenReturn("Bios vendor"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-version")).thenReturn("Bios version"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-release-date")).thenReturn("Bios release date"); + + doReturn("Linux").when(mockedCollector).getSystemProperty("os.name"); + + final DeviceInfoReportRequest request = new DeviceInfoReportRequest(); + DeviceInfoReport report = (DeviceInfoReport) mockedCollector.doCollect(request); + Assert.assertEquals(report.getHardwareInfo().getManufacturer(), + "Manufacturer"); + Assert.assertEquals(report.getHardwareInfo().getProductName(), + "Product name"); + Assert.assertEquals(report.getHardwareInfo().getSystemSerialNumber(), + "Serial number"); + Assert.assertEquals(report.getHardwareInfo().getChassisSerialNumber(), + "Chassis serial number"); + Assert.assertEquals(report.getHardwareInfo().getBaseboardSerialNumber(), + "Baseboard serial number"); + Assert.assertEquals(report.getHardwareInfo().getVersion(), + "Version"); + Assert.assertEquals(report.getFirmwareInfo().getBiosVendor(), + "Bios vendor"); + Assert.assertEquals(report.getFirmwareInfo().getBiosVersion(), + "Bios version"); + Assert.assertEquals(report.getFirmwareInfo().getBiosReleaseDate(), + "Bios release date"); + + } + + /** + * Tests that null hardware info is set to "Not specified". + * + * @throws CollectorException should not be thrown here as all collection is mocked + */ + @Test + public final void testCollectNullHardwareInfo() throws CollectorException { + DeviceInfoCollector mockedCollector = spy(DeviceInfoCollector.class); + PowerMockito.mockStatic(DeviceInfoCollector.class); + + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-manufacturer")).thenReturn(null); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-product-name")).thenReturn(null); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-serial-number")).thenReturn(null); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "chassis-serial-number")).thenReturn(null); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "baseboard-serial-number")).thenReturn(null); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-version")).thenReturn(null); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-vendor")).thenReturn("Bios vendor"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-version")).thenReturn("Bios version"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-release-date")).thenReturn("Bios release date"); + + doReturn("Linux").when(mockedCollector).getSystemProperty("os.name"); + + final DeviceInfoReportRequest request = new DeviceInfoReportRequest(); + DeviceInfoReport report = (DeviceInfoReport) mockedCollector.doCollect(request); + + Assert.assertEquals(report.getHardwareInfo().getManufacturer(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getProductName(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getSystemSerialNumber(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getChassisSerialNumber(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getBaseboardSerialNumber(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getVersion(), + DeviceInfoCollector.NOT_SPECIFIED); + + } + + /** + * Tests that empty hardware info is set to "Not specified". + * + * @throws CollectorException should not be thrown here as all collection is mocked + */ + @Test + public final void testCollectEmptyHardwareInfo() throws CollectorException { + DeviceInfoCollector mockedCollector = spy(DeviceInfoCollector.class); + PowerMockito.mockStatic(DeviceInfoCollector.class); + + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-manufacturer")).thenReturn(""); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-product-name")).thenReturn(""); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-serial-number")).thenReturn(""); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "chassis-serial-number")).thenReturn(""); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "baseboard-serial-number")).thenReturn(""); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-version")).thenReturn(""); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-vendor")).thenReturn("Bios vendor"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-version")).thenReturn("Bios version"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-release-date")).thenReturn("Bios release date"); + + doReturn("Linux").when(mockedCollector).getSystemProperty("os.name"); + + final DeviceInfoReportRequest request = new DeviceInfoReportRequest(); + DeviceInfoReport report = (DeviceInfoReport) mockedCollector.doCollect(request); + + Assert.assertEquals(report.getHardwareInfo().getManufacturer(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getProductName(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getSystemSerialNumber(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getChassisSerialNumber(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getBaseboardSerialNumber(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getHardwareInfo().getVersion(), + DeviceInfoCollector.NOT_SPECIFIED); + + } + + /** + * Tests that null firmware info is set to "Not specified". + * + * @throws CollectorException should not be thrown here as all collection is mocked + */ + @Test + public final void testCollectNullFirmwareInfo() throws CollectorException { + DeviceInfoCollector mockedCollector = spy(DeviceInfoCollector.class); + PowerMockito.mockStatic(DeviceInfoCollector.class); + + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-manufacturer")).thenReturn("Manufacturer"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-product-name")).thenReturn("Product name"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-serial-number")).thenReturn("Serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "chassis-serial-number")).thenReturn("Chassis serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "baseboard-serial-number")).thenReturn("Baseboard serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-version")).thenReturn("Version"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-vendor")).thenReturn(null); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-version")).thenReturn(null); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-release-date")).thenReturn(null); + + doReturn("Linux").when(mockedCollector).getSystemProperty("os.name"); + + final DeviceInfoReportRequest request = new DeviceInfoReportRequest(); + DeviceInfoReport report = (DeviceInfoReport) mockedCollector.doCollect(request); + + Assert.assertEquals(report.getFirmwareInfo().getBiosVendor(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getFirmwareInfo().getBiosVersion(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getFirmwareInfo().getBiosReleaseDate(), + DeviceInfoCollector.NOT_SPECIFIED); + + } + + /** + * Tests that empty firmware info is set to "Not specified". + * + * @throws CollectorException should not be thrown here as all collection is mocked + */ + @Test + public final void testCollectEmptyFirmwareInfo() throws CollectorException { + DeviceInfoCollector mockedCollector = spy(DeviceInfoCollector.class); + PowerMockito.mockStatic(DeviceInfoCollector.class); + + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-manufacturer")).thenReturn("Manufacturer"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-product-name")).thenReturn("Product name"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-serial-number")).thenReturn("Serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "chassis-serial-number")).thenReturn("Chassis serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "baseboard-serial-number")).thenReturn("Baseboard serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-version")).thenReturn("Version"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-vendor")).thenReturn(""); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-version")).thenReturn(""); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-release-date")).thenReturn(""); + + doReturn("Linux").when(mockedCollector).getSystemProperty("os.name"); + + final DeviceInfoReportRequest request = new DeviceInfoReportRequest(); + DeviceInfoReport report = (DeviceInfoReport) mockedCollector.doCollect(request); + + Assert.assertEquals(report.getFirmwareInfo().getBiosVendor(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getFirmwareInfo().getBiosVersion(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getFirmwareInfo().getBiosReleaseDate(), + DeviceInfoCollector.NOT_SPECIFIED); + + } + + /** + * Tests that null OS info is set to "Not specified". + * + * @throws CollectorException should not be thrown here as all collection is mocked + */ + @Test + public final void testCollectNullOSInfo() throws CollectorException { + DeviceInfoCollector mockedCollector = spy(DeviceInfoCollector.class); + PowerMockito.mockStatic(DeviceInfoCollector.class); + + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-manufacturer")).thenReturn("Manufacturer"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-product-name")).thenReturn("Product name"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-serial-number")).thenReturn("Serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "chassis-serial-number")).thenReturn("Chassis serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "baseboard-serial-number")).thenReturn("Baseboard serial number"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "system-version")).thenReturn("Version"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-vendor")).thenReturn("Bios vendor"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-version")).thenReturn("Bios version"); + when(DeviceInfoCollector.collectDmiDecodeValue( + OSName.LINUX, "bios-release-date")).thenReturn("Bios release date"); + + doReturn("Unknown").when(mockedCollector).getSystemProperty("os.name"); + + final DeviceInfoReportRequest request = new DeviceInfoReportRequest(); + DeviceInfoReport report = (DeviceInfoReport) mockedCollector.doCollect(request); + + Assert.assertEquals(report.getOSInfo().getDistribution(), + DeviceInfoCollector.NOT_SPECIFIED); + Assert.assertEquals(report.getOSInfo().getDistributionRelease(), + DeviceInfoCollector.NOT_SPECIFIED); + + } + + /** + * Tests that isReportRequestSupported() will return DeviceInfoReportRequest. + */ + @Test + public final void testReportRequestSupported() { + Assert.assertEquals(collector.reportRequestTypeSupported(), DeviceInfoReportRequest.class); + } + +} diff --git a/HIRS_Provisioner/src/test/java/hirs/provisioner/client/RestfulClientProvisionerTest.java b/HIRS_Provisioner/src/test/java/hirs/provisioner/client/RestfulClientProvisionerTest.java index 15c02a7e..9d4629c7 100644 --- a/HIRS_Provisioner/src/test/java/hirs/provisioner/client/RestfulClientProvisionerTest.java +++ b/HIRS_Provisioner/src/test/java/hirs/provisioner/client/RestfulClientProvisionerTest.java @@ -1,6 +1,6 @@ package hirs.provisioner.client; -import hirs.client.collector.DeviceInfoCollectorHelper; +import hirs.client.collector.DeviceInfoCollector; import hirs.data.persist.DeviceInfoReport; import hirs.data.persist.FirmwareInfo; import hirs.data.persist.HardwareInfo; @@ -56,7 +56,7 @@ import static org.testng.Assert.assertTrue; /** * Test suite for the {@link RestfulClientProvisioner}. */ -@PrepareForTest(DeviceInfoCollectorHelper.class) +@PrepareForTest(DeviceInfoCollector.class) public class RestfulClientProvisionerTest extends PowerMockTestCase { /** @@ -158,11 +158,11 @@ public class RestfulClientProvisionerTest extends PowerMockTestCase { * Tests {@link RestfulClientProvisioner#createIdentityRequest(AsymmetricPublicKey, * String, DeviceInfoReport)}. * @throws Exception if there is a problem encountered when mocking - * DeviceInfoCollectorHelper + * DeviceInfoCollector */ @Test public void createIdentityCredential() throws Exception { - PowerMockito.spy(DeviceInfoCollectorHelper.class); + PowerMockito.spy(DeviceInfoCollector.class); final InetAddress ipAddress = getTestIpAddress(); final byte[] macAddress = new byte[] {11, 22, 33, 44, 55, 66}; @@ -188,10 +188,10 @@ public class RestfulClientProvisionerTest extends PowerMockTestCase { when(mockTpm.getEndorsementCredential()).thenReturn(ek); - PowerMockito.doReturn("AB12345").when(DeviceInfoCollectorHelper.class, + PowerMockito.doReturn("AB12345").when(DeviceInfoCollector.class, "collectDmiDecodeValue", OSName.LINUX, "system-serial-number"); - PowerMockito.doReturn("AB12346").when(DeviceInfoCollectorHelper.class, + PowerMockito.doReturn("AB12346").when(DeviceInfoCollector.class, "collectDmiDecodeValue", OSName.LINUX, "chassis-serial-number"); // perform test @@ -228,11 +228,11 @@ public class RestfulClientProvisionerTest extends PowerMockTestCase { * Tests {@link RestfulClientProvisioner#createIdentityRequest(AsymmetricPublicKey, * String, DeviceInfoReport)}. * @throws Exception if there is a problem encountered when mocking - * DeviceInfoCollectorHelper + * DeviceInfoCollector */ @Test public void createIdentityCredentialEkNotFound() throws Exception { - PowerMockito.spy(DeviceInfoCollectorHelper.class); + PowerMockito.spy(DeviceInfoCollector.class); final InetAddress ipAddress = getTestIpAddress(); final byte[] macAddress = new byte[] {11, 22, 33, 44, 55, 66}; @@ -258,10 +258,10 @@ public class RestfulClientProvisionerTest extends PowerMockTestCase { new CommandResult("EK not found", -1))); - PowerMockito.doReturn("AB12345").when(DeviceInfoCollectorHelper.class, + PowerMockito.doReturn("AB12345").when(DeviceInfoCollector.class, "collectDmiDecodeValue", OSName.LINUX, "system-serial-number"); - PowerMockito.doReturn("AB12346").when(DeviceInfoCollectorHelper.class, + PowerMockito.doReturn("AB12346").when(DeviceInfoCollector.class, "collectDmiDecodeValue", OSName.LINUX, "chassis-serial-number"); // perform test diff --git a/HIRS_ProvisionerTPM2/CMakeLists.txt b/HIRS_ProvisionerTPM2/CMakeLists.txt index 7204d9cc..2e98deea 100644 --- a/HIRS_ProvisionerTPM2/CMakeLists.txt +++ b/HIRS_ProvisionerTPM2/CMakeLists.txt @@ -257,7 +257,7 @@ if (${DISTRIBUTION} STREQUAL "Ubuntu") set(CPACK_GENERATOR "DEB") set(CPACK_DEBIAN_PACKAGE_NAME "HIRSProvisionerTPM2.0") set(CPACK_DEBIAN_PACKAGE_SECTION "admin") - set(CPACK_DEBIAN_PACKAGE_DEPENDS "liblog4cplus-1.1-9(>=1.1.2), libcurlpp0(>=0.7), lshw") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "liblog4cplus-1.1-9(>=1.1.2), libcurlpp0(>=0.7), paccor") # Set variables specific to Ubuntu release version if (${DISTRIBUTION_VERSION} STREQUAL "16.04") set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}, libre2-1v5(>=20160201), libprotobuf9v5(>=2.4.1)") @@ -279,7 +279,7 @@ elseif (${DISTRIBUTION} STREQUAL "CentOS Linux") set(CPACK_RPM_PACKAGE_RELEASE_DIST "el7") set(CPACK_RPM_PACKAGE_LICENSE "Apache License, Version 2.0") set(CPACK_RPM_PACKAGE_GROUP "System Environment/Base") - set(CPACK_RPM_PACKAGE_REQUIRES "log4cplus >= 1.1.2, tpm2-tss >= 1.0, tpm2-tools >= 1.1.0, protobuf >= 2.4.1, re2 >= 20160401, libcurl >= 7.0.0, lshw") + set(CPACK_RPM_PACKAGE_REQUIRES "log4cplus >= 1.1.2, tpm2-tss >= 1.0, tpm2-tools >= 1.1.0, protobuf >= 2.4.1, re2 >= 20160401, libcurl >= 7.0.0, paccor") set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/package/rpm-post-install.sh) set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/local /usr/local/bin /usr/local/include /usr/local/lib) set(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_RELEASE}.${CPACK_RPM_PACKAGE_RELEASE_DIST}.${CMAKE_SYSTEM_PROCESSOR}") diff --git a/HIRS_ProvisionerTPM2/docs/dependencies-centos.md b/HIRS_ProvisionerTPM2/docs/dependencies-centos.md index 25cc4091..d1ba6153 100644 --- a/HIRS_ProvisionerTPM2/docs/dependencies-centos.md +++ b/HIRS_ProvisionerTPM2/docs/dependencies-centos.md @@ -13,5 +13,5 @@ Please look up their respective names in the CentOS repositories. | protobuf | 2.5.0 | 2.4.1 (estimated) | CentOS 7 base | https://github.com/google/protobuf | | re2 | 20160401 | 20160201 | CentOS 7 epel-release | https://github.com/google/re2 | | tpm2-tss | 1.2.0 | 1.0.0 | CentOS 7 base | https://github.com/intel/tpm2-tss | -| lshw | B.02.18-12 | B.02.18-12 | CentOS 7 base | https://github.com/lyonel/lshw | | tpm2-tools | 1.1.0 | 1.1.0 | CentOS 7 base | https://github.com/tpm2-software/tpm2-tools | +| paccor | 1.0.6 | none | | https://github.com/nsacyber/paccor | diff --git a/HIRS_ProvisionerTPM2/include/DeviceInfoCollector.h b/HIRS_ProvisionerTPM2/include/DeviceInfoCollector.h index 47db2ab2..ad368448 100644 --- a/HIRS_ProvisionerTPM2/include/DeviceInfoCollector.h +++ b/HIRS_ProvisionerTPM2/include/DeviceInfoCollector.h @@ -21,28 +21,6 @@ class DeviceInfoCollector { static const hirs::log::Logger LOGGER; - static void addBaseboardInfoIfAvailable(hirs::pb::HardwareInfo* hwInfo); - - static void addBiosInfoIfAvailable(hirs::pb::HardwareInfo* hwInfo); - - static void addChassisInfoIfAvailable(hirs::pb::HardwareInfo* hwInfo); - - static void addHardDriveInfoIfAvailable(hirs::pb::HardwareInfo* hwInfo); - - static void addMemoryInfoIfAvailable(hirs::pb::HardwareInfo* hwInfo); - - static void addNicInfoIfAvailable(hirs::pb::HardwareInfo* hwInfo); - - static void addProcessorInfoIfAvailable(hirs::pb::HardwareInfo* hwInfo); - - static int getLshwDeviceCount(std::string className, - std::string deviceType = ""); - - static std::string getLshwDeviceField(int deviceNumber, - std::string fieldName, - std::string className, - std::string deviceType); - static std::vector> getNetworks(); static hirs::pb::FirmwareInfo collectFirmwareInfo(); diff --git a/HIRS_ProvisionerTPM2/src/DeviceInfoCollector.cpp b/HIRS_ProvisionerTPM2/src/DeviceInfoCollector.cpp index b00cf3b9..d3486c45 100644 --- a/HIRS_ProvisionerTPM2/src/DeviceInfoCollector.cpp +++ b/HIRS_ProvisionerTPM2/src/DeviceInfoCollector.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include # define NOT_SPECIFIED "Not Specified" @@ -79,88 +78,6 @@ hirs::pb::HardwareInfo DeviceInfoCollector::collectHardwareInfo() { LOGGER.info("Product Version: " + hw.productversion()); LOGGER.info("System Serial Number: " + hw.systemserialnumber()); - addChassisInfoIfAvailable(&hw); - google::protobuf::RepeatedPtrField chassisInfo - = hw.chassisinfo(); - for (int i = 0; i < chassisInfo.size(); i++) { - LOGGER.info("Chassis Manufacturer: " - + chassisInfo.Get(i).manufacturer()); - LOGGER.info("Chassis Model: " + chassisInfo.Get(i).model()); - LOGGER.info( - "Chassis Serial Number: " + chassisInfo.Get(i).serialnumber()); - LOGGER.info("Chassis Version: " + chassisInfo.Get(i).revision()); - } - - addBaseboardInfoIfAvailable(&hw); - google::protobuf::RepeatedPtrField baseboardInfo - = hw.baseboardinfo(); - for (int i = 0; i < baseboardInfo.size(); i++) { - LOGGER.info( - "Baseboard Manufacturer: " + baseboardInfo.Get(i).manufacturer - ()); - LOGGER.info("Baseboard Model: " + baseboardInfo.Get(i).model()); - LOGGER.info("Baseboard Serial Number: " + - baseboardInfo.Get(i).serialnumber()); - LOGGER.info("Baseboard Version: " + baseboardInfo.Get(i).revision()); - } - - addProcessorInfoIfAvailable(&hw); - google::protobuf::RepeatedPtrField processorInfo - = hw.processorinfo(); - for (int i = 0; i < processorInfo.size(); i++) { - LOGGER.info("Processor Manufacturer: " - + processorInfo.Get(i).manufacturer()); - LOGGER.info("Processor Model: " + processorInfo.Get(i).model()); - LOGGER.info("Processor Serial Number: " + - processorInfo.Get(i).serialnumber()); - LOGGER.info("Processor Version: " + processorInfo.Get(i).revision()); - } - - addBiosInfoIfAvailable(&hw); - google::protobuf::RepeatedPtrField biosInfo - = hw.biosoruefiinfo(); - for (int i = 0; i < biosInfo.size(); i++) { - LOGGER.info("BIOS Manufacturer: " + biosInfo.Get(i).manufacturer()); - LOGGER.info("BIOS Model: " + biosInfo.Get(i).model()); - LOGGER.info("BIOS Version: " + biosInfo.Get(i).revision()); - } - - addNicInfoIfAvailable(&hw); - google::protobuf::RepeatedPtrField nicInfo - = hw.nicinfo(); - for (int i = 0; i < nicInfo.size(); i++) { - LOGGER.info("NIC Manufacturer: " + nicInfo.Get(i).manufacturer()); - LOGGER.info("NIC Model: " + nicInfo.Get(i).model()); - LOGGER.info("NIC Serial Number: " + nicInfo.Get(i).serialnumber()); - LOGGER.info("NIC Version: " + nicInfo.Get(i).revision()); - } - - addHardDriveInfoIfAvailable(&hw); - google::protobuf::RepeatedPtrField hdInfo - = hw.harddriveinfo(); - for (int i = 0; i < hdInfo.size(); i++) { - LOGGER.info("Hard Drive " + std::to_string(i) + " Manufacturer: " - + hdInfo.Get(i).manufacturer()); - LOGGER.info("Hard Drive " + std::to_string(i) + " Model: " - + hdInfo.Get(i).model()); - LOGGER.info("Hard Drive " + std::to_string(i) + " Serial Number: " - + hdInfo.Get(i).serialnumber()); - LOGGER.info("Hard Drive " + std::to_string(i) + " Version: " - + hdInfo.Get(i).revision()); - } - - addMemoryInfoIfAvailable(&hw); - google::protobuf::RepeatedPtrField memInfo - = hw.memoryinfo(); - for (int i = 0; i < memInfo.size(); i++) { - LOGGER.info("Memory Unit " + std::to_string(i) + " Manufacturer: " - + memInfo.Get(i).manufacturer()); - LOGGER.info("Memory Unit " + std::to_string(i) + " Model: " - + memInfo.Get(i).model()); - LOGGER.info("Memory Unit " + std::to_string(i) + " Serial Number: " - + memInfo.Get(i).serialnumber()); - } - return hw; } @@ -327,348 +244,3 @@ hirs::pb::OsInfo DeviceInfoCollector::collectOsInfo() { return info; } -void DeviceInfoCollector::addChassisInfoIfAvailable( - hirs::pb::HardwareInfo* hwInfo) { - int numChassis = atoi(RUN_PROCESS_OR_THROW("dmidecode", "-t 3 " - "| grep 'Manufacturer:' | wc -l").c_str()); - - for (int chassisNumber = 1; chassisNumber <= numChassis; chassisNumber++) { - // Manufacturer and Model are required if Chassis is to - // be included at all. - try { - hirs::pb::ComponentInfo chassisInfo; - chassisInfo.set_manufacturer( - RUN_PROCESS_OR_THROW("dmidecode", "-t 3 | " - "grep 'Manufacturer:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(chassisNumber) + "p")); - chassisInfo.set_model( - RUN_PROCESS_OR_THROW("dmidecode", "-t 3 | " - "grep 'Type:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(chassisNumber) + "p")); - - // Serial number is optional - try { - chassisInfo.set_serialnumber( - RUN_PROCESS_OR_THROW("dmidecode", "-t 3 | " - "grep 'Serial Number:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(chassisNumber) + "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - - // Chassis version is optional - try { - chassisInfo.set_revision( - RUN_PROCESS_OR_THROW("dmidecode", "-t 3 | " - "grep 'Version:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(chassisNumber) + "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - hwInfo->add_chassisinfo(); - hwInfo->mutable_chassisinfo(chassisNumber - 1) - ->CopyFrom(chassisInfo); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - } -} - -void DeviceInfoCollector::addBaseboardInfoIfAvailable( - hirs::pb::HardwareInfo* hwInfo) { - int numBaseboards = atoi(RUN_PROCESS_OR_THROW("dmidecode", "-t 2 " - "| grep 'Manufacturer:' | wc -l").c_str()); - - for (int baseboardNumber = 1; baseboardNumber <= numBaseboards; - baseboardNumber++) { - hirs::pb::ComponentInfo baseboardInfo; - - // Manufacturer and Model required if Baseboard is to be - // included at all. - try { - baseboardInfo.set_manufacturer( - RUN_PROCESS_OR_THROW("dmidecode", "-t 2 | " - "grep 'Manufacturer:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(baseboardNumber) + "p")); - baseboardInfo.set_model( - RUN_PROCESS_OR_THROW("dmidecode", "-t 2 | " - "grep 'Product Name:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(baseboardNumber) + "p")); - - // Serial number is optional - try { - baseboardInfo.set_serialnumber( - RUN_PROCESS_OR_THROW("dmidecode", "-t 2 | " - "grep 'Serial Number:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(baseboardNumber) + "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - - // Baseboard version is optional - try { - baseboardInfo.set_revision( - RUN_PROCESS_OR_THROW("dmidecode", "-t 2 | " - "grep 'Version:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(baseboardNumber) + "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - hwInfo->add_baseboardinfo(); - hwInfo->mutable_baseboardinfo(baseboardNumber - 1) - ->CopyFrom(baseboardInfo); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - } -} - -void DeviceInfoCollector::addProcessorInfoIfAvailable( - hirs::pb::HardwareInfo* hwInfo) { - int numProcessors = atoi(RUN_PROCESS_OR_THROW("dmidecode", "-t 4 " - "| grep 'Manufacturer:' | wc -l").c_str()); - - for (int processorNumber = 1; processorNumber <= numProcessors; - processorNumber++) { - hirs::pb::ComponentInfo processorInfo; - - // Manufacturer and Model required if Processor is to be - // included at all. - try { - processorInfo.set_manufacturer( - RUN_PROCESS_OR_THROW("dmidecode", "-t 4 | " - "grep 'Manufacturer:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(processorNumber) + "p")); - processorInfo.set_model( - RUN_PROCESS_OR_THROW("dmidecode", "-t 4 | " - "grep 'Family:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(processorNumber) + "p")); - - // Serial number is optional - try { - processorInfo.set_serialnumber( - RUN_PROCESS_OR_THROW("dmidecode", "-t 4 | " - "grep 'Serial Number:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(processorNumber) + "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - - // Processor version is optional - try { - processorInfo.set_revision( - RUN_PROCESS_OR_THROW("dmidecode", "-t 4 | " - "grep 'Version:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(processorNumber) + "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - hwInfo->add_processorinfo(); - hwInfo->mutable_processorinfo(processorNumber - 1) - ->CopyFrom(processorInfo); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - } -} - -void DeviceInfoCollector::addBiosInfoIfAvailable( - hirs::pb::HardwareInfo* hwInfo) { - int numBios = atoi(RUN_PROCESS_OR_THROW("dmidecode", "-t bios " - "| grep Vendor | wc -l").c_str()); - - for (int biosNumber = 1; biosNumber <= numBios; biosNumber++) { - hirs::pb::ComponentInfo biosOrUefiInfo; - - // Manufacturer and Model are required if BIOS is to be included at all. - try { - biosOrUefiInfo.set_manufacturer( - RUN_PROCESS_OR_THROW("dmidecode", - "-t bios| grep 'Vendor:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(biosNumber) + "p")); - - // TODO(apl.dev4): don't know how to know BIOS vs. UEFI - biosOrUefiInfo.set_model("BIOS"); - - // BIOS version is optional - try { - biosOrUefiInfo.set_revision( - RUN_PROCESS_OR_THROW("dmidecode", "-t bios" - "| grep 'Version:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(biosNumber) + "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - - hwInfo->add_biosoruefiinfo(); - hwInfo->mutable_biosoruefiinfo(biosNumber - 1) - ->CopyFrom(biosOrUefiInfo); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - } -} - -void DeviceInfoCollector::addNicInfoIfAvailable( - hirs::pb::HardwareInfo* hwInfo) { - int numNICs = atoi(RUN_PROCESS_OR_THROW("lshw", "-class network " - "| grep vendor | wc -l").c_str()); - - for (int nicNumber = 1; nicNumber <= numNICs; nicNumber++) { - hirs::pb::ComponentInfo nicInfo; - - // Manufacturer and Model are required if NIC info is to be - // included at all. - try { - nicInfo.set_manufacturer( - RUN_PROCESS_OR_THROW("lshw", "-class network " - "| grep vendor | sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(nicNumber) + "p")); - nicInfo.set_model( - RUN_PROCESS_OR_THROW("lshw", "-class network " - "| grep product | sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(nicNumber) + "p")); - - // Serial number is optional - try { - nicInfo.set_serialnumber( - RUN_PROCESS_OR_THROW("lshw", "-class network " - "| grep 'serial:' | sed -e 's/[^:]*: //' -n -e " - + std::to_string(nicNumber) + "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - - // NIC version is optional - try { - nicInfo.set_revision( - RUN_PROCESS_OR_THROW("lshw", "-class network " - "| grep version: | sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(nicNumber) + "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - - hwInfo->add_nicinfo(); - hwInfo->mutable_nicinfo(nicNumber - 1)->CopyFrom(nicInfo); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - } -} - -int DeviceInfoCollector::getLshwDeviceCount(string className, - string deviceType) { - stringstream argStream; - argStream << "-class " << className - << " | awk" - << " -vdev_type=" << deviceType - << " \'match($0, \"^ \\\\*-\" dev_type) {++count}" - << " END {print count}\'"; - return atoi(RUN_PROCESS_OR_THROW("lshw", argStream.str()).c_str()); -} - -string DeviceInfoCollector::getLshwDeviceField(int deviceNumber, - string fieldName, - string className, - string deviceType) { - stringstream argStream; - argStream << "-class " << className - << " | awk" - << " -vdev_type=" << deviceType - << " -vdevice_idx=" << deviceNumber - << " -vfield=" << fieldName - << " \'" - << " match($0, \"^[ ]+\\\\*-\"){show=0}" - << " match($0, \"^ \\\\*-\" dev_type){++dev;show=1}" - << " field \":\" == $1" - << " && show==1 && device_idx==dev{$1=\"\";print }\'"; - string value = RUN_PROCESS_OR_THROW("lshw", argStream.str()); - - if (value.empty()) { - return NOT_SPECIFIED; - } - return value; -} - -void DeviceInfoCollector::addHardDriveInfoIfAvailable( - hirs::pb::HardwareInfo* hwInfo) { - int numHardDrives = getLshwDeviceCount("disk", "disk"); - - for (int hdNumber = 1; hdNumber <= numHardDrives; hdNumber++) { - try { - hirs::pb::ComponentInfo hardDriveInfo; - - hardDriveInfo.set_manufacturer( - getLshwDeviceField(hdNumber, "vendor", "disk", "disk")); - - hardDriveInfo.set_model( - getLshwDeviceField(hdNumber, "product", "disk", "disk")); - - hardDriveInfo.set_serialnumber( - getLshwDeviceField(hdNumber, "serial", "disk", "disk")); - - hardDriveInfo.set_revision( - getLshwDeviceField(hdNumber, "version", "disk", "disk")); - - hwInfo->add_harddriveinfo(); - hwInfo->mutable_harddriveinfo(hdNumber - 1)->CopyFrom( - hardDriveInfo); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - } -} - -void DeviceInfoCollector::addMemoryInfoIfAvailable( - hirs::pb::HardwareInfo* hwInfo) { - int numDimms = atoi(RUN_PROCESS_OR_THROW("dmidecode", "-t 17 " - "| grep Manufacturer | wc -l").c_str()); - - for (int dimmNumber = 1; dimmNumber <= numDimms; dimmNumber++) { - try { - hirs::pb::ComponentInfo memoryInfo; - - memoryInfo.set_manufacturer( - RUN_PROCESS_OR_THROW("dmidecode", - "-t 17 | grep 'Manufacturer:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(dimmNumber) + "p")); - - memoryInfo.set_model( - RUN_PROCESS_OR_THROW("dmidecode", - "-t 17 | grep 'Part Number:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(dimmNumber) + "p")); - try { - memoryInfo.set_serialnumber( - RUN_PROCESS_OR_THROW("dmidecode", - "-t 17 | grep 'Serial Number:' " - "| sed -e 's/[^:]*:[ ]*//' -n -e " - + std::to_string(dimmNumber) + - "p")); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - - hwInfo->add_memoryinfo(); - hwInfo->mutable_memoryinfo(dimmNumber - 1)->CopyFrom(memoryInfo); - } catch (const HirsRuntimeException& e) { - LOGGER.warn(e.what()); - } - } -} diff --git a/HIRS_ProvisionerTPM2/src/ProvisionerTpm2.proto b/HIRS_ProvisionerTPM2/src/ProvisionerTpm2.proto index d2f69104..66bcb5f1 100644 --- a/HIRS_ProvisionerTPM2/src/ProvisionerTpm2.proto +++ b/HIRS_ProvisionerTPM2/src/ProvisionerTpm2.proto @@ -58,6 +58,8 @@ message IdentityClaim { optional bytes endorsement_credential = 4; repeated bytes platform_credential = 5; optional string client_version = 6; + optional string paccorOutput = 7; + } message IdentityClaimResponse { diff --git a/HIRS_ProvisionerTPM2/src/TPM2_Provisioner.cpp b/HIRS_ProvisionerTPM2/src/TPM2_Provisioner.cpp index b36b6276..8fcfe481 100644 --- a/HIRS_ProvisionerTPM2/src/TPM2_Provisioner.cpp +++ b/HIRS_ProvisionerTPM2/src/TPM2_Provisioner.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "log4cplus/configurator.h" @@ -70,6 +71,9 @@ int provision() { endorsementCredential, platformCredentials); identityClaim.set_client_version(CLIENT_VERSION); + string paccorOutputString = + RUN_PROCESS_OR_THROW("/opt/paccor/scripts/allcomponents.sh", ""); + identityClaim.set_paccoroutput(paccorOutputString); RestfulClientProvisioner provisioner; string nonceBlob = provisioner.sendIdentityClaim(identityClaim); if (nonceBlob == "") { diff --git a/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollector.java b/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollector.java index 96ccee46..bc9ca816 100644 --- a/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollector.java +++ b/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollector.java @@ -11,6 +11,8 @@ import hirs.data.persist.OSInfo; import hirs.data.persist.OSName; import hirs.data.persist.Report; import hirs.data.persist.TPMInfo; +import hirs.utils.exec.ExecBuilder; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -66,6 +68,9 @@ public class DeviceInfoCollector extends AbstractCollector { private static final Logger LOGGER = LogManager.getLogger(DeviceInfoCollector.class); + private static final String OPT_PACCOR_SCRIPTS_ALLCOMPONENTS_SH + = "/opt/paccor/scripts/allcomponents.sh"; + private X509Certificate clientCredential; private final String credentialFilePath; @@ -100,6 +105,66 @@ public class DeviceInfoCollector extends AbstractCollector { LOGGER.warn("default constructor called! Should only be done in test"); } + private static String callPaccor() throws CollectorException { + String[] command = {OPT_PACCOR_SCRIPTS_ALLCOMPONENTS_SH}; + + ProcessBuilder processBuilder = new ProcessBuilder(command); + + String errorAsString; + try { + // issue the command + Process process = processBuilder.start(); + + // block and wait for the process to be complete + int returnCode = process.waitFor(); + + try (InputStream processInputStream = process.getInputStream(); + InputStream processErrorStream = process.getErrorStream()) { + + if (returnCode == 0) { + return IOUtils.toString(processInputStream); + } + + errorAsString = IOUtils.toString(processErrorStream); + } + } catch (IOException | InterruptedException e) { + errorAsString = e.getMessage(); + LOGGER.error(e.toString()); + } + + String errorMessage = "Failed to collect component info: " + errorAsString; + LOGGER.error(errorMessage); + throw new CollectorException(errorMessage); + } + + /** + * Retrieves dmidecode for the device. Only supports Linux. + * + * @param osName name of OS (Linux, Windows, etc.) + * @param command dmidecode string keyword command + * @return String of the result + * @throws CollectorException if there is a problem encountered while performing collection + */ + public static String collectDmiDecodeValue(final OSName osName, final String command) + throws CollectorException { + ExecBuilder execBuilder = null; + try { + switch (osName) { + case LINUX: + execBuilder = new ExecBuilder("dmidecode").args("-s", command); + break; + default: + throw new CollectorException(String.format( + "Unsupported operating system detected: %s.", osName)); + } + + return execBuilder.exec().getStdOutResult().trim(); + } catch (IOException e) { + String msg = String.format("Could not call dmidecode using command: %s", execBuilder); + throw new CollectorException(msg, e); + } + } + /** * Takes a DeviceInfoReportRequest and returns a DeviceInfoReport. The * DeviceInfo report contains the following:
  • OSInfo
    • @@ -140,7 +205,8 @@ public class DeviceInfoCollector extends AbstractCollector { tpmInfo ); - DeviceInfoCollectorHelper.collectAndStoreComponentInfo(report); + report.setPaccorOutputString(callPaccor()); + return report; } @@ -366,19 +432,19 @@ public class DeviceInfoCollector extends AbstractCollector { switch (osName) { case LINUX: biosVendor = StringUtils.defaultIfEmpty( - DeviceInfoCollectorHelper.collectDmiDecodeValue( + collectDmiDecodeValue( OSName.LINUX, "bios-vendor" ), NOT_SPECIFIED ); biosVersion = StringUtils.defaultIfEmpty( - DeviceInfoCollectorHelper.collectDmiDecodeValue( + collectDmiDecodeValue( OSName.LINUX, "bios-version" ), NOT_SPECIFIED ); biosReleaseDate = StringUtils.defaultIfEmpty( - DeviceInfoCollectorHelper.collectDmiDecodeValue( + collectDmiDecodeValue( OSName.LINUX, "bios-release-date" ), NOT_SPECIFIED @@ -402,42 +468,42 @@ public class DeviceInfoCollector extends AbstractCollector { switch (osName) { case LINUX: manufacturer = StringUtils.defaultIfEmpty( - DeviceInfoCollectorHelper.collectDmiDecodeValue( + collectDmiDecodeValue( OSName.LINUX, "system-manufacturer" ), NOT_SPECIFIED ); productName = StringUtils.defaultIfEmpty( - DeviceInfoCollectorHelper.collectDmiDecodeValue( + collectDmiDecodeValue( OSName.LINUX, "system-product-name" ), NOT_SPECIFIED ); version = StringUtils.defaultIfEmpty( - DeviceInfoCollectorHelper.collectDmiDecodeValue( + collectDmiDecodeValue( OSName.LINUX, "system-version" ), NOT_SPECIFIED ); serialNumber = StringUtils.defaultIfEmpty( - DeviceInfoCollectorHelper.collectDmiDecodeValue( + collectDmiDecodeValue( OSName.LINUX, "system-serial-number" ), NOT_SPECIFIED ); chassisSerialNumber = StringUtils.defaultIfEmpty( - DeviceInfoCollectorHelper.collectDmiDecodeValue( + collectDmiDecodeValue( OSName.LINUX, "chassis-serial-number" ), NOT_SPECIFIED ); baseboardSerialNumber = StringUtils.defaultIfEmpty( - DeviceInfoCollectorHelper.collectDmiDecodeValue( + collectDmiDecodeValue( OSName.LINUX, "baseboard-serial-number" ), NOT_SPECIFIED diff --git a/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollectorHelper.java b/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollectorHelper.java deleted file mode 100644 index 49a1d4e9..00000000 --- a/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollectorHelper.java +++ /dev/null @@ -1,344 +0,0 @@ -package hirs.client.collector; - -import hirs.collector.CollectorException; -import hirs.data.persist.BIOSComponentInfo; -import hirs.data.persist.BaseboardComponentInfo; -import hirs.data.persist.ChassisComponentInfo; -import hirs.data.persist.ComponentInfo; -import hirs.data.persist.DeviceInfoReport; -import hirs.data.persist.HardDriveComponentInfo; -import hirs.data.persist.MemoryComponentInfo; -import hirs.data.persist.NICComponentInfo; -import hirs.data.persist.OSName; -import hirs.data.persist.ProcessorComponentInfo; -import hirs.utils.exec.AsynchronousExecResult; -import hirs.utils.exec.ExecBuilder; -import hirs.utils.exec.ExecPipe; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * This is a utility class which supports collecting additional - * information for the DeviceInfoCollector. - */ -@SuppressWarnings("checkstyle:linelength") -public final class DeviceInfoCollectorHelper { - private static final Logger LOGGER = LogManager.getLogger(DeviceInfoCollectorHelper.class); - - // commands - private static final String DMIDECODE = "dmidecode"; - private static final String LSHW = "lshw"; - private static final String GREP = "grep"; - private static final String SED = "sed"; - private static final String WC = "wc"; - private static final String AWK = "awk"; - - // DMI component enumerations - private static final int DMI_BIOS = 0; - private static final int DMI_BASEBOARD = 2; - private static final int DMI_CHASSIS = 3; - private static final int DMI_PROCESSOR = 4; - private static final int DMI_MEMORY = 17; - - // lshw hardware categories - private static final String LSHW_NETWORK = "network"; - private static final String LSHW_DISK = "disk"; - - private static final String AWK_COUNT_COMPONENTS = - "BEGIN { num=0 } { if ($0 ~ /^ \\*-.+/) { num++ } } END { print num }"; - - private static final String AWK_GET_LSHW_HEADER = - "BEGIN { device_idx=0 } { if ($0 ~ /^ \\*-.+/) { device_idx++ } if (device_idx == dev && $0 ~ /^ \\*-.+/) { print } }"; - - private static final String AWK_GET_LSHW_FIELD = - "BEGIN { device_idx=0 } { if ($0 ~ /^ \\*-.+/) { device_idx++ } if (device_idx == dev && $0 ~ field) { print } }"; - - /** - * Default constructor to prevent construction. - */ - private DeviceInfoCollectorHelper() { - } - - /** - * Collect all possible ComponentInfo information from the - * local machine and store it in the given DeviceInfoReport. - * - * @param report the DeviceInfoReport that will hold the ComponentInfo - * @throws CollectorException if an error is encountered during collection - */ - public static void collectAndStoreComponentInfo(final DeviceInfoReport report) - throws CollectorException { - try { - report.setChassisInfo(getChassisInfo()); - report.setBaseboardInfo(getBaseboardInfo()); - report.setProcessorInfo(getProcessorInfo()); - report.setBiosInfo(getBiosInfo()); - report.setNicInfo(getNicInfo()); - report.setHardDriveInfo(getHardDriveInfo()); - report.setMemoryInfo(getMemoryInfo()); - } catch (IOException e) { - throw new CollectorException("Failed to collect component info", e); - } - } - - private static List getChassisInfo() throws IOException { - LOGGER.debug("Collecting ChassisComponentInfo..."); - List components = new ArrayList<>(); - int compCount = getDmiCompCount(DMI_CHASSIS, "Manufacturer"); - for (int i = 1; i <= compCount; i++) { - String manufacturer = getDmiCompAttr(DMI_CHASSIS, "Manufacturer", getSedDmiLshwVal(i)); - String model = getDmiCompAttr(DMI_CHASSIS, "Type", getSedDmiLshwVal(i)); - String serial = getDmiCompAttr(DMI_CHASSIS, "Serial Number", getSedDmiLshwVal(i)); - String revision = getDmiCompAttr(DMI_CHASSIS, "Version", getSedDmiLshwVal(i)); - - if (ComponentInfo.isComplete(manufacturer, model, serial, revision)) { - ChassisComponentInfo component = - new ChassisComponentInfo(manufacturer, model, serial, revision); - LOGGER.debug(String.format("Collected: %s", component.toString())); - components.add(component); - } - } - return components; - } - - private static List getBaseboardInfo() throws IOException { - LOGGER.debug("Collecting BaseboardComponentInfo..."); - List components = new ArrayList<>(); - int compCount = getDmiCompCount(DMI_BASEBOARD, "Manufacturer"); - for (int i = 1; i <= compCount; i++) { - String manufacturer = - getDmiCompAttr(DMI_BASEBOARD, "Manufacturer", getSedDmiLshwVal(i)); - String model = getDmiCompAttr(DMI_BASEBOARD, "Product Name", getSedDmiLshwVal(i)); - String serial = getDmiCompAttr(DMI_BASEBOARD, "Serial Number", getSedDmiLshwVal(i)); - String revision = getDmiCompAttr(DMI_BASEBOARD, "Version", getSedDmiLshwVal(i)); - - if (ComponentInfo.isComplete(manufacturer, model, serial, revision)) { - BaseboardComponentInfo component = - new BaseboardComponentInfo(manufacturer, model, serial, revision); - LOGGER.debug(String.format("Collected: %s", component.toString())); - components.add(component); - } - } - return components; - } - - private static List getProcessorInfo() throws IOException { - LOGGER.debug("Collecting ProcessorComponentInfo..."); - List components = new ArrayList<>(); - int compCount = getDmiCompCount(DMI_PROCESSOR, "Manufacturer"); - for (int i = 1; i <= compCount; i++) { - String manufacturer = - getDmiCompAttr(DMI_PROCESSOR, "Manufacturer", getSedDmiLshwVal(i)); - String model = getDmiCompAttr(DMI_PROCESSOR, "Family", getSedDmiLshwVal(i)); - String serial = getDmiCompAttr(DMI_PROCESSOR, "Serial Number", getSedDmiLshwVal(i)); - String revision = getDmiCompAttr(DMI_PROCESSOR, "Version", getSedDmiLshwVal(i)); - - if (ComponentInfo.isComplete(manufacturer, model, serial, revision)) { - ProcessorComponentInfo component = - new ProcessorComponentInfo(manufacturer, model, serial, revision); - LOGGER.debug(String.format("Collected: %s", component.toString())); - components.add(component); - } - } - return components; - } - - private static List getBiosInfo() throws IOException { - LOGGER.debug("Collecting BIOSComponentInfo..."); - List components = new ArrayList<>(); - int compCount = getDmiCompCount(DMI_BIOS, "Vendor"); - for (int i = 1; i <= compCount; i++) { - String manufacturer = getDmiCompAttr(DMI_BIOS, "Vendor", getSedDmiLshwVal(i)); - String model = "BIOS"; - String revision = getDmiCompAttr(DMI_BIOS, "Version", getSedDmiLshwVal(i)); - - if (ComponentInfo.isComplete(manufacturer, model, null, revision)) { - BIOSComponentInfo component = new BIOSComponentInfo(manufacturer, model, revision); - LOGGER.debug(String.format("Collected: %s", component.toString())); - components.add(component); - } - } - return components; - } - - private static List getNicInfo() throws IOException { - LOGGER.debug("Collecting NICComponentInfo..."); - List components = new ArrayList<>(); - int compCount = getLshwCompCount(LSHW_NETWORK); - for (int i = 1; i <= compCount; i++) { - String manufacturer = getLshwCompAttr(LSHW_NETWORK, i, "vendor"); - String model = getLshwCompAttr(LSHW_NETWORK, i, "product"); - String serial = - getLshwCompAttr(LSHW_NETWORK, i, "serial"); - String revision = getLshwCompAttr(LSHW_NETWORK, i, "version"); - - if (ComponentInfo.isComplete(manufacturer, model, serial, revision)) { - NICComponentInfo component = - new NICComponentInfo(manufacturer, model, serial, revision); - LOGGER.debug(String.format("Collected: %s", component.toString())); - components.add(component); - } - } - return components; - } - - private static List getHardDriveInfo() throws IOException { - LOGGER.debug("Collecting HardDriveComponentInfo..."); - List components = new ArrayList<>(); - int compCount = getLshwCompCount(LSHW_DISK); - for (int i = 1; i <= compCount; i++) { - // known values: disk, cdrom - String diskDeviceType = getLshwHeader(LSHW_DISK, i); - if (!diskDeviceType.startsWith("*-disk")) { - LOGGER.debug(String.format("%s did not match *-disk prefix; skipping.", diskDeviceType)); - continue; - } - - String manufacturer = getLshwCompAttr(LSHW_DISK, i, "vendor"); - String model = getLshwCompAttr(LSHW_DISK, i, "product"); - String serial = - getLshwCompAttr(LSHW_DISK, i, "serial"); - String revision = getLshwCompAttr(LSHW_DISK, i, "version"); - - if (ComponentInfo.isComplete(manufacturer, model, serial, revision)) { - HardDriveComponentInfo component = - new HardDriveComponentInfo(manufacturer, model, serial, revision); - LOGGER.debug(String.format("Collected: %s", component.toString())); - components.add(component); - } - } - return components; - } - - private static List getMemoryInfo() throws IOException { - LOGGER.debug("Collecting MemoryComponentInfo..."); - List components = new ArrayList<>(); - int compCount = getDmiCompCount(DMI_MEMORY, "Manufacturer"); - for (int i = 1; i <= compCount; i++) { - String manufacturer = getDmiCompAttr(DMI_MEMORY, "Manufacturer", getSedDmiLshwVal(i)); - String model = getDmiCompAttr(DMI_MEMORY, "Part Number", getSedDmiLshwVal(i)); - String serial = getDmiCompAttr(DMI_MEMORY, "Serial Number", getSedDmiLshwVal(i)); - String revision = null; - - if (ComponentInfo.isComplete(manufacturer, model, serial, revision)) { - MemoryComponentInfo component = - new MemoryComponentInfo(manufacturer, model, serial, revision); - LOGGER.debug(String.format("Collected: %s", component.toString())); - components.add(component); - } - } - return components; - } - - private static int getDmiCompCount(final int dmidecodeComponentType, final String termToCount) - throws IOException { - return Integer.parseInt(waitForAndGetOutput(ExecPipe.pipeOf(false, new String[][]{ - {DMIDECODE, "-t", Integer.toString(dmidecodeComponentType)}, - {GREP, termToCount + ":"}, - {WC, "-l"} - }).exec())); - } - - private static String getDmiCompAttr( - final int dmidecodeComponentType, - final String attr, - final String[] sedCleanFormat - ) throws IOException { - return waitForAndGetOutput(ExecPipe.pipeOf(false, new String[][]{ - {DMIDECODE, "-t", Integer.toString(dmidecodeComponentType)}, - {GREP, attr + ":"}, - sedCleanFormat - }).exec()); - } - - private static String getLshwHeader( - final String lshwComponentName, - final int lshwComponentIndex - ) throws IOException { - return waitForAndGetOutput(ExecPipe.pipeOf(false, new String[][]{ - {LSHW, "-class", lshwComponentName}, - {AWK, "-vdev=" + lshwComponentIndex, AWK_GET_LSHW_HEADER} - }).exec()); - } - - private static int getLshwCompCount(final String componentType) - throws IOException { - return Integer.parseInt(waitForAndGetOutput(ExecPipe.pipeOf(false, new String[][]{ - {LSHW, "-class", componentType}, - {AWK, AWK_COUNT_COMPONENTS} - }).exec())); - } - - private static String getLshwCompAttr( - final String lshwComponentName, - final int lshwComponentIndex, - final String attr - ) throws IOException { - String attrToSearch = " " + attr + ":"; - String lshwFieldVal = waitForAndGetOutput(ExecPipe.pipeOf(false, new String[][]{ - {LSHW, "-class", lshwComponentName}, - {AWK, "-vdev=" + lshwComponentIndex, "-vfield=" + attrToSearch, AWK_GET_LSHW_FIELD} - }).exec()); - - if (!lshwFieldVal.isEmpty()) { - // remove the field and the following ': ' to just leave the value - return lshwFieldVal.substring(lshwFieldVal.indexOf(":") + 2); - } else { - return DeviceInfoCollector.NOT_SPECIFIED; - } - } - - private static String[] getSedDmiLshwVal(final int componentNumber) { - return new String[]{ - SED, "-e", "s/[^:]*:[ ]*//", "-n", "-e", String.format("%dp", componentNumber) - }; - } - - private static String waitForAndGetOutput(final AsynchronousExecResult execResult) - throws IOException { - return waitFor(execResult).getStdOutResult().trim(); - } - - private static AsynchronousExecResult waitFor(final AsynchronousExecResult execResult) - throws IOException { - try { - execResult.waitFor(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - execResult.throwExceptionIfFailed(); - return execResult; - } - - /** - * Retrieves dmidecode for the device. Only supports Linux. - * - * @param osName name of OS (Linux, Windows, etc.) - * @param command dmidecode string keyword command - * @return String of the result - * @throws CollectorException if there is a problem encountered while performing collection - */ - public static String collectDmiDecodeValue(final OSName osName, final String command) - throws CollectorException { - ExecBuilder execBuilder = null; - try { - switch (osName) { - case LINUX: - execBuilder = new ExecBuilder("dmidecode").args("-s", command); - break; - default: - throw new CollectorException(String.format( - "Unsupported operating system detected: %s.", osName)); - } - - return execBuilder.exec().getStdOutResult().trim(); - } catch (IOException e) { - String msg = String.format("Could not call dmidecode using command: %s", execBuilder); - throw new CollectorException(msg, e); - } - } -} diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/DeviceInfoReport.java b/HIRS_Utils/src/main/java/hirs/data/persist/DeviceInfoReport.java index 00bd5eec..990fae3a 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/DeviceInfoReport.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/DeviceInfoReport.java @@ -2,12 +2,10 @@ package hirs.data.persist; import static org.apache.logging.log4j.LogManager.getLogger; -import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; +import javax.persistence.Transient; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -16,13 +14,8 @@ import javax.xml.bind.annotation.XmlSeeAlso; import hirs.utils.VersionHelper; import org.apache.logging.log4j.Logger; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; /** * A DeficeInfoReport is a Report used to transfer the @@ -67,48 +60,8 @@ public class DeviceInfoReport extends Report implements Serializable { private String clientApplicationVersion; @XmlElement - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name = "deviceInfoReport_id") - @LazyCollection(LazyCollectionOption.FALSE) - private List chassisInfo = new ArrayList<>(); - - @XmlElement - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name = "deviceInfoReport_id") - @LazyCollection(LazyCollectionOption.FALSE) - private List baseboardInfo = new ArrayList<>(); - - @XmlElement - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name = "deviceInfoReport_id") - @LazyCollection(LazyCollectionOption.FALSE) - private List processorInfo = new ArrayList<>(); - - @XmlElement - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name = "deviceInfoReport_id") - @LazyCollection(LazyCollectionOption.FALSE) - private List biosInfo = new ArrayList<>(); - - @XmlElement - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name = "deviceInfoReport_id") - @LazyCollection(LazyCollectionOption.FALSE) - private List nicInfo = new ArrayList<>(); - - @XmlElement - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name = "deviceInfoReport_id") - @LazyCollection(LazyCollectionOption.FALSE) - private List hardDriveInfo = new ArrayList<>(); - - @XmlElement - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name = "deviceInfoReport_id") - @LazyCollection(LazyCollectionOption.FALSE) - private List memoryInfo = new ArrayList<>(); - - + @Transient + private String paccorOutputString; /** * Default constructor necessary for marshalling/unmarshalling. @@ -258,62 +211,6 @@ public class DeviceInfoReport extends Report implements Serializable { return tpmInfo; } - /** - * Get list of ChassisComponentInfo obects, each representing a chassis. - * @return list of ChassisComponentInfo obects, each representing a chassis - */ - public List getChassisInfo() { - return chassisInfo; - } - - /** - * Get list of BaseboardComponentInfo obects, each representing a baseboard. - * @return list of BaseboardComponentInfo obects, each representing a baseboard - */ - public List getBaseboardInfo() { - return baseboardInfo; - } - - /** - * Get list of ProcessorComponentInfo obects, each representing a processor. - * @return list of ProcessorComponentInfo obects, each representing a processor - */ - public List getProcessorInfo() { - return processorInfo; - } - - /** - * Get list of BIOSComponentInfo obects, each representing a BIOS. - * @return list of BIOSComponentInfo obects, each representing a BIOS - */ - public List getBiosInfo() { - return biosInfo; - } - - /** - * Get list of NICComponentInfo obects, each representing a NIC. - * @return list of NICComponentInfo obects, each representing a NIC - */ - public List getNicInfo() { - return nicInfo; - } - - /** - * Get list of HardDriveComponentInfo obects, each representing a hard drive. - * @return list of HardDriveComponentInfo obects, each representing a hard drive - */ - public List getHardDriveInfo() { - return hardDriveInfo; - } - - /** - * Get list of MemoryComponentInfo obects, each representing a memory DIMM. - * @return list of MemoryComponentInfo obects, each representing a memory DIMM - */ - public List getMemoryInfo() { - return memoryInfo; - } - /** * Gets the client application version. * @return the client application version @@ -391,31 +288,19 @@ public class DeviceInfoReport extends Report implements Serializable { this.tpmInfo = tpmInfo; } - public void setChassisInfo(List chassisInfo) { - this.chassisInfo = Collections.unmodifiableList(chassisInfo); + /** + * Get the string returned from PACCOR's allcomponents.sh script. + * @return the string returned from PACCOR's allcomponents.sh script + */ + public String getPaccorOutputString() { + return paccorOutputString; } - public void setBaseboardInfo(List baseboardInfo) { - this.baseboardInfo = Collections.unmodifiableList(baseboardInfo); - } - - public void setProcessorInfo(List processorInfo) { - this.processorInfo = Collections.unmodifiableList(processorInfo); - } - - public void setBiosInfo(List biosInfo) { - this.biosInfo = Collections.unmodifiableList(biosInfo); - } - - public void setNicInfo(List nicInfo) { - this.nicInfo = Collections.unmodifiableList(nicInfo); - } - - public void setHardDriveInfo(List hardDriveInfo) { - this.hardDriveInfo = Collections.unmodifiableList(hardDriveInfo); - } - - public void setMemoryInfo(List memoryInfo) { - this.memoryInfo = Collections.unmodifiableList(memoryInfo); + /** + * Set the string returned from PACCOR's allcomponents.sh script. + * @param paccorOutputString the string returned from PACCOR's allcomponents.sh script + */ + public void setPaccorOutputString(String paccorOutputString) { + this.paccorOutputString = paccorOutputString; } } diff --git a/HIRS_Utils/src/main/java/hirs/data/service/DeviceRegisterImpl.java b/HIRS_Utils/src/main/java/hirs/data/service/DeviceRegisterImpl.java index ab22dddb..403561c5 100644 --- a/HIRS_Utils/src/main/java/hirs/data/service/DeviceRegisterImpl.java +++ b/HIRS_Utils/src/main/java/hirs/data/service/DeviceRegisterImpl.java @@ -51,17 +51,19 @@ public class DeviceRegisterImpl implements DeviceRegister { private Device registerDeviceToManager(final String deviceName, final DeviceInfoReport report) { Device savedDevice = deviceManager.getDevice(deviceName); - if (savedDevice == null) { - LOGGER.debug("device not found, saving new device"); - Device newDevice = new Device(deviceName, report); - DeviceGroup group = deviceGroupManager.getDeviceGroup(DeviceGroup.DEFAULT_GROUP); - newDevice.setDeviceGroup(group); - deviceManager.saveDevice(newDevice); - } else { + + if (savedDevice != null) { LOGGER.debug("device found, updating device"); savedDevice.setDeviceInfo(report); deviceManager.updateDevice(savedDevice); + return savedDevice; } - return deviceManager.getDevice(deviceName); + + LOGGER.debug("device not found, saving new device"); + Device newDevice = new Device(deviceName, report); + DeviceGroup group = deviceGroupManager.getDeviceGroup(DeviceGroup.DEFAULT_GROUP); + newDevice.setDeviceGroup(group); + deviceManager.saveDevice(newDevice); + return newDevice; } } diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 55b351f2..2d7f3212 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -1,5 +1,8 @@ package hirs.validation; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import hirs.data.persist.AppraisalStatus; import hirs.data.persist.ComponentInfo; import hirs.data.persist.DeviceInfoReport; @@ -95,6 +98,42 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } + /** + * Parses the output from PACCOR's allcomponents.sh script into ComponentInfo objects. + * @param paccorOutput the output from PACCOR's allcomoponents.sh + * @return a list of ComponentInfo objects built from paccorOutput + * @throws IOException if something goes wrong parsing the JSON + */ + public static List getComponentInfoFromPaccorOutput(final String paccorOutput) + throws IOException { + List componentInfoList = new ArrayList<>(); + + if (StringUtils.isNotEmpty(paccorOutput)) { + ObjectMapper objectMapper = new ObjectMapper(new JsonFactory()); + JsonNode rootNode = objectMapper.readTree(paccorOutput); + Iterator jsonComponentNodes + = rootNode.findValue("COMPONENTS").elements(); + while (jsonComponentNodes.hasNext()) { + JsonNode next = jsonComponentNodes.next(); + componentInfoList.add(new ComponentInfo( + getJSONNodeValueAsText(next, "MANUFACTURER"), + getJSONNodeValueAsText(next, "MODEL"), + getJSONNodeValueAsText(next, "SERIAL"), + getJSONNodeValueAsText(next, "REVISION"))); + } + } + + return componentInfoList; + } + + private static String getJSONNodeValueAsText(final JsonNode node, final String fieldName) { + if (node.hasNonNull(fieldName)) { + return node.findValue(fieldName).asText(); + } + return null; + + } + /** * Checks if the platform credential is valid. * @@ -408,17 +447,18 @@ public final class SupplyChainCredentialValidator implements CredentialValidator && identifier.getComponentModel() != null) .collect(Collectors.toList()); - List allDeviceInfoComponents = new ArrayList<>(); - allDeviceInfoComponents.addAll(deviceInfoReport.getChassisInfo()); - allDeviceInfoComponents.addAll(deviceInfoReport.getBaseboardInfo()); - allDeviceInfoComponents.addAll(deviceInfoReport.getBiosInfo()); - allDeviceInfoComponents.addAll(deviceInfoReport.getHardDriveInfo()); - allDeviceInfoComponents.addAll(deviceInfoReport.getNicInfo()); - allDeviceInfoComponents.addAll(deviceInfoReport.getMemoryInfo()); - allDeviceInfoComponents.addAll(deviceInfoReport.getProcessorInfo()); - - fieldValidation &= validateV2p0PlatformCredentialComponentsExpectingExactMatch( - validPcComponents, allDeviceInfoComponents); + String paccorOutputString = deviceInfoReport.getPaccorOutputString(); + try { + List componentInfoList + = getComponentInfoFromPaccorOutput(paccorOutputString); + fieldValidation &= validateV2p0PlatformCredentialComponentsExpectingExactMatch( + validPcComponents, componentInfoList); + } catch (IOException e) { + final String baseErrorMessage = "Error parsing JSON output from PACCOR: "; + LOGGER.error(baseErrorMessage + e.toString()); + LOGGER.error("PACCOR output string:\n" + paccorOutputString); + return new AppraisalStatus(ERROR, baseErrorMessage + e.getMessage()); + } if (!fieldValidation) { resultMessage.append("There are unmatched components\n"); diff --git a/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java b/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java index 0ba808ba..d6006a4d 100644 --- a/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java +++ b/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java @@ -1,25 +1,22 @@ package hirs.validation; -import hirs.client.collector.DeviceInfoCollectorHelper; +import hirs.client.collector.DeviceInfoCollector; import hirs.data.persist.AppraisalStatus; -import hirs.data.persist.BaseboardComponentInfo; -import hirs.data.persist.ChassisComponentInfo; import hirs.data.persist.ComponentInfo; import hirs.data.persist.DeviceInfoReport; import hirs.data.persist.FirmwareInfo; -import hirs.data.persist.HardDriveComponentInfo; import hirs.data.persist.HardwareInfo; -import hirs.data.persist.NetworkInfo; import hirs.data.persist.NICComponentInfo; +import hirs.data.persist.NetworkInfo; import hirs.data.persist.OSInfo; -import hirs.data.persist.ProcessorComponentInfo; import hirs.data.persist.TPMInfo; import hirs.data.persist.certificate.Certificate; import hirs.data.persist.certificate.CertificateAuthorityCredential; +import hirs.data.persist.certificate.CertificateTest; import hirs.data.persist.certificate.EndorsementCredential; import hirs.data.persist.certificate.PlatformCredential; - import hirs.data.persist.certificate.attributes.ComponentIdentifier; +import org.apache.commons.io.IOUtils; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.X500Name; @@ -46,22 +43,21 @@ import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.ObjectFactory; import org.testng.annotations.Test; -import hirs.data.persist.certificate.CertificateTest; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.IOException; import java.math.BigInteger; import java.net.InetAddress; import java.net.URISyntaxException; +import java.net.URL; import java.net.UnknownHostException; import java.nio.file.Files; import java.nio.file.Paths; import java.security.KeyFactory; - import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; @@ -90,12 +86,17 @@ import static org.powermock.api.mockito.PowerMockito.when; /** * Tests the SupplyChainValidator class. */ -@PrepareForTest({SupplyChainCredentialValidator.class, DeviceInfoCollectorHelper.class, +@PrepareForTest({SupplyChainCredentialValidator.class, DeviceInfoCollector.class, PlatformCredential.class, EndorsementCredential.class }) @PowerMockIgnore({"javax.xml.parsers.*", "org.apache.xerces.jaxp.*", "org.apache.logging.log4j.*", "javax.security.auth.*" }) public class SupplyChainCredentialValidatorTest { + private static final String SAMPLE_PACCOR_OUTPUT_TXT = "sample_paccor_output.txt"; + + private static final String SAMPLE_PACCOR_OUTPUT_WITH_EXTRA_COMPONENT_TXT + = "sample_paccor_output_with_extra_component.txt"; + private static HardwareInfo hardwareInfo; private SupplyChainCredentialValidator supplyChainCredentialValidator = new SupplyChainCredentialValidator(); @@ -395,11 +396,10 @@ public class SupplyChainCredentialValidatorTest { TEST_SERIAL_NUMBER, TEST_SERIAL_NUMBER)); deviceInfoReport = PowerMockito.spy(deviceInfoReport); - ChassisComponentInfo chassis = new ChassisComponentInfo(TEST_COMPONENT_MANUFACTURER, - TEST_COMPONENT_MODEL, TEST_SERIAL_NUMBER, TEST_COMPONENT_REVISION); - ArrayList chassisSerial = new ArrayList<>(); - chassisSerial.add(chassis); - PowerMockito.when(deviceInfoReport.getChassisInfo()).thenReturn(chassisSerial); + URL url = SupplyChainCredentialValidator.class.getResource( + SAMPLE_PACCOR_OUTPUT_WITH_EXTRA_COMPONENT_TXT); + String paccorOutputString = IOUtils.toString(url); + when(deviceInfoReport.getPaccorOutputString()).thenReturn(paccorOutputString); byte[] certBytes = Files.readAllBytes(Paths.get(CertificateTest.class. getResource(TEST_PLATFORM_CRED).toURI())); @@ -436,11 +436,10 @@ public class SupplyChainCredentialValidatorTest { deviceInfoReport = PowerMockito.spy(deviceInfoReport); - BaseboardComponentInfo base = new BaseboardComponentInfo(TEST_COMPONENT_MANUFACTURER, - TEST_COMPONENT_MODEL, TEST_SERIAL_NUMBER, TEST_COMPONENT_REVISION); - ArrayList baseSerial = new ArrayList<>(); - baseSerial.add(base); - PowerMockito.when(deviceInfoReport.getBaseboardInfo()).thenReturn(baseSerial); + URL url = SupplyChainCredentialValidator.class.getResource( + SAMPLE_PACCOR_OUTPUT_WITH_EXTRA_COMPONENT_TXT); + String paccorOutputString = IOUtils.toString(url); + when(deviceInfoReport.getPaccorOutputString()).thenReturn(paccorOutputString); byte[] certBytes = Files.readAllBytes(Paths.get(CertificateTest.class. getResource(TEST_PLATFORM_CRED).toURI())); @@ -1101,12 +1100,6 @@ public class SupplyChainCredentialValidatorTest { deviceInfoReport = PowerMockito.spy(deviceInfoReport); - BaseboardComponentInfo base = new BaseboardComponentInfo(TEST_COMPONENT_MANUFACTURER, - TEST_COMPONENT_MODEL, BAD_SERIAL, TEST_COMPONENT_REVISION); - ArrayList baseSerial = new ArrayList<>(); - baseSerial.add(base); - PowerMockito.when(deviceInfoReport.getBaseboardInfo()).thenReturn(baseSerial); - EndorsementCredential ec = PowerMockito.spy(new EndorsementCredential( Files.readAllBytes(Paths.get(getClass().getResource(EK_CERT).toURI())))); PowerMockito.when(ec, "getSerialNumber").thenReturn(pc.getHolderSerialNumber()); @@ -1385,25 +1378,16 @@ public class SupplyChainCredentialValidatorTest { return deviceInfoReport; } - private static DeviceInfoReport setupDeviceInfoReportWithComponents() { + private static DeviceInfoReport setupDeviceInfoReportWithComponents() throws IOException { + return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT); + } + + private static DeviceInfoReport setupDeviceInfoReportWithComponents( + final String paccorOutputResource) throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReport(); - when(deviceInfoReport.getProcessorInfo()).thenReturn( - Collections.singletonList(new ProcessorComponentInfo("Intel", - "Core i7", - "Not Specified", - "Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz"))); - List nicInfo = deviceInfoReport.getNicInfo(); - nicInfo.add( - new NICComponentInfo("Intel Corporation", - "Ethernet Connection I217-V", - "23:94:17:ba:86:5e", - "00")); - nicInfo.add( - new NICComponentInfo("Intel Corporation", - "82580 Gigabit Network Connection", - "90:e2:ba:31:83:10", - "")); - when(deviceInfoReport.getNicInfo()).thenReturn(nicInfo); + URL url = SupplyChainCredentialValidator.class.getResource(paccorOutputResource); + String paccorOutputString = IOUtils.toString(url); + when(deviceInfoReport.getPaccorOutputString()).thenReturn(paccorOutputString); return deviceInfoReport; } @@ -1461,7 +1445,7 @@ public class SupplyChainCredentialValidatorTest { } private PlatformCredential setupMatchingPlatformCredential( - final DeviceInfoReport deviceInfoReport) { + final DeviceInfoReport deviceInfoReport) throws IOException { PlatformCredential platformCredential = mock(PlatformCredential.class); when(platformCredential.getCredentialType()).thenReturn( @@ -1475,14 +1459,9 @@ public class SupplyChainCredentialValidatorTest { when(platformCredential.getVersion()) .thenReturn(hardwareInfo.getVersion()); - List deviceInfoComponents = new ArrayList<>(); - deviceInfoComponents.addAll(deviceInfoReport.getBaseboardInfo()); - deviceInfoComponents.addAll(deviceInfoReport.getBiosInfo()); - deviceInfoComponents.addAll(deviceInfoReport.getChassisInfo()); - deviceInfoComponents.addAll(deviceInfoReport.getHardDriveInfo()); - deviceInfoComponents.addAll(deviceInfoReport.getMemoryInfo()); - deviceInfoComponents.addAll(deviceInfoReport.getNicInfo()); - deviceInfoComponents.addAll(deviceInfoReport.getProcessorInfo()); + List deviceInfoComponents + = SupplyChainCredentialValidator.getComponentInfoFromPaccorOutput( + deviceInfoReport.getPaccorOutputString()); List componentIdentifierList = new ArrayList<>(); for (ComponentInfo deviceInfoComponent : deviceInfoComponents) { componentIdentifierList.add(new ComponentIdentifier( @@ -1505,9 +1484,11 @@ public class SupplyChainCredentialValidatorTest { /** * Tests that TPM 2.0 Platform Credentials validate correctly against the device info report * when there are no components. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testvalidatePlatformCredentialAttributesV2p0NoComponentsPass() { + public final void testvalidatePlatformCredentialAttributesV2p0NoComponentsPass() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReport(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); @@ -1521,9 +1502,11 @@ public class SupplyChainCredentialValidatorTest { /** * Tests that TPM 2.0 Platform Credentials validate correctly against the device info report * when there are components present. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testvalidatePlatformCredentialAttributesV2p0WithComponentsPass() { + public final void testvalidatePlatformCredentialAttributesV2p0WithComponentsPass() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); @@ -1538,9 +1521,11 @@ public class SupplyChainCredentialValidatorTest { * Tests that TPM 2.0 Platform Credentials validate correctly against the device info report * when there are components present, and when the PlatformSerial field holds the system's * serial number instead of the baseboard serial number. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSystemSerial() { + public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSystemSerial() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); when(platformCredential.getPlatformSerial()) @@ -1555,9 +1540,11 @@ public class SupplyChainCredentialValidatorTest { /** * Tests that the SupplyChainCredentialValidator fails when required fields are null. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testvalidatePlatformCredentialAttributesV2p0RequiredFieldsNull() { + public final void testvalidatePlatformCredentialAttributesV2p0RequiredFieldsNull() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); @@ -1654,9 +1641,11 @@ public class SupplyChainCredentialValidatorTest { /** * Tests that the SupplyChainCredentialValidator fails when required fields contain only empty * strings. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testvalidatePlatformCredentialAttributesV2p0RequiredFieldsEmpty() { + public final void testvalidatePlatformCredentialAttributesV2p0RequiredFieldsEmpty() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); @@ -1753,9 +1742,11 @@ public class SupplyChainCredentialValidatorTest { /** * Tests that {@link SupplyChainCredentialValidator} failes when a component exists in the * platform credential, but not in the device info report. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testvalidatePlatformCredentialAttributesV2p0MissingComponentInDeviceInfo() { + public final void testvalidatePlatformCredentialAttributesV2p0MissingComponentInDeviceInfo() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); @@ -1791,12 +1782,18 @@ public class SupplyChainCredentialValidatorTest { * Tests that SupplyChainCredentialValidator passes when everything matches but there are * extra components in the device info report that are not represented in the platform * credential. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testvalidatePlatformCredentialAttributesV2p0ExtraComponentInDeviceInfo() { - DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); + public final void testvalidatePlatformCredentialAttributesV2p0ExtraComponentInDeviceInfo() + throws IOException { + PlatformCredential platformCredential = setupMatchingPlatformCredential( + setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT)); + + // The device info report will contain one extra component. + DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents( + SAMPLE_PACCOR_OUTPUT_WITH_EXTRA_COMPONENT_TXT); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); AppraisalStatus result = SupplyChainCredentialValidator .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport); @@ -1804,14 +1801,6 @@ public class SupplyChainCredentialValidatorTest { Assert.assertEquals(result.getMessage(), SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID); - List hardDriveInfoList = new ArrayList<>(); - hardDriveInfoList.add(new HardDriveComponentInfo( - "ACME", - "Fancy Hard Drive", - "12345", - "2000" - )); - when(deviceInfoReport.getHardDriveInfo()).thenReturn(hardDriveInfoList); result = SupplyChainCredentialValidator .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport); @@ -1823,9 +1812,11 @@ public class SupplyChainCredentialValidatorTest { /** * Tests that SupplyChainCredentialValidator fails when a component is found in the platform * credential without a manufacturer or model. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testvalidatePlatformCredentialAttributesV2p0RequiredComponentFieldEmpty() { + public final void testvalidatePlatformCredentialAttributesV2p0RequiredComponentFieldEmpty() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); @@ -1870,9 +1861,11 @@ public class SupplyChainCredentialValidatorTest { /** * Tests that SupplyChainCredentialValidator passes when a component on the system has a * matching component in the platform certificate, except the serial value is missing. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoSerial() { + public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoSerial() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); @@ -1898,9 +1891,11 @@ public class SupplyChainCredentialValidatorTest { /** * Tests that SupplyChainCredentialValidator passes when a component on the system has a * matching component in the platform certificate, except the revision value is missing. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoRevision() { + public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoRevision() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); @@ -1927,9 +1922,11 @@ public class SupplyChainCredentialValidatorTest { * Tests that SupplyChainCredentialValidator passes when a component on the system has a * matching component in the platform certificate, except the serial and revision values * are missing. + * @throws IOException if unable to set up DeviceInfoReport from resource file */ @Test - public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOrRevision() { + public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOrRevision() + throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); diff --git a/HIRS_Utils/src/test/resources/hirs/validation/sample_paccor_output.txt b/HIRS_Utils/src/test/resources/hirs/validation/sample_paccor_output.txt new file mode 100755 index 00000000..92b5d9b2 --- /dev/null +++ b/HIRS_Utils/src/test/resources/hirs/validation/sample_paccor_output.txt @@ -0,0 +1,27 @@ +{ + + "PLATFORM": { + "PLATFORMMANUFACTURERSTR": "innotek GmbH","PLATFORMMODEL": "VirtualBox","PLATFORMVERSION": "1.2","PLATFORMSERIAL": "0" + }, + "COMPONENTS": [ + { + "MANUFACTURER": "Intel","MODEL": "Core i7","SERIAL": "Not Specified","REVISION": "Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz" + }, + { + "MANUFACTURER": "Intel Corporation","MODEL": "Ethernet Connection I217-V", "FIELDREPLACEABLE": "false","SERIAL": "23:94:17:ba:86:5e", "REVISION": "00" + }, + { + "MANUFACTURER": "Intel Corporation","MODEL": "82580 Gigabit Network Connection", "FIELDREPLACEABLE": "false", "SERIAL": "90:e2:ba:31:83:10", "REVISION": "" + } + ], + "PROPERTIES": [ + { + "NAME": "uname -r", + "VALUE": "3.10.0-862.11.6.el7.x86_64" + }, + { + "NAME": "cat /etc/centos-release", + "VALUE": "CentOS Linux release 7.5.1804 (Core) " + } + ] +} diff --git a/HIRS_Utils/src/test/resources/hirs/validation/sample_paccor_output_with_extra_component.txt b/HIRS_Utils/src/test/resources/hirs/validation/sample_paccor_output_with_extra_component.txt new file mode 100755 index 00000000..9f58ecf2 --- /dev/null +++ b/HIRS_Utils/src/test/resources/hirs/validation/sample_paccor_output_with_extra_component.txt @@ -0,0 +1,30 @@ +{ + + "PLATFORM": { + "PLATFORMMANUFACTURERSTR": "innotek GmbH","PLATFORMMODEL": "VirtualBox","PLATFORMVERSION": "1.2","PLATFORMSERIAL": "0" + }, + "COMPONENTS": [ + { + "MANUFACTURER": "Intel","MODEL": "Core i7","SERIAL": "Not Specified","REVISION": "Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz" + }, + { + "MANUFACTURER": "Intel Corporation","MODEL": "Ethernet Connection I217-V", "FIELDREPLACEABLE": "false","SERIAL": "23:94:17:ba:86:5e", "REVISION": "00" + }, + { + "MANUFACTURER": "Intel Corporation","MODEL": "82580 Gigabit Network Connection", "FIELDREPLACEABLE": "false", "SERIAL": "90:e2:ba:31:83:10", "REVISION": "" + }, + { + "MANUFACTURER": "Intel","MODEL": "platform2018", "FIELDREPLACEABLE": "false", "SERIAL": "BQKP52840678", "REVISION": "1.0" + } + ], + "PROPERTIES": [ + { + "NAME": "uname -r", + "VALUE": "3.10.0-862.11.6.el7.x86_64" + }, + { + "NAME": "cat /etc/centos-release", + "VALUE": "CentOS Linux release 7.5.1804 (Core) " + } + ] +} diff --git a/package/rpm/HIRS.spec b/package/rpm/HIRS.spec index 1debddaf..ebf7bab0 100644 --- a/package/rpm/HIRS.spec +++ b/package/rpm/HIRS.spec @@ -36,11 +36,11 @@ Summary : Host Integrity at Runtime and Startup (HIRS) Provisioner Group : System Environment/Base %if 0%{?build6} -Requires : tpm_module, java-1.8.0, wget, util-linux, chkconfig, sed, initscripts, coreutils, dmidecode, lshw, bash%{?RPM_EXTRA_CLIENT_DEPENDENCIES} +Requires : tpm_module, java-1.8.0, wget, util-linux, chkconfig, sed, initscripts, coreutils, dmidecode, paccor, bash%{?RPM_EXTRA_CLIENT_DEPENDENCIES} %endif %if 0%{?build7} -Requires : tpm_module, java-1.8.0, wget, util-linux, chkconfig, sed, systemd, coreutils, dmidecode, lshw, bash%{?RPM_EXTRA_CLIENT_DEPENDENCIES} +Requires : tpm_module, java-1.8.0, wget, util-linux, chkconfig, sed, systemd, coreutils, dmidecode, paccor, bash%{?RPM_EXTRA_CLIENT_DEPENDENCIES} %endif %description -n %{provisioner_package_name}