package com.intel.mtwilson.as.business; import com.intel.dcsg.cpg.crypto.CryptographyException; import java.util.Date; import com.intel.mtwilson.as.data.TblModuleManifestLog; import com.intel.mtwilson.as.data.TblHosts; import com.intel.mtwilson.as.data.TblModuleManifest; import com.intel.mtwilson.as.data.TblTaLog; import com.intel.mtwilson.as.data.TblPcrManifest; import com.intel.mtwilson.as.business.trust.Util; import com.intel.mountwilson.as.common.ASException; import com.intel.mtwilson.i18n.ErrorCode; //import com.intel.mtwilson.model; import com.intel.dcsg.cpg.crypto.Sha1Digest; import com.intel.mtwilson.as.controller.TblTaLogJpaController; import com.intel.mountwilson.as.hostmanifestreport.data.HostManifestReportType; import com.intel.mountwilson.as.hostmanifestreport.data.ManifestType; import com.intel.mountwilson.as.hosttrustreport.data.HostType; import com.intel.mountwilson.as.hosttrustreport.data.HostsTrustReportType; import com.intel.mtwilson.My; import com.intel.mtwilson.agent.HostAgent; import com.intel.mtwilson.agent.HostAgentFactory; import com.intel.mtwilson.as.data.MwAssetTagCertificate; import com.intel.mtwilson.datatypes.*; import com.intel.dcsg.cpg.jpa.PersistenceManager; import com.intel.mtwilson.model.Hostname; import java.util.*; import java.io.IOException; /** * * @author dsmagadx */ public class ReportsBO { private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ReportsBO.class); private static String ASSET_TAG_PCR = "22"; public ReportsBO() { super(); } // public ReportsBO(PersistenceManager pm) { // super(pm); // } public HostsTrustReportType getTrustReport(Collection<Hostname> hostNames) { // datatype.Hostname try { HostsTrustReportType hostsTrustReportType = new HostsTrustReportType(); for (Hostname host : hostNames) { TblHosts tblHosts = My.jpa().mwHosts().findByName(host.toString()); // datatype.Hostname if (tblHosts == null) { throw new ASException(ErrorCode.AS_HOST_NOT_FOUND, host); } List<TblTaLog> logs = My.jpa().mwTaLog().findTrustStatusByHostId(tblHosts.getId(), 5); if (logs != null) { for (TblTaLog log : logs) { HostType hostType = new HostType(); hostType.setHostName(host.toString()); // datatype.Hostname hostType.setMLEInfo(getMleInfo(tblHosts)); hostType.setTrustStatus(getTrustStatus(log.getError())); // @since 1.1 we are relying on the audit log for "created on", "created by", etc. type information // hostType.setCreatedOn(Util.getCalendar(tblHosts.getCreatedOn())); hostType.setVerifiedOn(Util.getCalendar(log.getUpdatedOn())); hostsTrustReportType.getHost().add(hostType); } } } return hostsTrustReportType; } catch (IOException | CryptographyException | ASException e) { // throw new ASException(e); // Bug: 1038 - prevent leaks in error messages to client logger.error("Error during retrieval of host trust report.", e); throw new ASException(ErrorCode.AS_HOST_REPORT_ERROR, e.getClass().getSimpleName()); } } public HostManifestReportType getReportManifest(Hostname hostName) { // datatype.Hostname HostManifestReportType hostManifestReportType = new HostManifestReportType(); /* * if (hostName == null || hostName.isEmpty()) { throw new * ASException(ErrorCode.VALIDATION_ERROR, "Input Hostname " + hostName * + " is empty."); } * */ TblHosts tblHosts; try { tblHosts = My.jpa().mwHosts().findByName(hostName.toString()); // datatype.Hostname if (tblHosts == null) { throw new ASException(ErrorCode.AS_HOST_NOT_FOUND, hostName.toString()); } Date lastStatusTs = My.jpa().mwTaLog().findLastStatusTs(tblHosts.getId()); if (lastStatusTs != null) { List<TblTaLog> logs = My.jpa().mwTaLog().findLogsByHostId(tblHosts.getId(), lastStatusTs); com.intel.mountwilson.as.hostmanifestreport.data.HostType hostType = new com.intel.mountwilson.as.hostmanifestreport.data.HostType(); hostType.setName(hostName.toString()); // datatype.Hostname if (logs != null) { for (TblTaLog log : logs) { ManifestType manifest = new ManifestType(); manifest.setName(Integer.parseInt(log.getManifestName())); manifest.setValue(log.getManifestValue()); manifest.setVerifiedOn(Util.getCalendar(log.getUpdatedOn())); manifest.setTrustStatus(getTrustStatus(log.getTrustStatus())); hostType.getManifest().add(manifest); } } hostManifestReportType.setHost(hostType); } return hostManifestReportType; } catch(Exception e) { // throw new ASException(ErrorCode.HTTP_INTERNAL_SERVER_ERROR, e.toString()); // Bug: 1038 - prevent leaks in error messages to client logger.error("Error during retrieval of host trust report.", e); throw new ASException(ErrorCode.AS_HOST_REPORT_ERROR, e.getClass().getSimpleName()); } } private String getMleInfo(TblHosts tblHosts) { return String.format("BIOS:%s-%s,VMM:%s:%s", tblHosts.getBiosMleId().getName(), tblHosts.getBiosMleId().getVersion(), tblHosts.getVmmMleId().getName(), tblHosts.getVmmMleId().getVersion()); } private Integer getTrustStatus(String trustString) { int bios = 0; int vmm = 0; String[] parts = trustString.split(","); for (String sub : parts) { String[] subParts = sub.split(":"); if (subParts[0].equals("BIOS")) { bios = Integer.parseInt(subParts[1]); } else { vmm = Integer.parseInt(subParts[1]); } } return (bios == 1 && vmm == 1) ? 1 : 0; } private Integer getTrustStatus(boolean trustStatus) { if (trustStatus) { return 1; } else { return 0; } } public String getHostAttestationReport(Hostname hostName) { TblHosts tblHosts; try { tblHosts = My.jpa().mwHosts().findByName(hostName.toString()); if (tblHosts == null) { throw new ASException(ErrorCode.AS_HOST_NOT_FOUND, hostName.toString()); } if (tblHosts.getAddOnConnectionInfo() != null && tblHosts.getAddOnConnectionInfo().contains("http")) { throw new ASException(ErrorCode.AS_OPERATION_NOT_SUPPORTED, "getHostAttestationReport does not support VMWare hosts."); } HostAgentFactory factory = new HostAgentFactory(); HostAgent agent = factory.getHostAgent(tblHosts); // PcrManifest pcrManifest = agent.getPcrManifest(); return agent.getHostAttestationReport("0,17,18,19,20"); // maybe just 17,18,19,20 // "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23" } catch (ASException aex) { throw aex; } catch (Exception ex) { // throw new ASException(ex); // Bug: 1038 - prevent leaks in error messages to client logger.error("Error during retrieval of host attestation report.", ex); throw new ASException(ErrorCode.AS_HOST_ATTESTATION_REPORT_ERROR, ex.getClass().getSimpleName()); } } public AttestationReport getAttestationReport(Hostname hostName, Boolean failureOnly) { try { logger.debug("getAttestationReport - Received request to generate attestation report for {} with failuresOnly set to {}.", hostName.toString(), failureOnly); AttestationReport attestationReport = new AttestationReport(); /* * if (hostName == null || hostName.isEmpty()) { throw new * ASException(ErrorCode.VALIDATION_ERROR, "Input Hostname " + hostName * + " is empty."); } * */ TblHosts tblHosts = My.jpa().mwHosts().findByName(hostName.toString()); // datatype.Hostname if (tblHosts == null) { throw new ASException(ErrorCode.AS_HOST_NOT_FOUND, hostName.toString()); } TblTaLogJpaController tblTaLogJpaController = My.jpa().mwTaLog(); Date lastStatusTs = tblTaLogJpaController.findLastStatusTs(tblHosts.getId()); if (lastStatusTs != null) { List<TblTaLog> logs = tblTaLogJpaController.findLogsByHostId(tblHosts.getId(), lastStatusTs); com.intel.mountwilson.as.hostmanifestreport.data.HostType hostType = new com.intel.mountwilson.as.hostmanifestreport.data.HostType(); hostType.setName(hostName.toString()); // datatype.Hostname if (logs != null) { for (TblTaLog log : logs) { logger.debug("getAttestationReport - Processing the PCR {} with trust status {}.", log.getManifestName(), log.getTrustStatus()); boolean value = (failureOnly && log.getTrustStatus() == false); if (!failureOnly || value) { if (log.getManifestName().equalsIgnoreCase(ASSET_TAG_PCR)) { attestationReport.getPcrLogs().add(getPcrLogReportForAssetTag(log, tblHosts.getId())); } else { attestationReport.getPcrLogs().add(getPcrManifestLog(tblHosts, log, failureOnly)); } } } } } // temp fix to get pcr showing up in trust report /*HostAgentFactory factory = new HostAgentFactory(); HostAgent agent = factory.getHostAgent(tblHosts); if(agent != null) { String hostUUID; Map<String,String> attrs = agent.getHostAttributes(); if (attrs != null && attrs.containsKey("Host_UUID")) { hostUUID = attrs.get("Host_UUID"); AssetTagCertBO atagCertBO = new AssetTagCertBO(); MwAssetTagCertificate atagCert = atagCertBO.findValidAssetTagCertForHost(hostUUID); if (atagCert != null) { logger.debug("Found a valid asset tag certificate for the host {} with UUID {}.", tblHosts.getName(), hostUUID); PcrManifest pcrManifest = agent.getPcrManifest(); Pcr pcr = pcrManifest.getPcr(22); PcrLogReport manifest = new PcrLogReport(); manifest.setName(22); manifest.setValue(pcr.getValue().toString()); //Sha1Digest sha1d = new Sha1Digest(atagCert.getPCREvent()); manifest.setWhiteListValue(new Sha1Digest(atagCert.getPCREvent()).toString()); if(manifest.getValue().equals(manifest.getWhiteListValue())) { manifest.setTrustStatus(1); }else{ manifest.setTrustStatus(0); } manifest.setVerifiedOn(new Date()); attestationReport.getPcrLogs().add(manifest); } } else { logger.debug("assetTag trustVerfication could not find UUID for " + tblHosts.getName()); } }*/ return attestationReport; } catch(IOException | CryptographyException | ASException | NumberFormatException ex) { // throw new ASException(ErrorCode.HTTP_INTERNAL_SERVER_ERROR, e.toString()); // Bug: 1038 - prevent leaks in error messages to client logger.error("Error during retrieval of host attestation report.", ex); throw new ASException(ErrorCode.AS_HOST_ATTESTATION_REPORT_ERROR, ex.getClass().getSimpleName()); } } public PcrLogReport getPcrManifestLog(TblHosts tblHosts, TblTaLog log, Boolean failureOnly) throws NumberFormatException, IOException { TblPcrManifest tblPcrManifest = getPcrModuleManifest(tblHosts,log.getMleId(),log.getManifestName()); logger.debug("getPcrManifestLog - Got data from mw_pcr_manifest table with pcr name {} and value {}.", tblPcrManifest.getName(), tblPcrManifest.getValue()); PcrLogReport manifest = new PcrLogReport(); manifest.setName(Integer.parseInt(log.getManifestName())); manifest.setValue(log.getManifestValue()); manifest.setVerifiedOn(log.getUpdatedOn()); manifest.setTrustStatus(getTrustStatus(log.getTrustStatus())); manifest.setWhiteListValue(tblPcrManifest.getValue()); // if (log.getTblModuleManifestLogCollection() != null && log.getTblModuleManifestLogCollection().size() > 0) { addManifestLogs(tblHosts.getId(), manifest, log, failureOnly,tblPcrManifest);// 20130417 added host id to parameter list so addManifestLogs can find host-specific module values // } return manifest; } // private String getWhitelListValue(TblHosts tblHosts, Integer mleId, String manifestName) { // // Collection<TblPcrManifest> pcrManifestCollection = null; // // if (tblHosts.getVmmMleId().getId() == mleId) { // pcrManifestCollection = tblHosts.getVmmMleId().getTblPcrManifestCollection(); // } else { // pcrManifestCollection = tblHosts.getBiosMleId().getTblPcrManifestCollection(); // } // // if (pcrManifestCollection != null) { // for (TblPcrManifest pcrManifest : pcrManifestCollection) { // if (pcrManifest.getName().equals(manifestName)) { // return pcrManifest.getValue(); // } // } // } // return null; // // } private void addManifestLogs(Integer hostId, PcrLogReport manifest, TblTaLog log, Boolean failureOnly,TblPcrManifest tblPcrManifest) throws IOException { HashMap<String,ModuleLogReport> moduleReports = new HashMap<>(); if(log.getTblModuleManifestLogCollection() != null){ logger.debug("addManifestLogs - This is module based attestation with {} of modules.", log.getTblModuleManifestLogCollection().size()); for (TblModuleManifestLog moduleManifestLog : log.getTblModuleManifestLogCollection()) { moduleReports.put(moduleManifestLog.getName(), new ModuleLogReport(moduleManifestLog.getName(), moduleManifestLog.getValue(), moduleManifestLog.getWhitelistValue(),0)); } } if(!failureOnly){ logger.debug("FailureOnly flag is false. Adding all manifests."); for(TblModuleManifest moduleManifest : tblPcrManifest.getMleId().getTblModuleManifestCollection()){ if(moduleManifest.getExtendedToPCR().equalsIgnoreCase(tblPcrManifest.getName()) && !moduleReports.containsKey(moduleManifest.getComponentName())){ if( moduleManifest.getUseHostSpecificDigestValue() != null && moduleManifest.getUseHostSpecificDigestValue().booleanValue() ) { // For open source we used to have multiple module manifests for the same hosts. So, the below query by hostID was returning multiple results. //String hostSpecificDigestValue = new TblHostSpecificManifestJpaController(getEntityManagerFactory()).findByHostID(hostId).getDigestValue(); String hostSpecificDigestValue = My.jpa().mwHostSpecificManifest().findByModuleAndHostID(hostId, moduleManifest.getId()).getDigestValue(); moduleReports.put(moduleManifest.getComponentName(), new ModuleLogReport(moduleManifest.getComponentName(), hostSpecificDigestValue, hostSpecificDigestValue, 1)); } else { moduleReports.put(moduleManifest.getComponentName(), new ModuleLogReport(moduleManifest.getComponentName(), moduleManifest.getDigestValue(), moduleManifest.getDigestValue(),1)); } } } } manifest.getModuleLogs().addAll(moduleReports.values()); } private TblPcrManifest getPcrModuleManifest(TblHosts tblHosts, Integer mleId, String manifestName) { Collection<TblPcrManifest> pcrManifestCollection; if (tblHosts.getVmmMleId().getId().intValue() == mleId.intValue()) { pcrManifestCollection = tblHosts.getVmmMleId().getTblPcrManifestCollection(); } else { pcrManifestCollection = tblHosts.getBiosMleId().getTblPcrManifestCollection(); } if (pcrManifestCollection != null) { for (TblPcrManifest pcrManifest : pcrManifestCollection) { if (pcrManifest.getName().equals(manifestName)) { return pcrManifest; } } } throw new ASException(ErrorCode.AS_PCR_MANIFEST_MISSING,manifestName,mleId,tblHosts.getName()); } private PcrLogReport getPcrLogReportForAssetTag(TblTaLog taLog, Integer hostId) { logger.debug("getPcrLogReportForAssetTag : Creating pcr log report for asset tag verification for host with uuid {}.", hostId); AssetTagCertBO atagCertBO = new AssetTagCertBO(); MwAssetTagCertificate atagCert = atagCertBO.findValidAssetTagCertForHost(hostId); if (atagCert != null) { logger.debug("getPcrLogReportForAssetTag : Found a valid asset tag certificate for the host with white list value {}", atagCert.getPCREvent().toString()); PcrLogReport manifest = new PcrLogReport(); manifest.setName(Integer.parseInt(ASSET_TAG_PCR)); manifest.setValue(taLog.getManifestValue()); manifest.setWhiteListValue(new Sha1Digest(atagCert.getPCREvent()).toString()); if(manifest.getValue().equals(manifest.getWhiteListValue())) { manifest.setTrustStatus(1); }else{ manifest.setTrustStatus(0); } manifest.setVerifiedOn(new Date()); return manifest; } return null; } }