/* * Copyright (C) 2013 Intel Corporation * All rights reserved. */ package com.intel.mtwilson.as.business; import com.fasterxml.jackson.databind.ObjectMapper; import com.intel.mtwilson.i18n.ErrorCode; import com.intel.mountwilson.as.common.ASException; import com.intel.mtwilson.My; import com.intel.mtwilson.agent.HostAgent; import com.intel.mtwilson.agent.HostAgentFactory; import com.intel.mtwilson.as.controller.TblHostSpecificManifestJpaController; import com.intel.mtwilson.as.controller.TblHostsJpaController; import com.intel.mtwilson.as.controller.TblMleJpaController; import com.intel.mtwilson.as.controller.TblSamlAssertionJpaController; import com.intel.mtwilson.as.controller.TblTaLogJpaController; import com.intel.mtwilson.as.controller.exceptions.IllegalOrphanException; import com.intel.mtwilson.as.controller.exceptions.NonexistentEntityException; import com.intel.mtwilson.as.data.MwAssetTagCertificate; import com.intel.mtwilson.as.data.TblHostSpecificManifest; import com.intel.mtwilson.as.data.TblHosts; import com.intel.mtwilson.as.data.TblMle; import com.intel.mtwilson.as.data.TblModuleManifest; import com.intel.mtwilson.as.data.TblSamlAssertion; import java.io.IOException; import com.intel.mtwilson.as.data.TblTaLog; import com.intel.mtwilson.as.ASComponentFactory; import com.intel.dcsg.cpg.crypto.CryptographyException; import com.intel.dcsg.cpg.crypto.RsaUtil; import com.intel.dcsg.cpg.crypto.SimpleKeystore; import com.intel.dcsg.cpg.io.Resource; import com.intel.dcsg.cpg.io.UUID; import com.intel.dcsg.cpg.x509.X509Util; import com.intel.mtwilson.datatypes.*; import com.intel.dcsg.cpg.jpa.PersistenceManager; import com.intel.mtwilson.model.*; import com.intel.mtwilson.model.PcrIndex; import com.intel.mtwilson.tls.policy.TlsPolicyChoice; import com.intel.mtwilson.tls.policy.factory.impl.TblHostsTlsPolicyFactory; import com.intel.mtwilson.tls.policy.jdbi.TlsPolicyDAO; import com.intel.mtwilson.tls.policy.jdbi.TlsPolicyJdbiFactory; import com.intel.mtwilson.tls.policy.jdbi.TlsPolicyRecord; import com.intel.mtwilson.tls.policy.codec.impl.JsonTlsPolicyReader; import com.intel.mtwilson.tls.policy.codec.impl.JsonTlsPolicyWriter; import com.intel.mtwilson.util.ResourceFinder; import java.io.FileInputStream; import java.io.InputStream; import java.net.MalformedURLException; import java.security.InvalidKeyException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.SignatureException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * All settings should be via setters, not via constructor, because this class * may be instantiated by a factory. * * @author dsmagadx */ public class HostBO { private static final String COMMAND_LINE_MANIFEST = "/b.b00 vmbTrustedBoot=true tboot=0x0x101a000"; public static final PcrIndex LOCATION_PCR = PcrIndex.PCR22; private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(HostBO.class); private TblMle biosMleId = null; private TblMle vmmMleId = null; // private byte[] dataEncryptionKey = null; // private TblLocationPcrJpaController locationPcrJpaController = new TblLocationPcrJpaController(getEntityManagerFactory()); // private TblMleJpaController mleController = new TblMleJpaController(getEntityManagerFactory()); // private TblHostsJpaController hostController = new TblHostsJpaController(getEntityManagerFactory()); // private HostTrustPolicyManager hostTrustPolicyFactory = new HostTrustPolicyManager(getEntityManagerFactory()); // private TblHostSpecificManifestJpaController hostSpecificManifestJpaController = new TblHostSpecificManifestJpaController(getEntityManagerFactory()); // private TblModuleManifestJpaController moduleManifestJpaController = new TblModuleManifestJpaController(getEntityManagerFactory()); /* public void setDataEncryptionKey(byte[] key) { try { TblHosts.dataCipher = new Aes128DataCipher(new Aes128(key)); } catch(CryptographyException e) { log.error("Cannot initialize data encryption cipher", e); } }*/ public HostBO() { super(); } // public HostBO(PersistenceManager pm) { // super(pm); // // } // public HostResponse addHost(TxtHost host, PcrManifest pcrManifest, HostAgent agent, String uuid, Object... tlsObjects) { public HostResponse addHost(TxtHost host, PcrManifest pcrManifest, HostAgent agent, String uuid) { // JONATHAN BOOKMARK TODO COMMENT OUT THIS BLOCK BECAUSE OF CLEAR TEXT PASSWORDS AFTER DEBUGGING // if( log.isDebugEnabled() ) { // try { // ObjectMapper mapper = new ObjectMapper(); // log.debug("addHost input: {}", mapper.writeValueAsString(host)); //This statement may contain clear text passwords // } // catch(IOException e) { // log.debug("cannot serialize host input to addHost", e); // } // } log.trace("HOST BO ADD HOST STARTING"); try { TblMle biosMleId = findBiosMleForHost(host); TblMle vmmMleId = findVmmMleForHost(host); Vendor hostType; log.trace("HOST BO ADD HOST STARTING"); checkForDuplicate(host); getBiosAndVMM(host); log.debug("Getting Server Identity."); // BUG #497 setting default tls policy name and empty keystore for all new hosts. TblHosts tblHosts = new TblHosts(); //System.err.println("stdalex addHost " + host.getHostName() + " with cs == " + host.getAddOn_Connection_String()); tblHosts.setAddOnConnectionInfo(host.getAddOn_Connection_String()); setTlsPolicyFields(tblHosts, host); // Using the connection string we will find out the type of the host. This information would be used later ConnectionString hostConnString = new ConnectionString(host.getAddOn_Connection_String()); hostType = hostConnString.getVendor(); if (host.getHostName() != null) { tblHosts.setName(host.getHostName().toString()); } if (host.getHostName() != null) { tblHosts.setIPAddress(host.getHostName().toString()); } if (host.getPort() != null) { tblHosts.setPort(host.getPort()); } if (agent == null) { HostAgentFactory factory = new HostAgentFactory(); agent = factory.getHostAgent(tblHosts); } if( agent.isAikAvailable() ) { // INTEL and CITRIX PublicKey publicKey = agent.getAik(); String publicKeySha1 = Sha1Digest.valueOf(publicKey.getEncoded()).toString(); if (My.jpa().mwHosts().findByAikPublicKeySha1(publicKeySha1) != null) { throw new ASException(ErrorCode.AS_DUPLICATE_AIK_PUBLIC_KEY, publicKeySha1); } // stores the AIK public key (and certificate, if available) in the host record, and sets AIK_SHA1=SHA1(AIK_PublicKey) on the host record too setAikForHost(tblHosts, host, agent); // Intel hosts return an X509 certificate for the AIK public key, signed by the privacy CA. so we must verify the certificate is ok. if( agent.isAikCaAvailable() ) { // we have to check that the aik certificate was signed by a trusted privacy ca X509Certificate hostAikCert = X509Util.decodePemCertificate(tblHosts.getAIKCertificate()); hostAikCert.checkValidity(); // AIK certificate must be valid today boolean validCaSignature = isAikCertificateTrusted(hostAikCert); if( !validCaSignature ) { throw new ASException(ErrorCode.AS_INVALID_AIK_CERTIFICATE, host.getHostName().toString()); } } } // retrieve the complete manifest for the host, includes ALL pcr's and if there is module info available it is included also. if (pcrManifest == null) pcrManifest = agent.getPcrManifest(); // currently Vmware has pcr+module, but in 1.2 we are adding module attestation for Intel hosts too ; citrix would be just pcr for now i guess // send the pcr manifest to a vendor-specific class in order to extract any host-specific information // for vmware this is the "HostTpmCommandLineEventDetails" which is a host-specific value and must be // saved into mw_host_specific _manifest (using the MLE information obtained with getBiosAndVmm(host) above...) // HostReport hostReport = new HostReport(); // hostReport.aik = null; // hostReport.pcrManifest = pcrManifest; // hostReport.tpmQuote = null; // hostReport.variables = new HashMap<String,String>(); // for example if we know a UUID ... we would ADD IT HERE // TrustPolicy hostSpecificTrustPolicy = hostTrustPolicyFactory.createHostSpecificTrustPolicy(hostReport, biosMleId, vmmMleId); // Bug: 749: We need to handle the host specific modules only if the PCR 19 is selected for attestation List<TblHostSpecificManifest> tblHostSpecificManifests = null; if(vmmMleId.getRequiredManifestList().contains(PcrIndex.PCR19.toString())) { log.info("Host specific modules would be retrieved from the host that extends into PCR 19."); // Added the Vendor parameter to the below function so that we can handle the host specific records differently for different types of hosts. tblHostSpecificManifests = createHostSpecificManifestRecords(vmmMleId, pcrManifest, hostType); } else { log.info("Host specific modules will not be configured since PCR 19 is not selected for attestation"); } // now for vmware specifically, we have to pass this along to the vmware-specific function because it knows which modules are host-specific (the commandline event) and has to store those in mw_host_specific ... // pcrMap = getHostPcrManifest(tblHosts, host); // for all hosts (used to be just vmware, but no reason right now to make it vmware-specific...), if pcr 22 happens to match our location database, populate the location field in the host record tblHosts.setLocation( getLocation(pcrManifest) ); //Bug: 597, 594 & 583. Here we were trying to get the length of the TlsKeystore without checking if it is NULL or not. // If in case it is NULL, it would throw NullPointerException log.debug("Saving Host in database with TlsPolicyName {} and TlsKeystoreLength {}", tblHosts.getTlsPolicyName(), tblHosts.getTlsKeystore() == null ? "null" : tblHosts.getTlsKeystore().length); log.trace("HOST BO CALLING SAVEHOSTINDATABASE"); Map<String,String> attributes = agent.getHostAttributes(); String hostUuidAttr = attributes.get("Host_UUID"); if ((attributes != null) && (!attributes.isEmpty()) && (hostUuidAttr != null)) tblHosts.setHardwareUuid(hostUuidAttr.toLowerCase().trim()); saveHostInDatabase(tblHosts, host, pcrManifest, tblHostSpecificManifests, biosMleId, vmmMleId, uuid); // Now that the host has been registered successfully, let us see if there is an asset tag certificated configured for the host // to which the host has to be associated associateAssetTagCertForHost(host, agent.getHostAttributes()); //attributes); } catch (ASException ase) { //System.err.println("JIM DEBUG"); //ase.printStackTrace(System.err); throw ase; } // catch(CryptographyException e) { // throw new ASException(e,ErrorCode.AS_ENCRYPTION_ERROR, e.getCause() == null ? e.getMessage() : e.getCause().getMessage()); // } catch (Exception e) { //System.err.println("JIM DEBUG"); //e.printStackTrace(System.err); // throw new ASException(e); // Bug: 1038 - prevent leaks in error messages to client log.error("Error during registration of host.", e); throw new ASException(ErrorCode.AS_REGISTER_HOST_ERROR, e.getClass().getSimpleName()); } return new HostResponse(ErrorCode.OK); } /** * THIS IS A DUPLICATE OF WHAT IS THERE IN MANAGEMENT SERVICE HOSTBO.JAVA. IF YOU MAKE ANY CHANGE, PLEASE * CHANGE IT IN THE OTHER LOCATION AS WELL. * * @param hostAikCert * @return */ private boolean isAikCertificateTrusted(X509Certificate hostAikCert) { log.debug("isAikCertificateTrusted {}", hostAikCert.getSubjectX500Principal().getName()); // read privacy ca certificate. if there is a privacy ca list file available (PrivacyCA.pem) we read the list from that. otherwise we just use the single certificate in PrivacyCA.cer (DER formatt) HashSet<X509Certificate> pcaList = new HashSet<>(); try (InputStream privacyCaIn = new FileInputStream(ResourceFinder.getFile("PrivacyCA.list.pem"))) { List<X509Certificate> privacyCaCerts = X509Util.decodePemCertificates(IOUtils.toString(privacyCaIn)); pcaList.addAll(privacyCaCerts); //IOUtils.closeQuietly(privacyCaIn); log.debug("Added {} certificates from PrivacyCA.list.pem", privacyCaCerts.size()); } catch(Exception ex) { log.warn("Cannot load PrivacyCA.list.pem", ex); } try (InputStream privacyCaIn = new FileInputStream(ResourceFinder.getFile("PrivacyCA.pem"))) { X509Certificate privacyCaCert = X509Util.decodePemCertificate(IOUtils.toString(privacyCaIn)); pcaList.add(privacyCaCert); //IOUtils.closeQuietly(privacyCaIn); log.debug("Added certificate from PrivacyCA.pem"); } catch(Exception ex) { log.warn("Cannot load PrivacyCA.pem",ex); } boolean validCaSignature = false; for(X509Certificate pca : pcaList) { try { if( Arrays.equals(pca.getSubjectX500Principal().getEncoded(), hostAikCert.getIssuerX500Principal().getEncoded()) ) { log.debug("Found matching CA: {}", pca.getSubjectX500Principal().getName()); pca.checkValidity(hostAikCert.getNotBefore()); // Privacy CA certificate must have been valid when it signed the AIK certificate hostAikCert.verify(pca.getPublicKey()); // verify the trusted privacy ca signed this aik cert. throws NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException validCaSignature = true; } } catch(CertificateException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) { log.debug("Failed to verify AIK signature with CA", e); // but don't re-throw because maybe another cert in the list is a valid signer } } return validCaSignature; } private String getLocation(PcrManifest pcrManifest) throws IOException { if( pcrManifest == null ) { return null; } if( pcrManifest.containsPcr(LOCATION_PCR) ) { String value = pcrManifest.getPcr(LOCATION_PCR).getValue().toString(); return My.jpa().mwLocationPcr().findTblLocationPcrByPcrValue(value); } return null; } private void createHostSpecificManifest(List<TblHostSpecificManifest> tblHostSpecificManifests, TblHosts tblHosts) throws IOException { if (tblHostSpecificManifests != null && !tblHostSpecificManifests.isEmpty()) { for(TblHostSpecificManifest tblHostSpecificManifest : tblHostSpecificManifests){ tblHostSpecificManifest.setHostID(tblHosts.getId()); My.jpa().mwHostSpecificManifest().create(tblHostSpecificManifest); } } } private void deletePrivateTlsPolicy(TblHosts target) throws IOException { try(TlsPolicyDAO tlsPolicyDao = TlsPolicyJdbiFactory.tlsPolicyDAO()) { tlsPolicyDao.deletePrivateTlsPolicyByHostId(target.getUuid_hex()); } } private void setTlsPolicyFields(TblHosts target, TxtHost from) throws IOException { setTlsPolicyFields(target, from.getTlsPolicyChoice()); } private void setTlsPolicyFields(TblHosts target, TlsPolicyChoice from) throws IOException { // if there is a tls policy id, we save it directly in the host record // but if there is a tls policy descriptor, we need to create or update a per-from.(private) tls policy and // then set its id on the host record if( from != null && from.getTlsPolicyDescriptor() != null && from.getTlsPolicyDescriptor().getPolicyType() != null && !from.getTlsPolicyDescriptor().getPolicyType().isEmpty()) { target.setTlsPolicyId(null); target.setTlsPolicyDescriptor(from.getTlsPolicyDescriptor()); target.setTlsKeystore(null); target.setTlsPolicyName(null); } else if( from != null && from.getTlsPolicyId() != null && !from.getTlsPolicyId().isEmpty() ) { // a private tls policy may or may not exist but the host refers to one anyway target.setTlsPolicyId(from.getTlsPolicyId()); // automatically clears the old tls policy name and tls keystore fields as well as the new tls policy descriptor field target.setTlsPolicyDescriptor(null); target.setTlsKeystore(null); target.setTlsPolicyName(null); } else { // all these null will cause server default tls policy to be used, if available target.setTlsPolicyId(null); target.setTlsPolicyDescriptor(null); target.setTlsKeystore(null); target.setTlsPolicyName(null); } } private void storePrivateTlsPolicy(TblHosts target) throws IOException { // look for an existing private tls policy record - we ignore the (possibly) existing tls policy id in target because it might be a shared policy and we dont' want to update that one; if it's a private policy the dao will find it try(TlsPolicyDAO tlsPolicyDao = TlsPolicyJdbiFactory.tlsPolicyDAO()) { if( target.getTlsPolicyDescriptor() != null ) { // a descriptor is set so we assume a private policy and look to either update an existing one or create a new one TlsPolicyRecord existingTlsPolicy = tlsPolicyDao.findPrivateTlsPolicyByHostId(target.getUuid_hex()); // will only return a private policy if one is associated with this host if( existingTlsPolicy == null ) { log.debug("storePrivateTlsPolicy creating new private policy"); // no private tls policy exists yet for this host; so we create a new one and we'll save it TlsPolicyRecord newTlsPolicy = new TlsPolicyRecord(); newTlsPolicy.setId(new UUID()); newTlsPolicy.setName(target.getUuid_hex()); newTlsPolicy.setPrivate(true); newTlsPolicy.setContentType("application/json"); JsonTlsPolicyWriter tlsPolicyWriter = new JsonTlsPolicyWriter(); newTlsPolicy.setContent(tlsPolicyWriter.write(target.getTlsPolicyDescriptor())); tlsPolicyDao.insertTlsPolicy(newTlsPolicy); target.setTlsPolicyId(newTlsPolicy.getId().toString()); // automatically clears the old tls policy name and tls keystore fields as well as the new tls policy descriptor field } else { log.debug("storePrivateTlsPolicy updating existing private policy"); // a private tls policy already exists for this host, so update it with the new descriptor existingTlsPolicy.setContentType("application/json"); JsonTlsPolicyWriter tlsPolicyWriter = new JsonTlsPolicyWriter(); existingTlsPolicy.setContent(tlsPolicyWriter.write(target.getTlsPolicyDescriptor())); tlsPolicyDao.updateTlsPolicy(existingTlsPolicy); target.setTlsPolicyId(existingTlsPolicy.getId().toString()); // automatically clears the old tls policy name and tls keystore fields as well as the new tls policy descriptor field } } else if( target.getTlsPolicyId() != null ) { TlsPolicyRecord existingTlsPolicy = tlsPolicyDao.findPrivateTlsPolicyByHostId(target.getUuid_hex()); // will only return a private policy if one is associated with this host if( existingTlsPolicy != null && !target.getTlsPolicyId().equalsIgnoreCase(existingTlsPolicy.getId().toString()) ) { log.debug("storePrivateTlsPolicy deleting existing private policy because host is now linked to a shared policy"); // an id is set so we assume a shared policy, and therefore try to delete any existing private policy for the host deletePrivateTlsPolicy(target); } } } } public HostResponse updateHost(TxtHost host, PcrManifest pcrManifest, HostAgent agent, String uuid) { // JONATHAN BOOKMARK TODO COMMENT OUT THIS BLOCK BECAUSE OF CLEAR TEXT PASSWORDS AFTER DEBUGGING if( log.isDebugEnabled() ) { try { ObjectMapper mapper = new ObjectMapper(); log.debug("updateHost input: {}", mapper.writeValueAsString(host)); //This statement may contain clear text passwords } catch(IOException e) { log.debug("cannot serialize host input to updateHost", e); } } List<TblHostSpecificManifest> tblHostSpecificManifests = null; Vendor hostType; try { TblHosts tblHosts; if (uuid != null && !uuid.isEmpty()) { tblHosts = My.jpa().mwHosts().findHostByUuid(uuid); } else { tblHosts = getHostByName(host.getHostName()); // datatype.Hostname } if (tblHosts == null) { throw new ASException(ErrorCode.AS_HOST_NOT_FOUND, host.getHostName().toString()); } TblMle biosMleId = findBiosMleForHost(host); TblMle vmmMleId = findVmmMleForHost(host); tblHosts.setAddOnConnectionInfo(host.getAddOn_Connection_String()); setTlsPolicyFields(tblHosts, host); if( log.isDebugEnabled() ) { log.debug("updateHost after setTlsPolicyFields TlsPolicyName {}", tblHosts.getTlsPolicyName()); log.debug("updateHost after setTlsPolicyFields TlsKeystoreLength {}", (tblHosts.getTlsKeystore() == null ? "null" : tblHosts.getTlsKeystore().length)); log.debug("updateHost after setTlsPolicyFields tlsPolicyId {}", tblHosts.getTlsPolicyId()); try { ObjectMapper mapper = new ObjectMapper(); log.debug("updateHost after setTlsPolicyFields tlsPolicyDescriptor {}", mapper.writeValueAsString(tblHosts.getTlsPolicyDescriptor())); } catch(IOException e) { log.debug("cannot log tls policy descriptor in updateHost after setTlsPolicyFields", e); } } // Using the connection string we will find out the type of the host. This information would be used later ConnectionString hostConnString = new ConnectionString(host.getAddOn_Connection_String()); tblHosts.setAddOnConnectionInfo(hostConnString.getConnectionStringWithPrefix()); hostType = hostConnString.getVendor(); if (host.getHostName() != null) { tblHosts.setName(host.getHostName().toString()); } if (host.getHostName() != null) { tblHosts.setIPAddress(host.getHostName().toString()); } if (host.getPort() != null) { tblHosts.setPort(host.getPort()); } if (agent == null) { HostAgentFactory factory = new HostAgentFactory(); agent = factory.getHostAgent(tblHosts); } if( agent.isAikAvailable() ) { log.debug("Getting identity."); setAikForHost(tblHosts, host, agent); } // Fix for Bug 4241, where the host specific modules were not getting updated during host re-registration. // Earlier we were updating the host specific modules only when the host was getting mapped to a // different VMM MLE. This conditional check has been removed. log.debug("About to update the host specific manifest"); // retrieve the complete manifest for the host, includes ALL pcr's and if there is module info available it is included also. if (pcrManifest == null) pcrManifest = agent.getPcrManifest(); // currently Vmware has pcr+module, but in 1.2 we are adding module attestation for Intel hosts too ; citrix would be just pcr for now i guess // Bug 962: Earlier we were trying to delete the old host specific values after the host update. By then the VMM MLE would // already be updated and the query would not find any values to delete. deleteHostSpecificManifest(tblHosts); // Bug 963: We need to check if the white list configured for the MLE requires PCR 19. If not, we will skip creating // the host specific modules. if(vmmMleId.getRequiredManifestList().contains(PcrIndex.PCR19.toString())) { log.debug("Host specific modules would be retrieved from the host that extends into PCR 19."); // Added the Vendor parameter to the below function so that we can handle the host specific records differently for different types of hosts. tblHostSpecificManifests = createHostSpecificManifestRecords(vmmMleId, pcrManifest, hostType); } else { log.debug("Host specific modules will not be configured since PCR 19 is not selected for attestation"); } log.debug("Saving Host in database"); tblHosts.setBiosMleId(biosMleId); // @since 1.1 we are relying on the audit log for "created on", "created by", etc. type information // tblHosts.setUpdatedOn(new Date(System.currentTimeMillis())); tblHosts.setDescription(host.getDescription()); tblHosts.setEmail(host.getEmail()); if (host.getHostName() != null) { tblHosts.setIPAddress(host.getHostName().toString()); // datatype.IPAddress } if( host.getPort() != null ) { tblHosts.setPort(host.getPort()); } tblHosts.setVmmMleId(vmmMleId); tblHosts.setBios_mle_uuid_hex(biosMleId.getUuid_hex()); tblHosts.setVmm_mle_uuid_hex(vmmMleId.getUuid_hex()); storePrivateTlsPolicy(tblHosts); // will create a new private policy, or update an existing one, or delete an existing private policy (if host now has a shared policy) My.jpa().mwHosts().edit(tblHosts); log.info("Updated host: {}", tblHosts.getName()); if(tblHostSpecificManifests != null){ log.debug("Updating Host Specific Manifest in database"); // Bug 962: Making this call earlier in the function before updating the host with the new MLEs. //deleteHostSpecificManifest(tblHosts); createHostSpecificManifest(tblHostSpecificManifests, tblHosts); } } catch (ASException ase) { throw ase; } catch (CryptographyException e) { throw new ASException(e, ErrorCode.AS_ENCRYPTION_ERROR, e.getCause() == null ? e.getMessage() : e.getCause().getMessage()); } catch (Exception e) { // throw new ASException(e); // Bug: 1038 - prevent leaks in error messages to client log.error("Error during host update.", e); throw new ASException(ErrorCode.AS_UPDATE_HOST_ERROR, e.getClass().getSimpleName()); } return new HostResponse(ErrorCode.OK); } public HostResponse deleteHost(Hostname hostName, String uuid) { // datatype.Hostname try { TblHosts tblHosts; if (uuid != null && !uuid.isEmpty()) { tblHosts = My.jpa().mwHosts().findHostByUuid(uuid); hostName = new Hostname(tblHosts.getName()); } else { tblHosts = getHostByName(hostName); } if (tblHosts == null) { throw new ASException(ErrorCode.AS_HOST_NOT_FOUND, hostName); } log.debug("Deleting Host from database"); deleteHostAssetTagMapping(tblHosts); deleteHostSpecificManifest(tblHosts); deleteTALogs(tblHosts.getId()); deleteSAMLAssertions(tblHosts); deletePrivateTlsPolicy(tblHosts); My.jpa().mwHosts().destroy(tblHosts.getId()); log.info("Deleted host: {}", hostName.toString()); // Now that the host is deleted, we need to remove any asset tag certificate mapped to this host unmapAssetTagCertFromHost(tblHosts.getId(), tblHosts.getName()); } catch (ASException ase) { //System.err.println("JIM DEBUG"); //ase.printStackTrace(System.err); throw ase; } catch (CryptographyException e) { //System.err.println("JIM DEBUG"); //e.printStackTrace(System.err); throw new ASException(ErrorCode.SYSTEM_ERROR, e.getCause() == null ? e.getMessage() : e.getCause().getMessage(), e); //throw new ASException(ErrorCode.SYSTEM_ERROR, e.getCause() == null ? e.getMessage() : e.getCause().getMessage(), e); } catch (Exception e) { //System.err.println("JIM DEBUG"); //e.printStackTrace(System.err); // throw new ASException(e); // Bug: 1038 - prevent leaks in error messages to client log.error("Error during host deletion.", e); throw new ASException(ErrorCode.AS_DELETE_HOST_ERROR, e.getClass().getSimpleName()); } return new HostResponse(ErrorCode.OK); } private void deleteHostAssetTagMapping(TblHosts tblHosts) throws NonexistentEntityException, IOException { AssetTagCertAssociateRequest atagRequest = new AssetTagCertAssociateRequest(); atagRequest.setHostID(tblHosts.getId()); AssetTagCertBO atagBO = new AssetTagCertBO(); atagBO.unmapAssetTagCertFromHostById(atagRequest); } // PREMIUM FEATURE ? private void deleteHostSpecificManifest(TblHosts tblHosts) throws NonexistentEntityException, IOException { TblHostSpecificManifestJpaController tblHostSpecificManifestJpaController = My.jpa().mwHostSpecificManifest(); for(TblModuleManifest moduleManifest : tblHosts.getVmmMleId().getTblModuleManifestCollection()) { 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(); TblHostSpecificManifest hostSpecificManifest = tblHostSpecificManifestJpaController.findByModuleAndHostID(tblHosts.getId(), moduleManifest.getId()); if (hostSpecificManifest != null) { log.debug("Deleting Host specific manifest." + moduleManifest.getComponentName() + ":" + hostSpecificManifest.getDigestValue()); tblHostSpecificManifestJpaController.destroy(hostSpecificManifest.getId()); } } } } private void deleteTALogs(Integer hostId) throws IllegalOrphanException, IOException { TblTaLogJpaController tblTaLogJpaController = My.jpa().mwTaLog(); // new TblTaLogJpaController(getEntityManagerFactory()); List<TblTaLog> taLogs = tblTaLogJpaController.findLogsByHostId(hostId, new Date()); if (taLogs != null) { for (TblTaLog taLog : taLogs) { try { tblTaLogJpaController.destroy(taLog.getId()); } catch (NonexistentEntityException e) { log.error("Ta Log is already deleted " + taLog.getId()); } } log.info("Deleted all the logs for the given host " + hostId); } } /** * Deletes all the SAML assertions for the specified host. This should * be called before deleting the host. * * @param hostId */ private void deleteSAMLAssertions(TblHosts hostId) throws IOException { TblSamlAssertionJpaController samlJpaController = My.jpa().mwSamlAssertion(); //new TblSamlAssertionJpaController(getEntityManagerFactory()); List<TblSamlAssertion> hostSAMLAssertions = samlJpaController.findByHostID(hostId); if (hostSAMLAssertions != null) { for (TblSamlAssertion hostSAML : hostSAMLAssertions) { try { samlJpaController.destroy(hostSAML.getId()); } catch (NonexistentEntityException e) { log.error("Ta Log is already deleted " + hostSAML.getId()); } } log.info("Deleted all the logs for the given host " + hostId); } } private void setAikForHost(TblHosts tblHosts, TxtHost host, HostAgent agent) { //HostAgentFactory factory = new HostAgentFactory(); // we could call IntelHostAgentFactory but then we have to create the TlsPolicy object ourselves... the HostAgentFactory does that for us. //HostAgent agent = factory.getHostAgent(tblHosts); if( agent.isAikAvailable() ) { if( agent.isAikCaAvailable() ) { X509Certificate cert = agent.getAikCertificate(); try { String certPem = X509Util.encodePemCertificate(cert); tblHosts.setAIKCertificate(certPem); tblHosts.setAikPublicKey(RsaUtil.encodePemPublicKey(cert.getPublicKey())); // NOTE: we are getting the public key from the cert, NOT by calling agent.getAik() ... that's to ensure that someone doesn't give us a valid certificate and then some OTHER public key that is not bound to the TPM tblHosts.setAikSha1(Sha1Digest.valueOf(cert.getEncoded()).toString()); tblHosts.setAikPublicKeySha1(Sha1Digest.valueOf(cert.getPublicKey().getEncoded()).toString()); } catch(Exception e) { log.error("Cannot encode AIK certificate: "+e.toString(), e); } } else { PublicKey publicKey = agent.getAik(); String pem = RsaUtil.encodePemPublicKey(publicKey); tblHosts.setAIKCertificate(null); tblHosts.setAikPublicKey(pem); tblHosts.setAikSha1(null); tblHosts.setAikPublicKeySha1(Sha1Digest.valueOf(publicKey.getEncoded()).toString()); } } } /** * * @param host must not be null */ // private void validate(TxtHost host) { // HashSet<String> missing = new HashSet<String>(); // phase 1, check for required fields /* * if( host.getHostName() == null || host.getHostName().isEmpty() ) { * missing.add("HostName"); } if( host.getBIOS_Name() == null || * host.getBIOS_Name().isEmpty() ) { missing.add("BIOS_Name"); } if( * host.getVMM_Name() == null || host.getVMM_Name().isEmpty() ) { * missing.add("VMM_Name"); } if( !missing.isEmpty() ) { throw new * ASException(ErrorCode.VALIDATION_ERROR, * "Missing "+TextUtil.join(missing)); } */ // phase 2, check for conditionally required fields // String errorMessage = ""; // If in case we are adding a ESX host we need to ensure that we are // getting the connection string // for the vCenter server as well. // log.info( "VMM Name {}", host.getVmm()); /* * if (requiresConnectionString(host.getVmm().getName())) { * if(host.getAddOn_Connection_String() == null || * host.getAddOn_Connection_String().isEmpty()) { missing.add( * "AddOn connection string for connecting to vCenter server for host: " * +host.getHostName()); } } else { if( host.getIPAddress() == null || * host.getIPAddress().isEmpty() ) { missing.add("IPAddress"); } if( * host.getPort() == null ) { missing.add("Port"); } } */ // if (!missing.isEmpty()) { // throw new ASException(ErrorCode.VALIDATION_ERROR, "Missing " // + TextUtil.join(missing)); // } // } /* * private boolean requiresConnectionString(String vmmName) { if( * hostname.contains("ESX") ) { return true; } return false; } */ private void getBiosAndVMM(TxtHost host) throws IOException { TblMleJpaController mleController = My.jpa().mwMle(); //new TblMleJpaController(getEntityManagerFactory()); this.biosMleId = mleController.findBiosMle(host.getBios().getName(), host.getBios().getVersion(), host.getBios().getOem()); if (biosMleId == null) { throw new ASException(ErrorCode.AS_BIOS_INCORRECT, host.getBios().getName(), host.getBios().getVersion()); } this.vmmMleId = mleController.findVmmMle(host.getVmm().getName(), host .getVmm().getVersion(), host.getVmm().getOsName(), host .getVmm().getOsVersion()); if (vmmMleId == null) { throw new ASException(ErrorCode.AS_VMM_INCORRECT, host.getVmm().getName(), host.getVmm().getVersion()); } } private TblMle findBiosMleForHost(TxtHost host) throws IOException { TblMle biosMleId = My.jpa().mwMle().findBiosMle(host.getBios().getName(), host.getBios().getVersion(), host.getBios().getOem()); if (biosMleId == null) { throw new ASException(ErrorCode.AS_BIOS_INCORRECT, host.getBios().getName(),host.getBios().getVersion()); } return biosMleId; } private TblMle findVmmMleForHost(TxtHost host) throws IOException { TblMle vmmMleId = My.jpa().mwMle().findVmmMle(host.getVmm().getName(), host .getVmm().getVersion(), host.getVmm().getOsName(), host .getVmm().getOsVersion()); if (vmmMleId == null) { throw new ASException(ErrorCode.AS_VMM_INCORRECT, host.getVmm().getName(),host.getVmm().getVersion()); } return vmmMleId; } // BUG #607 changing HashMap<String, ? extends IManifest> pcrMap to PcrManifest private synchronized void saveHostInDatabase(TblHosts newRecordWithTlsPolicyAndKeystore, TxtHost host, PcrManifest pcrManifest, List<TblHostSpecificManifest> tblHostSpecificManifests, TblMle biosMleId, TblMle vmmMleId, String uuid) throws CryptographyException, MalformedURLException, IOException { checkForDuplicate(host); TblHosts tblHosts = newRecordWithTlsPolicyAndKeystore; // new TblHosts(); if(log.isDebugEnabled() ) { log.debug("saveHostInDatabase TlsPolicyName {}", tblHosts.getTlsPolicyName()); log.debug("saveHostInDatabase TlsKeystoreLength {}", (tblHosts.getTlsKeystore() == null ? "null" : tblHosts.getTlsKeystore().length)); log.debug("saveHostInDatabase tlsPolicyId {}", tblHosts.getTlsPolicyId()); // JONATHAN BOOKMARK TODO COMMENT OUT THIS BLOCK DUE TO CLEARTEXT PASSWORDS try { ObjectMapper mapper = new ObjectMapper(); log.debug("saveHostInDatabase tlsPolicyDescriptor {}", mapper.writeValueAsString(tblHosts.getTlsPolicyDescriptor())); } catch(IOException e) { log.debug("cannot log tls policy descriptor in saveHostInDatabase", e); } } String cs = host.getAddOn_Connection_String(); //log.info("saveHostInDatabase cs = " + cs); tblHosts.setAddOnConnectionInfo(cs); tblHosts.setBiosMleId(biosMleId); // @since 1.1 we are relying on the audit log for "created on", "created by", etc. type information // tblHosts.setCreatedOn(new Date(System.currentTimeMillis())); // tblHosts.setUpdatedOn(new Date(System.currentTimeMillis())); tblHosts.setDescription(host.getDescription()); tblHosts.setEmail(host.getEmail()); if (host.getHostName() != null) { tblHosts.setIPAddress(host.getHostName().toString()); // datatype.IPAddress }else{ tblHosts.setIPAddress(host.getHostName().toString()); } tblHosts.setName(host.getHostName().toString()); // datatype.Hostname if (host.getPort() != null) { tblHosts.setPort(host.getPort()); } tblHosts.setVmmMleId(vmmMleId); // We need to check if the user has passed in the UUID or we need to generate one if (uuid != null && !uuid.isEmpty()) tblHosts.setUuid_hex(uuid); else tblHosts.setUuid_hex(new UUID().toString()); tblHosts.setBios_mle_uuid_hex(biosMleId.getUuid_hex()); tblHosts.setVmm_mle_uuid_hex(vmmMleId.getUuid_hex()); storePrivateTlsPolicy(tblHosts); // will create a new private policy, or update an existing one, or delete an existing private policy (if host now has a shared policy) // Bug:583: Since we have seen exception related to this in the log file, we will check for contents // before setting the location value. // if (location != null) { // tblHosts.setLocation(location); // } // create the host log.trace("COMMITING NEW HOST DO DATABASE"); //log.error("saveHostInDatabase tblHost aik=" + tblHosts.getAIKCertificate() + ", cs=" + tblHosts.getAddOnConnectionInfo() + ", aikPub=" + tblHosts.getAikPublicKey() + // ", aikSha=" + tblHosts.getAikSha1() + ", desc=" + tblHosts.getDescription() + ", email=" + tblHosts.getEmail() + ", error=" + tblHosts.getErrorDescription() + ", ip=" + // tblHosts.getIPAddress() + ", loc=" + tblHosts.getLocation() + ", name=" + tblHosts.getName() + ", tls=" + tblHosts.getTlsPolicyName() + ", port=" + tblHosts.getPort()); try { My.jpa().mwHosts().create(tblHosts); }catch (Exception e){ log.debug("SaveHostInDatabase caught ex!"); e.printStackTrace(); log.trace("end print stack trace"); // throw new ASException(e); // Bug: 1038 - prevent leaks in error messages to client log.error("Error during saving the host to DB.", e); throw new ASException(ErrorCode.AS_REGISTER_HOST_ERROR, e.getClass().getSimpleName()); } log.debug("Save host specific manifest if any."); createHostSpecificManifest(tblHostSpecificManifests, tblHosts); } /* * It looks for a very specific event that * is extended into pcr 19 in vmware hosts. So the vmware host-specific policy factory creates a TrustPolicy * that has that event, and here we just convert it to a TblHostSpecificManifest record. * BUG #607 ... given a complete list of pcrs and module values from the host, and list of pcr's that should be used ... figures out * what host-specific module values should be recorded in the database... apparently hard-coded to pcr 19 * and vmware information... so this is a candidate for moving into VmwareHostTrustPolicyFactory, * and instaed of returning a "host-specific manifest" it should return a list of policies with module-included * or module-equals type rules. */ private List<TblHostSpecificManifest> createHostSpecificManifestRecords(TblMle vmmMleId, PcrManifest pcrManifest, Vendor hostType) throws IOException { List<TblHostSpecificManifest> tblHostSpecificManifests = new ArrayList<>(); // Using the connection string, let us first find out the host type // Bug 963: Ensure that we even check if PCR 19 is required as per the MLE setup if (vmmMleId.getRequiredManifestList().contains(PcrIndex.PCR19.toString()) && pcrManifest != null && pcrManifest.containsPcrEventLog(PcrIndex.PCR19)) { PcrEventLog pcrEventLog = pcrManifest.getPcrEventLog(19); if (pcrEventLog != null) { for (Measurement m : pcrEventLog.getEventLog()) { if (m != null && m.getInfo() != null && (!m.getInfo().isEmpty())) { String mEventName = m.getInfo().get("EventName"); String mComponentName = m.getInfo().get("ComponentName"); log.debug("Checking host specific manifest for event '" + mEventName + "' field '" + m.getLabel() + "' component '" + mComponentName + "'"); // we are looking for the "commandline" event specifically (vmware) if (hostType.equals(Vendor.VMWARE) && mEventName != null && mComponentName != null && mEventName.equals("Vim25Api.HostTpmCommandEventDetails")) { log.debug("Adding host specific manifest for event '" + mEventName + "' field '" + m.getLabel() + "' component '" + mComponentName + "'"); log.debug("Querying manifest for event '" +mEventName + "' MLE_ID '" + vmmMleId.getId() + "' component '" + mComponentName + "'"); TblModuleManifest tblModuleManifest = My.jpa().mwModuleManifest().findByMleNameEventName(vmmMleId.getId(), m.getInfo().get("ComponentName"), m.getInfo().get("EventName")); TblHostSpecificManifest tblHostSpecificManifest = new TblHostSpecificManifest(); tblHostSpecificManifest.setDigestValue(m.getValue().toString()); // tblHostSpecificManifest.setHostID(tblHosts.getId()); tblHostSpecificManifest.setModuleManifestID(tblModuleManifest); tblHostSpecificManifests.add(tblHostSpecificManifest); } else if (hostType.equals(Vendor.INTEL) && m.getInfo().get("EventName") != null) { log.debug("Adding host specific manifest for event '" + m.getInfo().get("EventName") + "' field '" + m.getLabel() + "' component '" + m.getInfo().get("ComponentName") + "'"); log.debug("Querying manifest for event '" + m.getInfo().get("EventName") + "' MLE_ID '" + vmmMleId.getId() + "' component '" + m.getInfo().get("ComponentName") + "'"); // For open source XEN and KVM both the modules that get extended to PCR 19 should be added into the host specific table TblModuleManifest tblModuleManifest = My.jpa().mwModuleManifest().findByMleNameEventName(vmmMleId.getId(), m.getInfo().get("ComponentName"), m.getInfo().get("EventName")); TblHostSpecificManifest tblHostSpecificManifest = new TblHostSpecificManifest(); tblHostSpecificManifest.setDigestValue(m.getValue().toString()); tblHostSpecificManifest.setModuleManifestID(tblModuleManifest); tblHostSpecificManifests.add(tblHostSpecificManifest); } } } } return tblHostSpecificManifests; } else { log.warn("No PCR 19 found.SO not saving host specific manifest."); return tblHostSpecificManifests; } } public HostResponse isHostRegistered(String hostnameOrAddress) { try { TblHostsJpaController tblHostsJpaController = My.jpa().mwHosts(); //new TblHostsJpaController(getEntityManagerFactory()); TblHosts tblHosts = tblHostsJpaController.findByName(hostnameOrAddress); if (tblHosts != null) { return new HostResponse(ErrorCode.OK); // host name exists in // database } tblHosts = tblHostsJpaController.findByIPAddress(hostnameOrAddress); if (tblHosts != null) { return new HostResponse(ErrorCode.OK); // host IP address exists in // database } return new HostResponse(ErrorCode.AS_HOST_NOT_FOUND); } catch (ASException e) { throw e; } catch (Exception e) { // throw new ASException(e); // Bug: 1038 - prevent leaks in error messages to client log.error("Error during verification of registered host.", e); throw new ASException(ErrorCode.AS_VERIFY_HOST_ERROR, e.getClass().getSimpleName()); } } private void checkForDuplicate(TxtHost host) throws CryptographyException, IOException { TblHostsJpaController tblHostsJpaController = My.jpa().mwHosts(); //new TblHostsJpaController(getEntityManagerFactory()); TblHosts tblHosts = tblHostsJpaController.findByName(host.getHostName() .toString()); // datatype.Hostname if (tblHosts != null) { throw new ASException( ErrorCode.AS_HOST_EXISTS, host.getHostName()); } // BUG #497 every host requires a connection string now, and will not have the "ip address" field anymore. /* if (!host.requiresConnectionString() && host.getIPAddress() != null ) { tblHosts = tblHostsJpaController.findByIPAddress(host .getIPAddress().toString()); // datatype.IPAddress if (tblHosts != null) { throw new ASException( ErrorCode.AS_IPADDRESS_EXISTS, host.getIPAddress()); } } */ } /** * This is not a REST API method, it is public because it is used by * HostTrustBO. * * @param hostName * @return * @throws CryptographyException */ public TblHosts getHostByName(Hostname hostName) throws CryptographyException, IOException { // datatype.Hostname TblHosts tblHosts = My.jpa().mwHosts().findByName(hostName.toString()); return tblHosts; } public TblHosts getHostByAik(Sha1Digest aik) throws CryptographyException, IOException { // datatype.Hostname TblHosts tblHosts = My.jpa().mwHosts().findByAikSha1(aik.toString()); return tblHosts; } /** * Author: Sudhir * * Searches for the hosts using the criteria specified. * * @param searchCriteria: If in case the user has not provided any * search criteria, then all the hosts would be returned back to the * caller * @param includeHardwareUuid: if this is set to true, it causes the resulting * TxtHostRecord to include the hardware_uuid field from the tblHost * @return */ public List<TxtHostRecord> queryForHosts(String searchCriteria,boolean includeHardwareUuid) { log.debug("queryForHost " + searchCriteria + " includeHardwareUuid[" + includeHardwareUuid +"]"); try { TblHostsJpaController tblHostsJpaController = My.jpa().mwHosts(); //new TblHostsJpaController(getEntityManagerFactory()); List<TxtHostRecord> txtHostList = new ArrayList<TxtHostRecord>(); List<TblHosts> tblHostList; if (searchCriteria != null && !searchCriteria.isEmpty()) { tblHostList = tblHostsJpaController.findHostsByNameSearchCriteria(searchCriteria); } else { tblHostList = tblHostsJpaController.findTblHostsEntities(); } if (tblHostList != null) { log.debug(String.format("Found [%d] host results for search criteria [%s]", tblHostList.size(), searchCriteria)); for (TblHosts tblHosts : tblHostList) { TxtHostRecord hostObj = createTxtHostFromDatabaseRecord(tblHosts,includeHardwareUuid); txtHostList.add(hostObj); } } else { log.debug(String.format("Found no hosts for search criteria [%s]", searchCriteria)); } return txtHostList; } catch (ASException e) { throw e; } catch (Exception e) { // throw new ASException(e); // Bug: 1038 - prevent leaks in error messages to client log.error("Error during querying for registered hosts.", e); throw new ASException(ErrorCode.AS_QUERY_HOST_ERROR, e.getClass().getSimpleName()); } } /** * Author: Sudhir * * Searches for the hosts using the criteria specified. * * @param searchCriteria: If in case the user has not provided any * search criteria, then all the hosts would be returned back to the * caller * @return */ public List<TxtHostRecord> queryForHosts(String searchCriteria) { log.debug("queryForHost " + searchCriteria); try { TblHostsJpaController tblHostsJpaController = My.jpa().mwHosts(); //new TblHostsJpaController(getEntityManagerFactory()); List<TxtHostRecord> txtHostList = new ArrayList<TxtHostRecord>(); List<TblHosts> tblHostList; if (searchCriteria != null && !searchCriteria.isEmpty()) { tblHostList = tblHostsJpaController.findHostsByNameSearchCriteria(searchCriteria); } else { tblHostList = tblHostsJpaController.findTblHostsEntities(); } if (tblHostList != null) { log.debug(String.format("Found [%d] host results for search criteria [%s]", tblHostList.size(), searchCriteria)); for (TblHosts tblHosts : tblHostList) { TxtHostRecord hostObj = createTxtHostFromDatabaseRecord(tblHosts, false); txtHostList.add(hostObj); } } else { log.debug(String.format("Found no hosts for search criteria [%s]", searchCriteria)); } return txtHostList; } catch (ASException e) { throw e; } catch (Exception e) { // throw new ASException(e); // Bug: 1038 - prevent leaks in error messages to client log.error("Error during querying for registered hosts.", e); throw new ASException(ErrorCode.AS_QUERY_HOST_ERROR, e.getClass().getSimpleName()); } } public TxtHostRecord createTxtHostFromDatabaseRecord(TblHosts tblHost,boolean includeHardwareUuid) { TxtHostRecord hostObj = new TxtHostRecord(); hostObj.HostName = tblHost.getName(); hostObj.IPAddress = tblHost.getName(); hostObj.Port = tblHost.getPort(); hostObj.AddOn_Connection_String = tblHost.getAddOnConnectionInfo(); hostObj.Description = tblHost.getDescription(); hostObj.Email = tblHost.getEmail(); hostObj.Location = tblHost.getLocation(); hostObj.BIOS_Name = tblHost.getBiosMleId().getName(); hostObj.BIOS_Oem = tblHost.getBiosMleId().getOemId().getName(); hostObj.BIOS_Version = tblHost.getBiosMleId().getVersion(); hostObj.VMM_Name = tblHost.getVmmMleId().getName(); hostObj.VMM_Version = tblHost.getVmmMleId().getVersion(); hostObj.VMM_OSName = tblHost.getVmmMleId().getOsId().getName(); hostObj.VMM_OSVersion = tblHost.getVmmMleId().getOsId().getVersion(); if(includeHardwareUuid){ log.debug("adding in hardware uuid field["+tblHost.getHardwareUuid()+"]"); hostObj.Hardware_Uuid = tblHost.getHardwareUuid(); }else{ log.debug("not adding in hardware uuid"); hostObj.Hardware_Uuid = null; } // if the host already has a mtwilson 1.x tls keystore, automatically convert it to the new tls policy descriptor if( tblHost.getTlsPolicyName() != null || tblHost.getTlsKeystore() != null ) { TblHostsTlsPolicyFactory.TblHostsObjectTlsPolicy tlsPolicyFactory = new TblHostsTlsPolicyFactory.TblHostsObjectTlsPolicy(tblHost); hostObj.tlsPolicyChoice = tlsPolicyFactory.getTlsPolicyChoice(); } else if( tblHost.getTlsPolicyId() != null ) { // there is a policy id, but for the UI edit host page we need to provide the id for a shared policy, or the descriptor for a private policy try(TlsPolicyDAO tlsPolicyDao = TlsPolicyJdbiFactory.tlsPolicyDAO()) { TlsPolicyRecord tlsPolicyRecord = tlsPolicyDao.findPrivateTlsPolicyByHostId(tblHost.getUuid_hex()); if( tlsPolicyRecord != null && tblHost.getTlsPolicyId().equalsIgnoreCase(tlsPolicyRecord.getId().toString()) ) { // found the private policy for this host, so set the descriptor on the host record JsonTlsPolicyReader reader = new JsonTlsPolicyReader(); hostObj.tlsPolicyChoice = new TlsPolicyChoice(); hostObj.tlsPolicyChoice.setTlsPolicyDescriptor(reader.read(tlsPolicyRecord.getContent())); } else { // either didn't find a private policy OR we found one but the host actually links to a shared policy - so keep the tls policy id hostObj.tlsPolicyChoice = new TlsPolicyChoice(); hostObj.tlsPolicyChoice.setTlsPolicyId(tblHost.getTlsPolicyId()); } } catch(IOException e) { log.debug("Cannot lookup tlsPolicyId {}", tblHost.getTlsPolicyId(), e); } } else if( tblHost.getTlsPolicyDescriptor() != null ) { hostObj.tlsPolicyChoice = new TlsPolicyChoice(); hostObj.tlsPolicyChoice.setTlsPolicyDescriptor(tblHost.getTlsPolicyDescriptor()); } return hostObj; } public HostResponse addHostByFindingMLE(HostConfigData hostObj) { try { return ASComponentFactory.getHostTrustBO().getTrustStatusOfHostNotInDBAndRegister(hostObj); } catch (ASException ae){ throw ae; } } public HostResponse updateHostByFindingMLE(HostConfigData hostObj) { try { return ASComponentFactory.getHostTrustBO().getTrustStatusOfHostNotInDBAndRegister(hostObj); } catch (ASException ae) { throw ae; } } /** * * @param host */ private void associateAssetTagCertForHost(TxtHost host, Map<String, String> hostAttributes) { String hostUUID; try { log.debug("Starting the procedure to map the asset tag certificate for host {}.", host.getHostName().toString()); // First let us find if the asset tag is configured for this host or not. This information // would be available in the mw_asset_tag_certificate table, where the host's UUID would be // present. if (hostAttributes != null && hostAttributes.containsKey("Host_UUID")) { hostUUID = hostAttributes.get("Host_UUID"); } else { log.info("Since UUID for the host {} is not specified, asset tag would not be configured.", host.getHostName().toString()); return; } // Now that we have a valid host UUID, let us search for an entry in the db. AssetTagCertBO atagCertBO = new AssetTagCertBO(); MwAssetTagCertificate atagCert = atagCertBO.findValidAssetTagCertForHost(hostUUID); if (atagCert != null) { log.debug("Found a valid asset tag certificate for the host {} with UUID {}.", host.getHostName().toString(), hostUUID); // Now that there is a asset tag certificate for the host, let us retrieve the host ID and update // the asset tag certificate with that ID TblHosts tblHost = My.jpa().mwHosts().findByName(host.getHostName().toString()); if (tblHost != null) { AssetTagCertAssociateRequest atagMapRequest = new AssetTagCertAssociateRequest(); atagMapRequest.setSha1OfAssetCert(atagCert.getSHA1Hash()); atagMapRequest.setHostID(tblHost.getId()); boolean mapAssetTagCertToHost = atagCertBO.mapAssetTagCertToHostById(atagMapRequest); if (mapAssetTagCertToHost) log.info("Successfully mapped the asset tag certificate with UUID {} to host {}", atagCert.getUuid(), tblHost.getName()); else log.info("No valid asset tag certificate configured for the host {}.", tblHost.getName()); } } else { log.info("No valid asset tag certificate configured for the host {}.", host.getHostName().toString()); } } catch (Exception ex) { // Log the error and return back. log.info("Error during asset tag configuration for the host {}. Details: {}.", host.getHostName().toString(), ex.getMessage()); } } /** * * @param id * @param name */ private void unmapAssetTagCertFromHost(Integer id, String name) { try { log.debug("Starting the procedure to unmap the asset tag certificate from host {}.", name); AssetTagCertBO atagCertBO = new AssetTagCertBO(); AssetTagCertAssociateRequest atagUnmapRequest = new AssetTagCertAssociateRequest(); atagUnmapRequest.setHostID(id); boolean unmapAssetTagCertFromHost = atagCertBO.unmapAssetTagCertFromHostById(atagUnmapRequest); if (unmapAssetTagCertFromHost) log.info("Either the asset tag certificate was successfully unmapped from the host {} or there was not asset tag certificate associated.", name); else log.info("Either there were errors or no asset tag certificate was configured for the host {}.", name); } catch (Exception ex) { // Log the error and return back. log.info("Error during asset tag unmapping for the host {}. Details: {}.", name, ex.getMessage()); } } }