Continued changes to update to Hibernate 5, removed a lot of the

baseline files
This commit is contained in:
Cyrus 2022-05-10 07:04:16 -04:00
parent dabd88719f
commit 116ed5b4aa
36 changed files with 144 additions and 2850 deletions

View File

@ -7,11 +7,6 @@ import hirs.persist.AppraiserManager;
import hirs.persist.DeviceGroupManager;
import hirs.persist.PolicyManager;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import static hirs.attestationca.AbstractAttestationCertificateAuthority.LOG;
/**
@ -71,19 +66,4 @@ public final class AcaDbInit {
LOG.info("ACA database initialization complete.");
}
public static void main(String[] args) throws IOException {
File file = new File("/home/tdmatth/Downloads/HP_CND12774J0_pxe.1.swidtag");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] buffer = new byte[1024];
int length = 0;
String output = "";
while ((length = bis.read(buffer)) != -1) {
output += new String(buffer, 0, length);
}
System.out.println(output);
}
}

View File

@ -1,7 +1,7 @@
package hirs;
import static org.apache.logging.log4j.LogManager.getLogger;
import hirs.data.persist.IMAReport;
import hirs.data.persist.Report;
import javax.xml.bind.annotation.XmlElement;

View File

@ -1,9 +1,9 @@
package hirs.data.persist;
import hirs.data.persist.baseline.Baseline;
import hirs.data.persist.enums.AlertSeverity;
import hirs.data.persist.enums.AlertSource;
import hirs.data.persist.enums.AlertType;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.CollectionTable;
@ -241,7 +241,7 @@ public class Alert extends ArchivableEntity {
* Returns the source of this <code>Alert</code>.
*
* @return source of this <code>Alert</code>
* @see Source
*
*/
@XmlAttribute(name = "source")
public final AlertSource getSource() {
@ -316,39 +316,6 @@ public class Alert extends ArchivableEntity {
this.received = truncate(received, DEFAULT_MAX_STRING_LENGTH);
}
/**
* Sets the id of baselines associated with the alert as well as the severity of the
* <code>Baseline</code> that was in use, if any, when the <code>Alert</code> was generated.
* Should only be used when initially generating an <code>Alert</code>.
*
* @param baselines - a collection of <code>Baseline</code>s related to this alert
*/
public final void setBaselineIdsAndSeverity(final Set<Baseline> baselines) {
if (baselines != null) {
for (Baseline baseline : baselines) {
if (baseline != null) {
this.baselineIds.add(baseline.getId());
/**
* This is a temporary solution to resolve any failures in
* live code or unit tests. BaselineId is used to count the number
* of alerts associated with a baseline. The <code>AlertManager</code>
* class uses baselineId for this count.
*
*/
this.baselineId = baseline.getId();
// only overwrite severity if the new one is non-null
if (baseline.getSeverity() != null) {
// Assign the most critical severity level of the collection of baselines to
// the alert
this.severity = getPrioritizedSeverityLevel(baseline.getSeverity());
}
}
}
}
}
/**
* Set the severity of the alert regardless of baseline.
* @param severity Alert.Severity.
@ -378,7 +345,7 @@ public class Alert extends ArchivableEntity {
* Returns the <code>Severity</code> of this <code>Alert</code>.
*
* @return severity of this <code>Alert</code>
* @see Severity
*
*/
@XmlAttribute(name = "severity")
public final AlertSeverity getSeverity() {

View File

@ -1,12 +1,12 @@
package hirs.data.persist;
import hirs.data.persist.info.FirmwareInfo;
import hirs.data.persist.info.HardwareInfo;
import hirs.data.persist.info.NetworkInfo;
import hirs.data.persist.info.OSInfo;
import hirs.data.persist.info.HardwareInfo;
import hirs.data.persist.info.TPMInfo;
import hirs.data.persist.info.FirmwareInfo;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import static org.apache.logging.log4j.LogManager.getLogger;
import hirs.utils.VersionHelper;
import org.apache.logging.log4j.Logger;
import javax.persistence.Column;
import javax.persistence.Embedded;
@ -17,12 +17,10 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import hirs.utils.VersionHelper;
import org.apache.logging.log4j.Logger;
import java.io.Serializable;
import static org.apache.logging.log4j.LogManager.getLogger;
/**
* A <code>DeficeInfoReport</code> is a <code>Report</code> used to transfer the
* information about the device. This <code>Report</code> includes the network,
@ -249,7 +247,7 @@ public class DeviceInfoReport extends Report implements Serializable {
* @return True, if one of the TPM baselines in the set has the same kernel-specific
* info as this DeviceinfoReport.
*/
public final boolean matchesKernelInfo(final Iterable<TpmWhiteListBaseline> tpmBaselines) {
public final boolean matchesKernelInfo(final Iterable<Digest> tpmBaselines) {
boolean match = false;
if (tpmBaselines != null) {
@ -257,8 +255,8 @@ public class DeviceInfoReport extends Report implements Serializable {
final OSInfo kernelOSInfo = getOSInfo();
// perform the search
for (final TpmWhiteListBaseline baseline : tpmBaselines) {
final OSInfo baselineOSInfo = baseline.getOSInfo();
for (final Digest baseline : tpmBaselines) {
final OSInfo baselineOSInfo = new OSInfo();//baseline.getOSInfo();
if(baselineOSInfo.getOSName().equalsIgnoreCase(kernelOSInfo.getOSName())
&& baselineOSInfo.getOSVersion().equalsIgnoreCase(kernelOSInfo.getOSVersion())) {
match = true;

View File

@ -1,280 +0,0 @@
package hirs.data.persist;
import hirs.data.persist.enums.AlertSource;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import java.util.Arrays;
import java.util.Date;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
/**
* An <code>IMADeviceState</code> manages the IMA state for appraisal. This
* information is useful so that the IMA appraiser does not have to request or
* appraise the full report for each appraisal. The appraiser can fetch the
* information from the last appraisal and begin appraising from the saved
* state.
* <p>
* For instance consider a client that first appraises at t0. At t0 the client
* send the full report and IMA appraiser appraises the X entries in the report.
* Then at time t1 the client has another appraisal. If the machine has not been
* rebooted then the appraiser can validate the integrity of the full report
* using the saved PCR value from t0. The server can also validate only the IMA
* entries after t0.
*
*/
@Entity
@Access(AccessType.FIELD)
public class IMADeviceState extends DeviceState {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "device", nullable = false, unique = true)
private final Device device;
@Column(name = "bootcycleId")
private String bootcycleId;
@Column(name = "appraiseIndex")
private int index;
@Column(nullable = true, name = "pcrState",
length = Digest.SHA512_DIGEST_LENGTH)
private byte[] pcrState;
@Column(name = "mostRecentFullReportDate")
private Date mostRecentFullReportDate;
/**
* Creates a new <code>IMADeviceState</code> to manage the state for the
* <code>Device</code>. The boot-cycle ID will be null to indicate that this
* has not saved state for previous report. The index will be 0 to indicate
* that no entries have been appraised, and the PCR state will be null as
* well.
*
* @param device
* device
*/
public IMADeviceState(final Device device) {
if (device == null) {
throw new NullPointerException("device");
}
this.device = device;
resetState();
}
/**
* Default constructor that has no state saved.
*/
protected IMADeviceState() {
this.device = null;
resetState();
}
/**
* Returns the database ID associated with this entity. After this object is
* stored in a database then this ID will be set. This is necessary only for
* Hibernate.
*
* @return the id
*/
public final Long getId() {
return id;
}
/**
* Resets the state. This sets boot-cycle ID to null, index to 0, and PCR
* state to null.
*/
public final void resetState() {
this.bootcycleId = null;
this.index = 0;
this.pcrState = null;
}
/**
* Returns the <code>Device</code> associated with this state.
*
* @return the device
*/
public final Device getDevice() {
return device;
}
/**
* Returns the boot-cycle ID associated with the last appraisal. This may be
* null to indicate a reset in state. If the <code>IMAAppraiser</code> sees
* this value as null then it will know to request a full report and
* appraise the full report.
*
* @return the bootcycleId (may be null if no appraisals yet or state is
* reset)
*/
public final String getBootcycleId() {
return bootcycleId;
}
/**
* Sets the boot-cycle ID associated with the last appraisal.
*
* @param bootcycleId
* bootcycleId
*/
public final void setBootcycleId(final String bootcycleId) {
this.bootcycleId = bootcycleId;
}
/**
* Returns the index of the next IMA record to be appraised. The first
* record has index 0. If zero is returned then this indicates the first
* entry in the report is to be appraised.
*
* @return index of last successfully appraised IMA record
*/
public final int getIndex() {
return index;
}
/**
* Sets the index of the next IMA record to be appraised.
*
* @param index
* index of last IMA record that was successfully appraised
* @throws IllegalArgumentException
* if index &lt; 0
*/
public final void setIndex(final int index)
throws IllegalArgumentException {
if (index < 0) {
throw new IllegalArgumentException("index < 0");
}
this.index = index;
}
/**
* Sets the date of the most recent full report. This is useful for determining the start time
* of the most recent delta report series, as the first delta report is indistinguishable from
* a full report.
*
* @return date of most recent full report or null if there have not been any reports yet
*/
public final Date getMostRecentFullReportDate() {
if (mostRecentFullReportDate == null) {
return null;
} else {
return (Date) mostRecentFullReportDate.clone();
}
}
/**
* Sets the date of the most recent full report. This is useful for determining the start time
* of the most recent delta report series, as the first delta report is indistinguishable from
* a full report.
*
* @param date date of the most recent full report or null to unset the date
*/
public final void setMostRecentFullReportDate(final Date date) {
if (date == null) {
this.mostRecentFullReportDate = null;
} else {
this.mostRecentFullReportDate = (Date) date.clone();
}
}
@Override
public Criterion getDeviceTrustAlertCriterion() {
Criterion createTimeRestriction = Restrictions.ge("createTime", mostRecentFullReportDate);
Criterion sourceRestriction = Restrictions.eq("source", AlertSource.IMA_APPRAISER);
return Restrictions.and(createTimeRestriction, sourceRestriction);
}
/**
* Returns the PCR hash that verified the last IMA report. An IMA report can
* be verified by recalculating the PCR hash in the TPM. This value
* indicates the last verified PCR value for a valid report in the
* boot-cycle ID.
* <p>
* This may return null if the state has been reset, no entries have been
* appraised, or the <code>Device</code> does not have a TPM.
*
* @return PCR state
*/
public final byte[] getPcrState() {
if (pcrState == null) {
return null;
} else {
return Arrays.copyOf(pcrState, pcrState.length);
}
}
/**
* Sets the PCR state. See {@link #getPcrState()} for more details.
*
* @param pcrState PCR state
*/
public final void setPcrState(final byte[] pcrState) {
if (pcrState == null) {
this.pcrState = null;
} else {
this.pcrState = Arrays.copyOf(pcrState, pcrState.length);
}
}
/**
* Returns the hash code representing this object. The hash code is derived
* from the <code>Device</code> this state represents.
*
* @return hash code
*/
@Override
public final int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + device.hashCode();
return result;
}
/**
* Compares this object for equality with <code>obj</code>.
* <code>IMADeviceState</code> objects are considered equal if they have
* equal <code>Device</code>s.
*
* @param obj
* other object
* @return true if both are instances of <code>IMADeviceState</code> and
* both have the same <code>Device</code>
*/
@Override
public final boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof IMADeviceState)) {
return false;
}
final IMADeviceState other = (IMADeviceState) obj;
return device.equals(other.device);
}
@Override
public final String toString() {
return String.format("(%s %s %d)", device, bootcycleId, index);
}
}

View File

@ -1,194 +0,0 @@
package hirs.data.persist;
import hirs.data.persist.enums.DigestAlgorithm;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
/**
* This class represents an IMA measurement record. A measurement record
* contains a file path and a hash. The file path represents the file name and
* the hash is the hash of the file.
* <p>
* In IMA the file path is not guaranteed to be unique. For instance initrd has
* files measured at /. The root file space that is mounted later is also
* mounted at /.
*/
@XmlSeeAlso(Digest.class)
@Entity
@XmlAccessorType(XmlAccessType.FIELD)
public class IMAMeasurementRecord extends ExaminableRecord {
private static final Logger LOGGER = LogManager.getLogger(IMAMeasurementRecord.class);
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@XmlElement
@Column(nullable = false)
private final String path;
@XmlElement
@Embedded
private final Digest hash;
@XmlTransient
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "ima_report_id")
@JsonIgnore
private IMAReport report;
/**
* Creates a new <code>IMAMeasurementRecord</code>. The record contains the
* file path and its hash.
*
* @param path
* the file path that identifies the file location
* @param hash
* SHA-1 hash of the file
* @throws IllegalArgumentException
* if digest algorithm is not SHA-1
*/
public IMAMeasurementRecord(final String path, final Digest hash)
throws IllegalArgumentException {
super();
checkNullArg(path, "path");
checkNullArg(hash, "hash");
if (hash.getAlgorithm() != DigestAlgorithm.SHA1) {
throw new IllegalArgumentException("digest algorithm is not SHA-1");
}
this.path = path;
this.hash = hash;
}
/**
* Default constructor necessary for Hibernate.
*/
protected IMAMeasurementRecord() {
super();
this.path = null;
this.hash = null;
}
/**
* Returns the ID of the IMAMeasurementRecord.
*
* @return id of IMAMeasurementRecord
*/
public final Long getId() {
return id;
}
/**
* Returns the path (including file name) of the IMA baseline record.
*
* @return file path of baseline record
*/
public final String getPath() {
return this.path;
}
/**
* Returns the SHA1 hash of the file associated with IMA baseline record.
*
* @return hash of file associated with baseline record
*/
public final Digest getHash() {
return this.hash;
}
/**
* This gets the report.
*
* @return Report
*/
public final IMAReport getReport() {
return report;
}
/**
* Sets the given report.
*
* @param report report that matches the given record
*/
public final void setReport(final IMAReport report) {
this.report = report;
}
/**
* Overrides hashCode() method in order to generate a new hashCode based on
* hashCode of path and hash. This is required because of override of
* equals() method.
*
* @return generated hash code
*/
@Override
public final int hashCode() {
if (id == null) {
return super.hashCode();
}
return id.hashCode();
}
/**
* Returns a boolean if other is equal to this.
* <code>IMAMeasurementRecord</code>s are identified by their name and hash,
* so this returns true if <code>other</code> is an instance of
* <code>IMAMeasurementRecord</code> and its name and hash are the same as
* this <code>IMAMeasurementRecord</code>. Otherwise this returns false.
*
* @param obj
* other object to test for equals
* @return true if other is <code>IMAMeasurementRecord</code> and has same
* name and same hash
*/
@Override
public final boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof IMAMeasurementRecord)) {
return false;
}
IMAMeasurementRecord other = (IMAMeasurementRecord) obj;
if (other.id == null || id == null) {
return super.equals(other);
}
return other.id.equals(id);
}
@Override
public final String toString() {
return String.format("(%s, %s)", path, hash);
}
private void checkNullArg(final Object arg, final String argName) {
if (arg == null) {
final String msg = String.format("null argument: %s", argName);
LOGGER.error(msg);
throw new NullPointerException(msg);
}
}
}

View File

@ -1,195 +0,0 @@
package hirs.data.persist;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import org.apache.logging.log4j.Logger;
import static org.apache.logging.log4j.LogManager.getLogger;
/**
* IMAReport is a listing of <code>IMAMeasurementRecord</code>s. The list of
* <code>IMAMeasurementRecord</code>s is an ordered list. The list is ordered
* based upon the order in which the files were measured. The ordering is
* important because the TPM hash value can only be verified if the order is
* correct.
*/
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
@XmlSeeAlso(IMAMeasurementRecord.class)
@Entity
public class IMAReport extends Report {
private static final Logger LOGGER = getLogger(IMAReport.class);
private static final int MAX_BOOTCYCLE_LENGTH = 128;
@Column(nullable = true, length = MAX_BOOTCYCLE_LENGTH)
@XmlElement(name = "bootcycleID", required = false)
private String bootcycleId;
@XmlElement(name = "startIndex", required = true)
@Column(nullable = false, name = "startingIndex")
private int index;
@XmlElement
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER,
mappedBy = "report")
@Access(AccessType.FIELD)
@JsonIgnore
private final Set<IMAMeasurementRecord> imaRecords;
/**
* Constructor used to initialize an IMA report. This creates an empty set
* of IMA records and sets the default index to zero.
*/
public IMAReport() {
imaRecords = new LinkedHashSet<>();
index = 0;
}
@Override
public final String getReportType() {
return this.getClass().getName();
}
/**
* Returns the boot cycle ID. A boot cycle ID is a unique identifier that
* indicates a machine reboot. If the machine is rebooted then it will have
* a different boot cycle ID.
* <p>
* The boot cycle ID is useful for IMA delta measurements. With this ID the
* appraiser can know if a machine has rebooted. If it has not rebooted then
* efficiencies can be applied, such as not re-appraising a part of a report
* that has previously been appraised.
* <p>
* This is an optional component of an IMA report. The return value may be
* null.
*
* @return boot cycle ID
*/
public final String getBootcycleId() {
return this.bootcycleId;
}
/**
* Sets the boot cycle ID for this report. See {@link #getBootcycleId()} for
* more details.
*
* @param bootcycleId boot cycle ID (may be null to omit from report)
*/
public final void setBootcycleId(final String bootcycleId) {
this.bootcycleId = bootcycleId;
}
/**
* Returns the index of the first record. An IMA report contains an array of
* measurement records. This value indicates the index of the first record
* in this report.
* <p>
* This can be non-zero if this report represents a delta report. A report
* can be sent at time t0. This report contains y records. At time t1, if
* the machine has not rebooted, then the full IMA report will have x+y
* records where y&ge;0. A delta report can be sent with just the records in
* the set {y-x}. In that case the index would be x.
* <p>
* The first entry in the IMA report has index 0.
*
* @return index of the first measurement record in this report
*/
public final int getIndex() {
return index;
}
/**
* Sets the index of the first measurement record.
*
* @param index
* index of first measurement record
* @throws IllegalArgumentException
* if index&lt;0
*/
public final void setIndex(final int index) {
if (index < 0) {
final String msg = "index cannot be less than zero";
LOGGER.warn(msg);
throw new IllegalArgumentException(msg);
}
this.index = index;
}
/**
* Gets the list of IMA records. The <code>IMAMeasurementRecords</code> are
* lazily loaded and this method will have to be called within a transaction
* in order to properly load and return all of the records related to the
* report.
*
* @return list of IMA measurement records
*/
@JsonIgnore
public Set<IMAMeasurementRecord> getRecords() {
return Collections.unmodifiableSet(imaRecords);
}
/**
* Adds a record to the list of IMA measurement records by appending it to
* the ordered list.
*
* @param record
* IMA record to be added
*/
public final void addRecord(final IMAMeasurementRecord record) {
if (record == null) {
LOGGER.error("null record");
throw new NullPointerException("record");
}
imaRecords.add(record);
LOGGER.debug("record added: {}", record);
}
/**
* Removes a record from the list.
*
* @param record
* record to be removed
* @return a boolean indicating if the removal was successful
*/
public final boolean removeRecord(final IMAMeasurementRecord record) {
return imaRecords.remove(record);
}
/**
* Returns a boolean indicating if this report is a full report. The first measurement in the
* IMA log has an index of 0. If delta reports are enabled, the first delta report should be a
* full report (index starts at 0), and subsequent delta reports will have index values greater
* than 0.
*
* @return true if a full report or first delta report, false if not the first delta report
*/
public final boolean isFullReport() {
return index == 0;
}
/**
* Method returns the number of records in the IMA report.
* @return the number of records found in the IMA Report
*/
public int getRecordCount() {
return imaRecords.size();
}
}

View File

@ -1,184 +0,0 @@
package hirs.data.persist;
import hirs.data.persist.baseline.ImaBlacklistBaseline;
import hirs.data.persist.baseline.AbstractImaBaselineRecord;
import hirs.data.persist.enums.AlertType;
import org.apache.commons.lang3.StringUtils;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
/**
* This class holds information about blacklisted paths and hashes that, if found in a machine's
* IMA log, would be adverse indicators of the integrity of that machine. This class is intended
* to be flexible, and as such, any instance may include only a path, only a hash, or both.
* For blacklist records that contain only one of these two pieces of information, a measurement
* record will be considered as matching if its respective path or hash matches that record.
* For blacklist records that contain both pieces of information, only measurement records
* that contain both a matching path and hash will be considered as matching.
*/
@Entity
public class ImaBlacklistRecord extends AbstractImaBaselineRecord {
/**
* Referenced in DbImaBlacklistBaselineRecordManager.iterateOverBaselineRecords().
*/
public static final int FILENAME_HASH_BUCKET_COUNT = 4;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "ima_baseline_id")
private ImaBlacklistBaseline baseline;
/**
* Construct a new ImaBlacklistRecord that blacklists any file at the given path.
*
* @param path the path to blacklist
*/
public ImaBlacklistRecord(final String path) {
this(path, null, null, null);
}
/**
* Construct a new ImaBlacklistRecord that blacklists any file at the given path.
*
* @param path the path to blacklist
* @param description a description of the given path, may be null
*/
public ImaBlacklistRecord(final String path, final String description) {
this(path, null, description, null);
}
/**
* Construct a new ImaBlacklistRecord that blacklists any file with the given hash.
*
* @param hash the hash to blacklist
*/
public ImaBlacklistRecord(final Digest hash) {
this(null, hash, null, null);
}
/**
* Construct a new ImaBlacklistRecord that blacklists any file with the given hash.
*
* @param hash the hash to blacklist
* @param description a description of the given hash. may be null
*/
public ImaBlacklistRecord(final Digest hash, final String description) {
this(null, hash, description, null);
}
/**
* Construct a new ImaBlacklistRecord that blacklists a file at the given path with the given
* hash.
*
* @param path the path to blacklist
* @param hash the hash to blacklist
*/
public ImaBlacklistRecord(final String path, final Digest hash) {
this(path, hash, null, null);
}
/**
* Construct a new ImaBlacklistRecord with the given parameters. Either a path or hash,
* or both, may be provided, as well as a description.
*
* If:
* - a non-null path and a null hash is provided, any file matching the path should be
* considered as blacklisted
* - a null path and a non-null hash is provided, any file whose hash matches the given hash
* should be considered as blacklisted
* - a non-null path and a non-null hash is provided, a file that has both a matching path
* and hash should be considered as blacklisted
*
* This class cannot be instantiated with both a null path and hash.
*
* @param path a blacklisted path, as described above
* @param hash a blacklisted hash, as described above
* @param description a description of the nature of the blacklist record, may be null
*/
public ImaBlacklistRecord(
final String path,
final Digest hash,
final String description) {
this(path, hash, description, null);
}
/**
* Construct a new ImaBlacklistRecord with the given parameters. Either a path or hash,
* or both, may be provided, as well as a description.
*
* If:
* - a non-null path and a null hash is provided, any file matching the path should be
* considered as blacklisted
* - a null path and a non-null hash is provided, any file whose hash matches the given hash
* should be considered as blacklisted
* - a non-null path and a non-null hash is provided, a file that has both a matching path
* and hash should be considered as blacklisted
*
* This class cannot be instantiated with both a null path and hash.
*
* @param path a blacklisted path, as described above
* @param hash a blacklisted hash, as described above
* @param description a description of the nature of the blacklist record, may be null
* @param baseline the baseline that this record belongs to, may be null
*/
public ImaBlacklistRecord(
final String path,
final Digest hash,
final String description,
final ImaBlacklistBaseline baseline) {
super(path, hash, description);
if (path == null && hash == null) {
throw new IllegalArgumentException("Cannot instantiate with both a null path and hash");
}
if (path != null && StringUtils.isEmpty(path)) {
throw new IllegalArgumentException(
"Cannot instantiate with an empty (and non-null) path"
);
}
this.baseline = baseline;
}
/**
* Zero-arg constructor necessary for Hibernate.
*/
protected ImaBlacklistRecord() {
super();
}
/**
* Retrieve the IMA blacklist baseline that this record belongs to.
*
* @return this record's owning blacklist baseline
*/
public ImaBlacklistBaseline getBaseline() {
return baseline;
}
/**
* Set this record's associated blacklist baseline.
*
* @param baseline the blacklist baseline to associate this record with
*/
public void setBaseline(final ImaBlacklistBaseline baseline) {
this.baseline = baseline;
}
/**
* Get the alert match type that should be raised for a measurement record that matches this
* baseline record.
*
* @return the alert match type
*/
public AlertType getAlertMatchType() {
if (getPath() == null) {
return AlertType.IMA_BLACKLIST_HASH_MATCH;
} else if (getHash() == null) {
return AlertType.IMA_BLACKLIST_PATH_MATCH;
} else {
return AlertType.IMA_BLACKLIST_PATH_AND_HASH_MATCH;
}
}
}

View File

@ -1,147 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package hirs.data.persist;
import hirs.data.persist.baseline.ImaIgnoreSetBaseline;
import hirs.data.persist.baseline.AbstractImaBaselineRecord;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import com.google.common.base.Preconditions;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.persistence.Transient;
/**
* An <code>IMAIgnoreSetRecord</code> contains a filepath and description of
* files that should be ignored in IMA reports. The description is to provide
* insight into why a file or group of files (in the case of dynamic matching) was ignored.
*
*/
@Entity
public class ImaIgnoreSetRecord extends AbstractImaBaselineRecord {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "ima_ignore_set_id")
private ImaIgnoreSetBaseline baseline;
@Transient
private static final Pattern RECORD_PATTERN = Pattern.compile("\\((.*),.*\\)");
/**
* Creates a new <code>ImaIgnoreSetRecord</code>.
*
* @param path file path, not null
*/
public ImaIgnoreSetRecord(final String path) {
this(path, null, null);
}
/**
* Creates a new <code>ImaIgnoreSetRecord</code>.
*
* @param path file path, not null
* @param description description of why the file path was added to the ignore set, may be null
*/
public ImaIgnoreSetRecord(final String path, final String description) {
this(path, description, null);
}
/**
* Creates a new <code>ImaIgnoreSetRecord</code>.
*
* @param path file path
* @param baseline the IMA ignore set baseline this record belongs to, may be null
*/
public ImaIgnoreSetRecord(final String path, final ImaIgnoreSetBaseline baseline) {
this(path, null, baseline);
}
/**
* Creates a new <code>ImaIgnoreSetRecord</code>.
*
* @param path file path, not null
* @param description description of why the file path was added to the ignore set, may be null
* @param baseline the IMA ignore set baseline this record belongs to, may be null
*/
public ImaIgnoreSetRecord(
final String path,
final String description,
final ImaIgnoreSetBaseline baseline) {
super(path, null, description);
Preconditions.checkNotNull(path, "Path cannot be null");
this.baseline = baseline;
}
/**
* Default constructor necessary for Hibernate.
*/
protected ImaIgnoreSetRecord() {
super();
}
/**
* This gets the baseline associated with the ignore set record.
*
* @return ImaIgnoreSetBaseline
*/
public final ImaIgnoreSetBaseline getBaseline() {
return baseline;
}
/**
* Sets the given baseline.
*
* @param recordBaseline baseline that matches the given baseline
*/
public final void setBaseline(final ImaIgnoreSetBaseline recordBaseline) {
setOnlyBaseline(recordBaseline);
if (recordBaseline != null) {
recordBaseline.addOnlyToBaseline(this);
}
}
/**
* Sets the baseline for this record.
*
* @param baseline
* baseline or null
*/
public final void setOnlyBaseline(final ImaIgnoreSetBaseline baseline) {
if (this.baseline != null && baseline != null) {
this.baseline.removeOnlyBaseline(this);
}
this.baseline = baseline;
}
/**
* Designed to translate the 'received' String field in an <code>Alert</code> into an <code>
* ImaIgnoreSetRecord</code>. Throws an IllegalArgumentException if an invalid String is passed
* in
*
* @param record String formatted like the 'received' field of an <code>Alert</code>
* @param description Description to be provided for the IMA ignore set baseline record
* @return ImaIgnoreSetRecord built ImaIgnoreSetRecord based on report record String
*/
public static ImaIgnoreSetRecord fromString(final String record, final String description) {
Matcher m = RECORD_PATTERN.matcher(record);
m.matches();
//Verifies that one and only one group was captured based on the Regex pattern.
if (m.groupCount() != 1) {
String msg = String.format("Unexpected number of groups found with pattern \"%s\" "
+ "on string \"%s\"", RECORD_PATTERN.toString(), record);
throw new IllegalArgumentException(msg);
}
return new ImaIgnoreSetRecord(m.group(1), description);
}
}

View File

@ -1,7 +1,6 @@
package hirs.data.persist;
import com.google.common.base.Preconditions;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.utils.xjc.File;
import org.apache.logging.log4j.LogManager;
@ -21,7 +20,6 @@ public class SwidResource {
private String name, size;
private String rimFormat, rimType, rimUriGlobal, hashValue;
private TpmWhiteListBaseline tpmWhiteList;
private DigestAlgorithm digest = DigestAlgorithm.SHA1;
private boolean validFileSize = false;
@ -76,7 +74,6 @@ public class SwidResource {
}
this.digest = digest;
tpmWhiteList = new TpmWhiteListBaseline(this.name);
}
/**

View File

@ -1,18 +1,10 @@
package hirs.data.persist;
import hirs.data.persist.baseline.TpmBlackListBaseline;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import hirs.data.persist.baseline.HasBaselines;
import hirs.data.persist.baseline.Baseline;
import hirs.data.persist.enums.AlertSeverity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
@ -21,13 +13,12 @@ import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OrderColumn;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Class represents TPM policy. TPM Policy identifies the TPMBaseline instance that the TPM
@ -38,7 +29,7 @@ import org.apache.logging.log4j.Logger;
* maintains a set of the PCRs that should be appraised on a device-specific basis.
*/
@Entity
public final class TPMPolicy extends Policy implements HasBaselines {
public final class TPMPolicy extends Policy {
/**
* Identifies all valid TPM PCRs bits (i.e. PCR 0-23) in any TPM PCR mask.
@ -80,18 +71,6 @@ public final class TPMPolicy extends Policy implements HasBaselines {
@Enumerated(EnumType.STRING)
private AlertSeverity kernelUpdateAlertSeverity = AlertSeverity.UNSPECIFIED;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "TPMWhiteListBaselines",
joinColumns = { @JoinColumn(name = "PolicyID", nullable = false) })
@OrderColumn(name = "TPMWhiteListBaselineIndex")
private final List<TpmWhiteListBaseline> tpmWhiteListBaselines = new LinkedList<>();
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "TPMBlackListBaselines",
joinColumns = { @JoinColumn(name = "PolicyID", nullable = false) })
@OrderColumn(name = "TPMBlackListBaselineIndex")
private final List<TpmBlackListBaseline> tpmBlackListBaselines = new LinkedList<>();
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "TPMPolicyDeviceSpecificPCRs",
joinColumns = { @JoinColumn(name = "PolicyID", nullable = false) })
@ -126,98 +105,6 @@ public final class TPMPolicy extends Policy implements HasBaselines {
super();
}
/**
* Configures the policy such that it contains only the given TPM WhiteList
* baseline, which identifies
* trusted PCR values for appraising a device. The trusted values are the expected or
* acceptable values for PCRs. The report's PCR values will be compared against these values
* to determine if the device is in a trusted state.
*
* @param baseline
* The TPM white list baseline to be used by this policy.
*/
public void setTpmWhiteListBaseline(final TpmWhiteListBaseline baseline) {
LOGGER.debug("setting TpmWhiteListBaseline {} for the {} policy", baseline, getName());
if (baseline == null) {
throw new PolicyException("Cannot set TPM baseline to null");
}
this.tpmWhiteListBaselines.clear();
this.tpmWhiteListBaselines.add(baseline);
}
/**
* Configures the policy such that it contains only the given TPM BlackList baseline,
* which identifies PCR values that are not permitted.
* Reports containing values that are not permitted result in the generation of an alert.
*
* @param baseline
* The TPM black list baseline to be used by this policy.
*/
public void setTpmBlackListBaseline(final TpmBlackListBaseline baseline) {
LOGGER.debug("setting TpmBlackListBaseline {} for the {} policy", baseline, getName());
if (baseline == null) {
throw new PolicyException("Cannot set TPM baseline to null");
}
this.tpmBlackListBaselines.clear();
this.tpmBlackListBaselines.add(baseline);
}
/**
* Configures the policy such that it contains the given TPM white list baselines,
* which together identify trusted PCR values for appraising a device. These trusted
* values are the expected or acceptable values for PCRs. The report's PCR
* values will be compared against these values to determine if the device
* is in a trusted state.
*
* @param baselines
* The TPM white list baselines to be used by this policy.
*/
public void setTpmWhiteListBaselines(final Collection<TpmWhiteListBaseline> baselines) {
LOGGER.debug("setting TpmWhiteListBaseline {} for the {} policy", baselines, getName());
if (baselines == null) {
throw new PolicyException("Cannot set TPM baselines to null");
}
this.tpmWhiteListBaselines.clear();
this.tpmWhiteListBaselines.addAll(baselines);
}
/**
* Configures the policy such that it contains multiple TPM BlackList baselines,
* which identifies PCR values that are not permitted.
* Reports containing values that are not permitted result in the generation of an alert.
*
* @param blackListBaselines
* The TPM black list baselines to be used by this policy.
*/
public void setTpmBlackListBaselines(
final Collection<TpmBlackListBaseline> blackListBaselines) {
LOGGER.debug("setting TpmBlackListBaseline {} for the {} policy",
blackListBaselines, getName());
if (blackListBaselines == null) {
throw new PolicyException("Cannot set TPM baselines to null");
}
this.tpmBlackListBaselines.clear();
this.tpmBlackListBaselines.addAll(blackListBaselines);
}
/**
* Returns the TPM whitelist baselines associated with this policy.
*
* @return the TPM whitelist baselines for this policy
*/
public Collection<TpmWhiteListBaseline> getTpmWhiteListBaselines() {
return Collections.unmodifiableCollection(this.tpmWhiteListBaselines);
}
/**
* Returns the TPM blacklist baselines associated with this policy.
*
* @return the TPM blacklist baselines for this policy
*/
public List<TpmBlackListBaseline> getTpmBlackListBaselines() {
return Collections.unmodifiableList(tpmBlackListBaselines);
}
/**
* Returns a set of the device-specific PCRs. These are PCR IDs used by the appraiser to know
* that the hash for that PCR should be compared against values for those PCRs from a previous
@ -567,13 +454,6 @@ public final class TPMPolicy extends Policy implements HasBaselines {
kernelUpdateAlertSeverity = severity;
}
@Override
public List<Baseline> getBaselines() {
List<Baseline> baselines = new ArrayList<>();
baselines.addAll(tpmWhiteListBaselines);
return Collections.unmodifiableList(baselines);
}
/**
* Format the list of kernel pcrs into a String for display purposes.
* @return String

View File

@ -1,14 +1,10 @@
package hirs.persist;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import hirs.FilteredRecordsList;
import org.apache.commons.lang3.reflect.FieldUtils;
import hirs.data.persist.ArchivableEntity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
@ -25,28 +21,16 @@ import org.hibernate.criterion.Restrictions;
import org.hibernate.query.Query;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import static org.hibernate.criterion.Restrictions.ilike;
import static org.hibernate.criterion.Restrictions.sqlRestriction;
@ -56,25 +40,25 @@ import static org.hibernate.criterion.Restrictions.sqlRestriction;
* This class exists primarily to reduce code in {@link DBManager} which retries these methods
* using a RetryTemplate.
*
* @param <AbstractEntity> type of objects to manage by this manager
* @param <T> type of objects to manage by this manager
*/
public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<AbstractEntity> {
public abstract class AbstractDbManager<T> implements CrudManager<ArchivableEntity> {
private static final Logger LOGGER = LogManager.getLogger(AbstractDbManager.class);
private static final int MAX_CLASS_CACHE_ENTRIES = 500;
private final AbstractEntity entity;
private final ArchivableEntity entity;
private SessionFactory factory;
/**
* Creates a new <code>AbstractDbManager</code>.
*
* @param clazz Class to search for when doing Hibernate queries,
* @param entity Class to search for when doing Hibernate queries,
* unfortunately class type of T cannot be determined using only T
* @param sessionFactory the session factory to use to interact with the database
*/
public AbstractDbManager(final AbstractEntity entity, final SessionFactory sessionFactory) {
public AbstractDbManager(final ArchivableEntity entity, final SessionFactory sessionFactory) {
if (entity == null) {
LOGGER.error("AbstractDbManager cannot be instantiated with a null class");
throw new IllegalArgumentException(
@ -91,74 +75,6 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
this.factory = sessionFactory;
}
private static final LoadingCache<AbstractEntity, Set<Field>> PERSISTED_FIELDS =
CacheBuilder.newBuilder()
.maximumSize(MAX_CLASS_CACHE_ENTRIES)
.build(new CacheLoader<AbstractEntity, Set<Field>>() {
@Override
public Set<Field> load(final AbstractEntity entity) throws Exception {
return getPersistedFields(entity);
}
});
private static Set<Field> getPersistedFields(final AbstractEntity entity) {
Set<Field> fields = new HashSet<>();
for (Field f : entity.getDeclaredFields()) {
if (f.isAnnotationPresent(OneToMany.class)
|| f.isAnnotationPresent(ManyToMany.class)
|| f.isAnnotationPresent(ManyToOne.class)
|| f.isAnnotationPresent(OneToOne.class)
|| f.isAnnotationPresent(Column.class)) {
fields.add(f);
}
}
if (entity.getSuperclass() != Object.class) {
fields.addAll(getPersistedFields(entity.getSuperclass()));
}
return fields;
}
private static final LoadingCache<Class, Set<Field>> LAZY_LOADED_FIELDS =
CacheBuilder.newBuilder()
.maximumSize(MAX_CLASS_CACHE_ENTRIES)
.build(
new CacheLoader<Class, Set<Field>>() {
@Override
public Set<Field> load(final Class clazz) throws Exception {
return getLazyFields(clazz);
}
}
);
private static Set<Field> getLazyFields(final Class clazz) {
Set<Field> fields = new HashSet<>();
for (Field f : clazz.getDeclaredFields()) {
if (f.isAnnotationPresent(OneToMany.class)) {
if (f.getAnnotation(OneToMany.class).fetch().equals(FetchType.LAZY)) {
fields.add(f);
}
continue;
}
if (f.isAnnotationPresent(ManyToMany.class)) {
if (f.getAnnotation(ManyToMany.class).fetch().equals(FetchType.LAZY)) {
fields.add(f);
}
continue;
}
}
if (clazz.getSuperclass() != Object.class) {
fields.addAll(getLazyFields(clazz.getSuperclass()));
}
return fields;
}
/**
* Return the currently configured database implementation.
*
@ -204,8 +120,8 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
LOGGER.debug("retrieving object from db");
tx = session.beginTransaction();
Object obj = session.get(entity, id);
if (obj instanceof AbstractEntity) {
AbstractEntity objectOfTypeT = (AbstractEntity) obj;
if (obj instanceof hirs.data.persist.ArchivableEntity) {
hirs.data.persist.ArchivableEntity objectOfTypeT = (hirs.data.persist.ArchivableEntity) obj;
LOGGER.debug("found object, deleting it");
session.delete(objectOfTypeT);
deleted = true;
@ -248,16 +164,16 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
Transaction tx = null;
Session session = factory.getCurrentSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<AbstractEntity> criteria = builder.createQuery(entity);
CriteriaQuery<hirs.data.persist.ArchivableEntity> criteria = builder.createQuery(entity);
try {
LOGGER.debug("retrieving object from db");
tx = session.beginTransaction();
Root<AbstractEntity> myObjectRoot = criteria.from(clazz);
Join<AbstractEntity, JoinObject> joinObject = myObjectRoot.join("joinObject");
Root<hirs.data.persist.ArchivableEntity> myObjectRoot = criteria.from(clazz);
Join<hirs.data.persist.ArchivableEntity, JoinObject> joinObject = myObjectRoot.join("joinObject");
Object object = session.getSessionFactory().getCurrentSession().createCriteria(clazz)
.add(Restrictions.eq("name", name)).uniqueResult();
if (object instanceof AbstractEntity) {
AbstractEntity objectOfTypeT = (AbstractEntity) object;
if (object instanceof hirs.data.persist.ArchivableEntity) {
hirs.data.persist.ArchivableEntity objectOfTypeT = (hirs.data.persist.ArchivableEntity) object;
LOGGER.debug("found object, deleting it");
session.delete(objectOfTypeT);
deleted = true;
@ -287,7 +203,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* @throws DBManagerException if unable to find the baseline or delete it
* from the database
*/
protected boolean doDelete(final AbstractEntity object) throws DBManagerException {
protected boolean doDelete(final ArchivableEntity object) throws DBManagerException {
LOGGER.debug("deleting object: {}", object);
if (object == null) {
LOGGER.debug("null object argument");
@ -327,14 +243,14 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
LOGGER.debug("Deleting instances of class: {}", clazz);
tx = session.beginTransaction();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<AbstractEntity> criteriaQuery = builder.createQuery(clazz);
Root<AbstractEntity> root = criteriaQuery.from(clazz);
CriteriaQuery<ArchivableEntity> criteriaQuery = builder.createQuery(clazz);
Root<hirs.data.persist.ArchivableEntity> root = criteriaQuery.from(clazz);
Predicate recordPredicate = builder.and(
);
criteriaQuery.select(root).where(recordPredicate);
Query<AbstractEntity> query = session.createQuery(criteriaQuery);
List<AbstractEntity> results = query.getResultList();
AbstractEntity ret = null;
Query<ArchivableEntity> query = session.createQuery(criteriaQuery);
List<ArchivableEntity> results = query.getResultList();
ArchivableEntity ret = null;
if (results != null && !results.isEmpty()) {
ret = results.get(0);
}
@ -342,8 +258,8 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
List instances = session.createCriteria(clazz)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
for (Object instance : instances) {
if (instance instanceof AbstractEntity) {
session.delete((AbstractEntity) instance);
if (instance instanceof ArchivableEntity) {
session.delete((ArchivableEntity) instance);
numEntitiesDeleted++;
}
}
@ -370,7 +286,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* @throws DBManagerException if an error is encountered while performing the query or creating
* the result objects
*/
protected List<AbstractEntity> doGetWithCriteria(final Collection<Criterion> criteriaCollection)
protected List<ArchivableEntity> doGetWithCriteria(final Collection<Criterion> criteriaCollection)
throws DBManagerException {
return doGetWithCriteria(entity, criteriaCollection);
}
@ -379,7 +295,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* Runs a Criteria query using the given collection of Criterion over the
* associated class.
*
* @param <AbstractEntity> the specific type of class to retrieve
* @param <ArchivableEntity> the specific type of class to retrieve
* (should extend this class' &lt;T&gt; parameter)
* @param clazzToGet the class of object to retrieve
* @param criteriaCollection the collection of Criterion to apply
@ -388,8 +304,8 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* @throws DBManagerException if an error is encountered while performing the query or creating
* the result objects
*/
protected final List<AbstractEntity> doGetWithCriteria(
final Class<AbstractEntity> clazzToGet,
protected final List<ArchivableEntity> doGetWithCriteria(
final Class<ArchivableEntity> clazzToGet,
final Collection<Criterion> criteriaCollection
) throws DBManagerException {
LOGGER.debug("running criteria query over: {}", clazzToGet);
@ -397,7 +313,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
LOGGER.debug("null object argument");
throw new NullPointerException("criteria or restrictions");
}
List<AbstractEntity> ret = new ArrayList<>();
List<ArchivableEntity> ret = new ArrayList<>();
Transaction tx = null;
Session session = factory.getCurrentSession();
try {
@ -437,7 +353,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* @throws DBManagerException if object has previously been saved or an
* error occurs while trying to save it to the database
*/
protected AbstractEntity doSave(final AbstractEntity object) throws DBManagerException {
protected ArchivableEntity doSave(final ArchivableEntity object) throws DBManagerException {
LOGGER.debug("saving object: {}", object);
if (object == null) {
LOGGER.debug("null object argument");
@ -452,7 +368,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
final Serializable id = session.save(object);
Object o = session.get(object.getClass(), id);
session.getTransaction().commit();
return (AbstractEntity) o;
return (ArchivableEntity) o;
} catch (Exception e) {
final String msg = "unable to save object";
LOGGER.error(msg, e);
@ -471,7 +387,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* @param object object to update
* @throws DBManagerException if unable to update the record
*/
protected void doUpdate(final AbstractEntity object) throws DBManagerException {
protected void doUpdate(final ArchivableEntity object) throws DBManagerException {
LOGGER.debug("updating object");
if (object == null) {
LOGGER.debug("null object argument");
@ -506,7 +422,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* @throws DBManagerException if unable to search the database or recreate
* the <code>Object</code>
*/
protected AbstractEntity doGet(final String name) throws DBManagerException {
protected ArchivableEntity doGet(final String name) throws DBManagerException {
LOGGER.debug("getting object: {}", name);
if (name == null) {
LOGGER.debug("null name argument");
@ -519,14 +435,14 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
LOGGER.debug("retrieving " + entity.toString() + " from db");
tx = session.beginTransaction();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<AbstractEntity> criteriaQuery = builder.createQuery(entity);
Root<AbstractEntity> root = criteriaQuery.from(entity);
CriteriaQuery<ArchivableEntity> criteriaQuery = builder.createQuery(entity);
Root<ArchivableEntity> root = criteriaQuery.from(entity);
Predicate recordPredicate = builder.and(
builder.equal(root.get("name"), name));
criteriaQuery.select(root).where(recordPredicate);
Query<AbstractEntity> query = session.createQuery(criteriaQuery);
List<AbstractEntity> results = query.getResultList();
AbstractEntity ret = null;
Query<ArchivableEntity> query = session.createQuery(criteriaQuery);
List<ArchivableEntity> results = query.getResultList();
ArchivableEntity ret = null;
if (results != null && !results.isEmpty()) {
ret = results.get(0);
}
@ -555,7 +471,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* @throws DBManagerException if unable to search the database or recreate
* the <code>Object</code>
*/
protected AbstractEntity doGet(final Serializable id) throws DBManagerException {
protected ArchivableEntity doGet(final Serializable id) throws DBManagerException {
LOGGER.debug("getting object: {}", id);
if (id == null) {
LOGGER.debug("null id argument");
@ -566,155 +482,7 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
try {
LOGGER.debug("retrieving object from db");
tx = session.beginTransaction();
AbstractEntity ret = (AbstractEntity) session.get(entity, id);
tx.commit();
return ret;
} catch (Exception e) {
final String msg = "unable to retrieve object";
LOGGER.error(msg, e);
if (tx != null) {
LOGGER.debug("rolling back transaction");
tx.rollback();
}
throw new DBManagerException(msg, e);
}
}
private void doLoadLazyFields(final Object obj, final boolean recurse)
throws ExecutionException, IllegalAccessException, NoSuchMethodException,
InvocationTargetException {
doLoadLazyFields(obj, recurse, new HashSet<>());
}
private void doLoadLazyFields(final Object obj, final boolean recurse,
final Set<Object> doNotLoad)
throws ExecutionException, IllegalAccessException, NoSuchMethodException,
InvocationTargetException {
if (obj == null) {
return;
}
if (!obj.getClass().isAnnotationPresent(Entity.class)) {
return;
}
doNotLoad.add(obj);
for (Field field : LAZY_LOADED_FIELDS.get(obj.getClass())) {
field.setAccessible(true);
Object fieldObj = FieldUtils.readField(obj, field.getName(), true);
Hibernate.initialize(fieldObj);
field.setAccessible(false);
if (fieldObj instanceof Collection) {
Collection.class.getMethod("size").invoke(fieldObj);
}
}
if (recurse) {
for (Field field : PERSISTED_FIELDS.get(obj.getClass())) {
field.setAccessible(true);
Object fieldObj = FieldUtils.readField(obj, field.getName(), true);
field.setAccessible(false);
if (!doNotLoad.contains(fieldObj)) {
if (fieldObj instanceof Collection) {
for (Object o : (Collection) fieldObj) {
doLoadLazyFields(o, true, doNotLoad);
}
} else {
doLoadLazyFields(fieldObj, true, doNotLoad);
}
}
}
}
}
/**
* Retrieves the <code>Object</code> from the database. This searches the
* database for an entry whose name matches <code>name</code>. It then
* reconstructs the <code>Object</code> from the database entry. It will also
* load all the lazy fields in the given class. If the parameter <code>recurse</code>
* is set to true, this method will recursively descend into each of the object's fields
* to load all the lazily-loaded entities. If false, only the fields belonging to the object
* itself will be loaded.
*
* @param name name of the object
* @param recurse whether to recursively load lazy data throughout the object's structures
* @return object if found, otherwise null.
* @throws DBManagerException if unable to search the database or recreate
* the <code>Object</code>
*/
protected AbstractEntity doGetAndLoadLazyFields(final String name, final boolean recurse)
throws DBManagerException {
LOGGER.debug("getting object: {}", name);
if (name == null) {
LOGGER.debug("null id argument");
return null;
}
Transaction tx = null;
Session session = factory.getCurrentSession();
try {
LOGGER.debug("retrieving " + entity.toString() + " from db");
tx = session.beginTransaction();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<AbstractEntity> criteriaQuery = builder.createQuery(entity);
Root<AbstractEntity> root = criteriaQuery.from(entity);
Predicate recordPredicate = builder.and(
builder.equal(root.get("name"), name));
criteriaQuery.select(root).where(recordPredicate);
Query<AbstractEntity> query = session.createQuery(criteriaQuery);
List<AbstractEntity> results = query.getResultList();
AbstractEntity ret = null;
if (results != null && !results.isEmpty()) {
ret = results.get(0);
}
// T ret = clazz.cast(session.createCriteria(clazz)
// .add(Restrictions.eq("name", name)).uniqueResult());
doLoadLazyFields(ret, recurse);
tx.commit();
return ret;
} catch (Exception e) {
final String msg = "unable to retrieve object";
LOGGER.error(msg, e);
if (tx != null) {
LOGGER.debug("rolling back transaction");
tx.rollback();
}
throw new DBManagerException(msg, e);
}
}
/**
* Retrieves the <code>Object</code> from the database. This searches the
* database for an entry whose id matches <code>id</code>. It then
* reconstructs the <code>Object</code> from the database entry. It will also
* load all the lazy fields in the given class. If the parameter <code>recurse</code>
* is set to true, this method will recursively descend into each of the object's fields
* to load all the lazily-loaded entities. If false, only the fields belonging to the object
* itself will be loaded.
*
* @param id id of the object
* @param recurse whether to recursively load lazy data throughout the object's structures
* @return object if found, otherwise null.
* @throws DBManagerException if unable to search the database or recreate
* the <code>Object</code>
*/
protected AbstractEntity doGetAndLoadLazyFields(final Serializable id, final boolean recurse)
throws DBManagerException {
LOGGER.debug("getting object: {}", id);
if (id == null) {
LOGGER.debug("null id argument");
return null;
}
Transaction tx = null;
Session session = factory.getCurrentSession();
try {
LOGGER.debug("retrieving object from db");
tx = session.beginTransaction();
AbstractEntity ret = (AbstractEntity) session.get(entity, id);
doLoadLazyFields(ret, recurse);
ArchivableEntity ret = (ArchivableEntity) session.get(entity, id);
tx.commit();
return ret;
} catch (Exception e) {
@ -742,17 +510,17 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* @return list of <code>T</code> names
* @throws DBManagerException if unable to search the database
*/
protected List<AbstractEntity> doGetList(final AbstractEntity entity,
protected List<ArchivableEntity> doGetList(final ArchivableEntity entity,
final Criterion additionalRestriction)
throws DBManagerException {
LOGGER.debug("Getting object list");
AbstractEntity searchClass = entity;
ArchivableEntity searchClass = entity;
if (entity == null) {
LOGGER.debug("entity is null");
searchClass = this.entity;
}
List<AbstractEntity> objects = new ArrayList<>();
List<ArchivableEntity> objects = new ArrayList<>();
Transaction tx = null;
Session session = factory.getCurrentSession();
try {
@ -774,8 +542,8 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
}
// List list = criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
for (Object o : results) {
if (o instanceof AbstractEntity) {
objects.add((AbstractEntity) o);
if (o instanceof ArchivableEntity) {
objects.add((ArchivableEntity) o);
}
}
tx.commit();
@ -812,12 +580,12 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
* @throws DBManagerException if unable to create the list
*/
@SuppressWarnings("checkstyle:parameternumber")
protected FilteredRecordsList<AbstractEntity> doGetOrderedList(final AbstractEntity clazz,
protected FilteredRecordsList<ArchivableEntity> doGetOrderedList(final ArchivableEntity clazz,
final String columnToOrder, final boolean ascending, final int firstResult,
final int maxResults, final String search, final Map<String, Boolean> searchableColumns,
final CriteriaModifier criteriaModifier) throws DBManagerException {
LOGGER.debug("Getting object list");
AbstractEntity searchClass = clazz;
ArchivableEntity searchClass = clazz;
if (clazz == null) {
LOGGER.debug("clazz is null");
searchClass = this.clazz;
@ -830,9 +598,9 @@ public abstract class AbstractDbManager<AbstractEntity> implements CrudManager<A
}
//Object that will store query values
FilteredRecordsList<AbstractEntity> aqr = new FilteredRecordsList<>();
FilteredRecordsList<ArchivableEntity> aqr = new FilteredRecordsList<>();
List<AbstractEntity> objects = new ArrayList<>();
List<ArchivableEntity> objects = new ArrayList<>();
Transaction tx = null;
Session session = factory.getCurrentSession();
try {

View File

@ -1,5 +1,6 @@
package hirs.persist;
import hirs.data.persist.AbstractEntity;
import org.hibernate.criterion.Criterion;
import java.io.Serializable;
@ -9,7 +10,7 @@ import java.util.List;
* Interface defining database CRUD operations (Create, Read, Update, Delete).
* @param <T> the object type, T.
*/
public interface CrudManager<AbstractEntity> extends OrderedListQuerier<AbstractEntity> {
public interface CrudManager<T> extends OrderedListQuerier<AbstractEntity> {
/**
* Deletes all instances of the associated class.
@ -80,39 +81,39 @@ public interface CrudManager<AbstractEntity> extends OrderedListQuerier<Abstract
*/
AbstractEntity get(Serializable id) throws DBManagerException;
/**
* Retrieves the <code>Object</code> from the database. This searches the
* database for an entry whose id matches <code>id</code>. It then
* reconstructs the <code>Object</code> from the database entry. It will also
* load all the lazy fields in the given class. If the parameter <code>recurse</code>
* is set to true, this method will recursively descend into each of the object's fields
* to load all the lazily-loaded entities. If false, only the fields belonging to the object
* itself will be loaded.
*
* @param id id of the object
* @param recurse whether to recursively load lazy data throughout the object's structures
* @return object if found, otherwise null.
* @throws DBManagerException if unable to search the database or recreate
* the <code>Object</code>
*/
AbstractEntity getAndLoadLazyFields(Serializable id, boolean recurse)
throws DBManagerException;
/**
* Returns a list of all <code>T</code>s of type <code>clazz</code> in the database, with no
* additional restrictions.
* <p>
* This would be useful if <code>T</code> has several subclasses being
* managed. This class argument allows the caller to limit which types of
* <code>T</code> should be returned.
*
* @param clazz class type of <code>T</code>s to search for (may be null to
* use Class&lt;T&gt;)
* @return list of <code>T</code> names
* @throws DBManagerException if unable to search the database
*/
List<AbstractEntity> getList(AbstractEntity entity)
throws DBManagerException;
// /**
// * Retrieves the <code>Object</code> from the database. This searches the
// * database for an entry whose id matches <code>id</code>. It then
// * reconstructs the <code>Object</code> from the database entry. It will also
// * load all the lazy fields in the given class. If the parameter <code>recurse</code>
// * is set to true, this method will recursively descend into each of the object's fields
// * to load all the lazily-loaded entities. If false, only the fields belonging to the object
// * itself will be loaded.
// *
// * @param id id of the object
// * @param recurse whether to recursively load lazy data throughout the object's structures
// * @return object if found, otherwise null.
// * @throws DBManagerException if unable to search the database or recreate
// * the <code>Object</code>
// */
// AbstractEntity getAndLoadLazyFields(Serializable id, boolean recurse)
// throws DBManagerException;
//
// /**
// * Returns a list of all <code>T</code>s of type <code>clazz</code> in the database, with no
// * additional restrictions.
// * <p>
// * This would be useful if <code>T</code> has several subclasses being
// * managed. This class argument allows the caller to limit which types of
// * <code>T</code> should be returned.
// *
// * @param AbstractEntity class type of <code>T</code>s to search for (may be null to
// * use Class&lt;T&gt;)
// * @return list of <code>T</code> names
// * @throws DBManagerException if unable to search the database
// */
// List<AbstractEntity> getList(AbstractEntity entity)
// throws DBManagerException;
/**
* Returns a list of all <code>T</code>s of type <code>clazz</code> in the database, with an
@ -122,7 +123,7 @@ public interface CrudManager<AbstractEntity> extends OrderedListQuerier<Abstract
* managed. This class argument allows the caller to limit which types of
* <code>T</code> should be returned.
*
* @param clazz class type of <code>T</code>s to search for (may be null to
* @param AbstractEntity class type of <code>T</code>s to search for (may be null to
* use Class&lt;T&gt;)
* @param additionalRestriction - an added Criterion to use in the query, null for none
* @return list of <code>T</code> names

View File

@ -1,6 +1,7 @@
package hirs.persist;
import hirs.FilteredRecordsList;
import hirs.data.persist.AbstractEntity;
import hirs.data.persist.ArchivableEntity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -27,7 +28,7 @@ import java.util.Map;
* archive, and delete operations for managing objects in a database.
*
*/
public class DBManager<AbstractEntity> extends AbstractDbManager<AbstractEntity> {
public class DBManager<T> extends AbstractDbManager<AbstractEntity> {
private static final Logger LOGGER = LogManager.getLogger(DBManager.class);
/**
@ -114,7 +115,7 @@ public class DBManager<AbstractEntity> extends AbstractDbManager<AbstractEntity>
* @throws DBManagerException if an error is encountered while performing the query or creating
* the result objects
*/
public final List<AbstractEntity> getWithCriteria(final Collection<Criterion> criteriaCollection)
public final List<hirs.data.persist.ArchivableEntity> getWithCriteria(final Collection<Criterion> criteriaCollection)
throws DBManagerException {
return retryTemplate.execute(
new RetryCallback<List<AbstractEntity>, DBManagerException>() {
@ -137,13 +138,13 @@ public class DBManager<AbstractEntity> extends AbstractDbManager<AbstractEntity>
* @throws DBManagerException if an error is encountered while performing the query or creating
* the result objects
*/
protected final List<AbstractEntity> getWithCriteria(
final Class<AbstractEntity> clazzToGet,
protected final List<hirs.data.persist.ArchivableEntity> getWithCriteria(
final Class<hirs.data.persist.ArchivableEntity> clazzToGet,
final Collection<Criterion> criteriaCollection) throws DBManagerException {
return retryTemplate.execute(
new RetryCallback<List<AbstractEntity>, DBManagerException>() {
@Override
public List<AbstractEntity> doWithRetry(final RetryContext context)
public List<hirs.data.persist.ArchivableEntity> doWithRetry(final RetryContext context)
throws DBManagerException {
return doGetWithCriteria(clazzToGet, criteriaCollection);
}
@ -213,10 +214,10 @@ public class DBManager<AbstractEntity> extends AbstractDbManager<AbstractEntity>
* @throws DBManagerException if unable to search the database or recreate
* the <code>Object</code>
*/
public final AbstractEntity get(final String name) throws DBManagerException {
return retryTemplate.execute(new RetryCallback<AbstractEntity, DBManagerException>() {
public final ArchivableEntity get(final String name) throws DBManagerException {
return retryTemplate.execute(new RetryCallback<ArchivableEntity, DBManagerException>() {
@Override
public AbstractEntity doWithRetry(final RetryContext context) throws DBManagerException {
public ArchivableEntity doWithRetry(final RetryContext context) throws DBManagerException {
return doGet(name);
}
});
@ -488,7 +489,7 @@ public class DBManager<AbstractEntity> extends AbstractDbManager<AbstractEntity>
return false;
}
AbstractEntity target = get(name);
ArchivableEntity target = get(name);
if (target == null) {
return false;
}

View File

@ -5,14 +5,11 @@ import hirs.appraiser.Appraiser;
import hirs.data.persist.Device;
import hirs.data.persist.DeviceGroup;
import hirs.data.persist.Policy;
import hirs.data.persist.baseline.Baseline;
import hirs.data.persist.baseline.HasBaselines;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.hibernate.query.Query;
import javax.persistence.criteria.CriteriaBuilder;
@ -20,7 +17,6 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
@ -97,36 +93,7 @@ public class DBPolicyManager extends DBManager<Policy> implements PolicyManager
public final List<Policy> getPolicyList(final Class<? extends Policy> clazz)
throws PolicyManagerException {
LOGGER.debug("getting policy list");
try {
return super.getList(clazz, Restrictions.isNull("archivedTime"));
} catch (DBManagerException e) {
throw new PolicyManagerException(e);
}
}
/**
* Return a list of all the policies that contain the given baseline.
*
* @param clazz the class of Policy to search
* @param baseline the baseline that should be a member of returned Policies
* @return the list of matching Policies
*/
@Override
public List<Policy> getPoliciesContainingBaseline(
final Class<? extends Policy> clazz,
final Baseline baseline
) {
List<Policy> matchingPolicies = new ArrayList<>();
List<Policy> policies = getPolicyList(clazz);
for (Policy policy : policies) {
if (policy instanceof HasBaselines) {
HasBaselines policyWithBaselines = (HasBaselines) policy;
if (policyWithBaselines.getBaselines().contains(baseline)) {
matchingPolicies.add(policy);
}
}
}
return matchingPolicies;
return null;
}
/**

View File

@ -1,29 +1,16 @@
package hirs.persist;
import hirs.FilteredRecordsList;
import hirs.data.bean.SimpleImaRecordBean;
import hirs.data.persist.IMAMeasurementRecord;
import hirs.data.persist.IMAReport;
import hirs.data.persist.IntegrityReport;
import hirs.data.persist.Report;
import hirs.data.persist.ReportSummary;
import hirs.persist.imarecord.DbImaRecordQueryForDevice;
import hirs.persist.imarecord.DbImaRecordQueryForDeviceSinceLastFullReport;
import hirs.persist.imarecord.DbImaRecordQueryForNone;
import hirs.persist.imarecord.DbImaRecordQueryForReport;
import hirs.persist.imarecord.DbImaRecordQueryParameters;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -90,165 +77,12 @@ public class DBReportManager extends DBManager<Report> implements ReportManager
throws ReportManagerException {
LOGGER.debug("getting report list");
try {
return super.getList(clazz);
return super.getList(Report);
} catch (DBManagerException e) {
throw new ReportManagerException(e);
}
}
/**
* Returns a list of all Report Records that are ordered by a column
* and direction (ASC, DESC) that is provided by the user. This
* method contains database interactions designed to extract specific
* fields from the database to avoid retrieving full records in order
* to improve query performance and reduce the size of teh data set
* returned to the caller. This method helps support the server-side
* processing in the JQuery DataTables.
*
* @param scope the scope of the search: NONE, ALL, REPORT, or DEVICE
* @param id the id or name of the REPORT or DEVICE to search
* @param sinceLastFullReport limits the records to those since the last full report for the
* device
* @param columnToOrder Column to be ordered
* @param ascending direction of sort
* @param firstResult starting point of first result in set
* @param maxResults total number we want returned for display in table
* @param search string of criteria to be matched to visible columns
* @param searchableColumns map containing columns that search string can
* be applied to
* @return FilteredRecordsList object with fields for DataTables
* @throws ReportManagerException if unable to create the list
*/
@Override
@SuppressWarnings("checkstyle:parameternumber")
public final FilteredRecordsList<SimpleImaRecordBean>
getOrderedRecordListWithoutRecords(
final IMARecordScope scope,
final String id,
final boolean sinceLastFullReport,
final IMARecordField columnToOrder,
final boolean ascending,
final int firstResult,
final int maxResults,
final String search,
final Map<String, Boolean> searchableColumns)
throws ReportManagerException {
// check columnToOrder
if (columnToOrder == null) {
final String msg = "columnToOrder cannot be null";
LOGGER.error(msg);
throw new IllegalArgumentException(msg);
}
// check scope
if (scope == null) {
throw new IllegalArgumentException("IMARecordScope cannot be null");
}
switch (scope) {
case NONE:
// Returns an empty FilteredRecordsList to make DataTables
// display "No Data".
return new FilteredRecordsList<>();
case REPORT:
// return getImaRecordsForReport(id, columnToOrder, ascending,
// firstResult,
// maxResults, search, searchableColumns);
case DEVICE:
// return getImaRecordsForDevice(id, sinceLastFullReport,
// columnToOrder, ascending, firstResult,
// maxResults, search, searchableColumns);
default:
throw new UnsupportedOperationException(
"IMARecordScope " + scope + " is not supported");
}
}
/**
* Returns a list of all Report Records that are ordered by a column
* and direction (ASC, DESC) that is provided by the user. This method
* helps support the server-side processing in the JQuery DataTables.
*
* @param scope the scope of the search: NONE, ALL, REPORT, or DEVICE
* @param id the id or name of the REPORT or DEVICE to search
* @param sinceLastFullReport limits the records to those since the last full report for the
* device
* @param columnToOrder Column to be ordered
* @param ascending direction of sort
* @param firstResult starting point of first result in set
* @param maxResults total number we want returned for display in table
* @param search string of criteria to be matched to visible columns
* @return FilteredRecordsList object with fields for DataTables
* @throws ReportManagerException if unable to create the list
*/
@Override
@SuppressWarnings("checkstyle:parameternumber")
public final FilteredRecordsList<IMAMeasurementRecord> getOrderedRecordList(
final IMARecordScope scope,
final String id,
final boolean sinceLastFullReport,
final IMARecordField columnToOrder,
final boolean ascending,
final int firstResult,
final int maxResults,
final String search)
throws ReportManagerException {
// check columnToOrder
if (columnToOrder == null) {
final String msg = "columnToOrder cannot be null";
LOGGER.error(msg);
throw new IllegalArgumentException(msg);
}
// check scope
if (scope == null) {
throw new IllegalArgumentException("IMARecordScope cannot be null");
}
Transaction tx = null;
Session session = getFactory().getCurrentSession();
try {
tx = session.beginTransaction();
final DbImaRecordQueryParameters params
= new DbImaRecordQueryParameters(id, columnToOrder, ascending,
firstResult, maxResults, search);
switch (scope) {
case NONE:
return new DbImaRecordQueryForNone().query();
case REPORT:
return new DbImaRecordQueryForReport(session, params).query();
case DEVICE:
if (sinceLastFullReport) {
DbImaRecordQueryForDeviceSinceLastFullReport q
= new DbImaRecordQueryForDeviceSinceLastFullReport(session, params);
return q.query();
} else {
return new DbImaRecordQueryForDevice(session, params).query();
}
default:
throw new UnsupportedOperationException(
"IMARecordScope " + scope + " is not supported");
}
} catch (Exception ex) {
String msg = "Error executing IMA Record query for " + scope + " scope.";
if (scope == IMARecordScope.DEVICE) {
msg += "Since last full report = " + sinceLastFullReport;
}
LOGGER.error(msg, ex);
throw ex;
} finally {
if (tx != null) {
tx.rollback();
}
}
}
/**
* Retrieves the <code>Report</code> from the database. This searches the
* database for an entry whose id matches <code>id</code>. It then
@ -330,52 +164,6 @@ public class DBReportManager extends DBManager<Report> implements ReportManager
}
}
/**
* Method retrieves all ima report ids associated with the latest full ima
* report (as determined by a starting index of 0 and the most recent
* report create time) of provided device id.
* @param id of device
* @return list of IMA report ids
*/
private List<UUID> getImaIdsOfRecentBootCycle(final String id) {
ReportSummaryManager reportSummaryManager =
new DBReportSummaryManager(getFactory());
List<ReportSummary> reportSummary = reportSummaryManager
.getReportSummaryListByHostname(id);
List<IMAReport> imaReports = new ArrayList<>();
for (ReportSummary summary : reportSummary) {
IntegrityReport integrityReport = (IntegrityReport) summary
.getReport();
imaReports.add(integrityReport.extractReport(IMAReport.class));
}
String bootCycleId = "";
Date createTime = null;
List<UUID> imaReportIds = new ArrayList<>();
// Retrieve most recent IMAReport where index is 0.
for (IMAReport report : imaReports) {
if (createTime == null) {
createTime = report.getCreateTime();
bootCycleId = report.getBootcycleId();
} else if (createTime.before(report.getCreateTime())
&& report.getIndex() == 0) {
createTime = report.getCreateTime();
bootCycleId = report.getBootcycleId();
}
}
// Retrieve all IMAReports corresponding to bootCycleID.
for (IMAReport report : imaReports) {
if (report.getBootcycleId().equals(bootCycleId)) {
imaReportIds.add(report.getId());
}
}
return imaReportIds;
}
/**
* Method retrieves all ima report ids corresponding to provided
* device id.
@ -391,12 +179,7 @@ public class DBReportManager extends DBManager<Report> implements ReportManager
.getReportSummaryListByHostname(id);
List<UUID> imaReportIds = new ArrayList<>();
for (ReportSummary summary : reportSummary) {
IntegrityReport integrityReport = (IntegrityReport) summary
.getReport();
imaReportIds.add(integrityReport.extractReport(IMAReport.class)
.getId());
}
return imaReportIds;
}

View File

@ -1,211 +0,0 @@
package hirs.persist;
import hirs.data.persist.baseline.Baseline;
import hirs.data.persist.DeviceInfoReport;
import hirs.data.persist.IMAReport;
import hirs.data.persist.IntegrityReport;
import hirs.data.persist.TPMReport;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import hirs.ima.SimpleImaBaselineGenerator;
import hirs.ima.IMABaselineGeneratorException;
import hirs.tpm.TPMBaselineGenerator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* This class is a command-line interface (CLI) for importing baselines into a
* database. This takes a file and stores it in a <code>BaselineManager</code>.
*/
public final class ImportCLI {
private static final Logger LOGGER = LogManager.getLogger(ImportCLI.class);
private static final String HELP = "help";
private static final String TPM = "tpm";
private static final String IMA = "ima";
private static final String CSV = "csv";
private static final String XML = "xml";
private static BaselineManager baselineManager;
/**
* Default constructor that is private to prevent this class from being
* initialized.
*/
private ImportCLI() {
/* do nothing */
}
/**
* Imports a new baseline.
*
* @param args command-line arguments
*/
public static void main(final String[] args) {
LOGGER.debug("import cli started");
loadBeansFromSpringContext();
final int fileIndex = 0;
final int nameIndex = 1;
final Options options = getOptions();
final CommandLineParser parser = new DefaultParser();
InputStream istream = null;
try {
final CommandLine line = parser.parse(options, args);
if (line.hasOption("help")) {
printHelp(options);
return;
}
final String[] extraArgs = line.getArgs();
if (extraArgs.length != 2) {
LOGGER.error("file and baseline name not given");
printHelp(options);
return;
}
LOGGER.debug("importing file: {}", extraArgs[fileIndex]);
istream = new FileInputStream(new File(extraArgs[fileIndex]));
final String name = extraArgs[nameIndex];
Baseline baseline = null;
if (line.hasOption("tpm")) {
LOGGER.debug("specified TPM import");
final TPMBaselineGenerator generator = new TPMBaselineGenerator();
if (line.hasOption("csv")) {
LOGGER.debug("importing csv file");
baseline = generator.generateWhiteListBaselineFromCSVFile(name, istream);
} else {
LOGGER.debug("importing TPM baseline from intgerity report xml file");
IntegrityReport report;
report = getIntegrityReportFromXmlFile(istream);
if (report != null) {
baseline = generator.generateBaselineFromIntegrityReport(name, report);
}
}
}
if (line.hasOption("ima")) {
LOGGER.debug("specified IMA import");
final SimpleImaBaselineGenerator generator = new SimpleImaBaselineGenerator();
if (line.hasOption("csv")) {
LOGGER.debug("importing csv file");
baseline = generator.generateBaselineFromCSVFile(name, istream);
} else {
LOGGER.debug("importing IMA baseline from intgerity report xml file");
IntegrityReport report;
report = getIntegrityReportFromXmlFile(istream);
try {
if (report != null) {
generator.generateBaselineFromIntegrityReport(name, report);
} else {
LOGGER.error("could not create integrity report from xml file");
return;
}
} catch (IMABaselineGeneratorException | NullPointerException e) {
return;
}
}
}
saveBaseline(baseline);
} catch (ParseException e) {
if (options.hasOption(HELP)) {
printHelp(options);
} else {
LOGGER.error("error parsing options");
LOGGER.error(e.getMessage());
printHelp(options);
}
} catch (Exception e) {
LOGGER.error("unable to generate baseline", e);
} finally {
try {
if (istream != null) {
istream.close();
}
} catch (IOException e) {
LOGGER.error("unexpected error closing istream", e);
}
LOGGER.debug("shutdown session factory");
}
}
private static void loadBeansFromSpringContext() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(PersistenceConfiguration.class);
context.refresh();
// register a shutdown hook such that components are properly shutdown when JVM is closing
context.registerShutdownHook();
baselineManager = context.getBean(BaselineManager.class);
}
private static void printHelp(final Options options) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("import-cli {--tpm | --ima} {--csv | --xml} file name", options);
}
private static Options getOptions() {
final Option help = new Option("h", HELP, false, "print this help menu");
final OptionGroup typeGroup = new OptionGroup();
typeGroup.setRequired(true);
final Option tpm = new Option("t", TPM, false, "add TPM baseline");
final Option ima = new Option("i", IMA, false, "add IMA baseline");
typeGroup.addOption(tpm);
typeGroup.addOption(ima);
final OptionGroup formatGroup = new OptionGroup();
formatGroup.setRequired(true);
final Option csv = new Option("c", CSV, false, "CSV file format");
final Option xml = new Option("x", XML, false, "XML report file format");
formatGroup.addOption(csv);
formatGroup.addOption(xml);
final Options options = new Options();
options.addOption(help);
options.addOptionGroup(typeGroup);
options.addOptionGroup(formatGroup);
return options;
}
private static void saveBaseline(final Baseline baseline)
throws BaselineManagerException {
if (baseline == null) {
LOGGER.info("baseline is null");
return;
}
LOGGER.debug("saving baseline");
baselineManager.saveBaseline(baseline);
}
private static IntegrityReport getIntegrityReportFromXmlFile(final InputStream istream) {
try {
JAXBContext context = JAXBContext.newInstance(IntegrityReport.class,
DeviceInfoReport.class, TPMReport.class,
IMAReport.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
return (IntegrityReport) unmarshaller.unmarshal(istream);
} catch (Exception e) {
LOGGER.error("error occurred while unmarshalling Integrity report", e);
return null;
}
}
}

View File

@ -1,12 +1,8 @@
package hirs.persist;
import hirs.FilteredRecordsList;
import hirs.data.bean.SimpleImaRecordBean;
import hirs.data.persist.IMAMeasurementRecord;
import hirs.data.persist.Report;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
@ -45,71 +41,6 @@ public interface ReportManager {
List<Report> getReportList(Class<? extends Report> clazz)
throws ReportManagerException;
/**
* Returns a list of all Report Records that are ordered by a column
* and direction (ASC, DESC) that is provided by the user. This
* method contains database interactions designed to extract specific
* fields from the database to avoid retrieving full records in order
* to improve query performance and reduce the size of teh data set
* returned to the caller. This method helps support the server-side
* processing in the JQuery DataTables.
*
* @param scope the scope of the search: NONE, ALL, REPORT, or DEVICE
* @param id the id or name of the REPORT or DEVICE to search
* @param sinceLastFullReport
* limits the records to those since the last full report for the device
* @param columnToOrder Column to be ordered
* @param ascending direction of sort
* @param firstResult starting point of first result in set
* @param maxResults total number we want returned for display in table
* @param search string of criteria to be matched to visible columns
* @param searchableColumns map containing columns that search string can
* be applied to
* @return FilteredRecordsList object with fields for DataTables
* @throws ReportManagerException if unable to create the list
*/
@SuppressWarnings("checkstyle:parameternumber")
FilteredRecordsList<SimpleImaRecordBean> getOrderedRecordListWithoutRecords(
IMARecordScope scope,
String id,
boolean sinceLastFullReport,
IMARecordField columnToOrder,
boolean ascending,
int firstResult,
int maxResults,
String search,
Map<String, Boolean> searchableColumns)
throws ReportManagerException;
/**
* Returns a list of all Report Records that are ordered by a column
* and direction (ASC, DESC) that is provided by the user. This method
* helps support the server-side processing in the JQuery DataTables.
*
* @param scope the scope of the search: NONE, ALL, REPORT, or DEVICE
* @param id the id or name of the REPORT or DEVICE to search
* @param sinceLastFullReport
* limits the records to those since the last full report for the device
* @param columnToOrder Column to be ordered
* @param ascending direction of sort
* @param firstResult starting point of first result in set
* @param maxResults total number we want returned for display in table
* @param search string of criteria to be matched to visible columns
* @return FilteredRecordsList object with fields for DataTables
* @throws ReportManagerException if unable to create the list
*/
@SuppressWarnings("checkstyle:parameternumber")
FilteredRecordsList<IMAMeasurementRecord> getOrderedRecordList(
IMARecordScope scope,
String id,
boolean sinceLastFullReport,
IMARecordField columnToOrder,
boolean ascending,
int firstResult,
int maxResults,
String search)
throws ReportManagerException;
/**
* Retrieves the <code>Report</code> identified by <code>id</code>.
*

View File

@ -1,12 +1,18 @@
package hirs.repository;
import com.google.common.collect.Multimap;
import hirs.data.persist.Digest;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.data.persist.baseline.IMABaselineRecord;
import hirs.repository.measurement.PackageMeasurer;
import hirs.repository.measurement.RPMMeasurer;
import hirs.utils.exec.ExecBuilder;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import java.io.IOException;
import java.net.URL;
import java.nio.file.FileSystems;
@ -17,17 +23,6 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Transient;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.google.common.collect.Multimap;
import javax.persistence.MappedSuperclass;
/**
* Abstract base class representing a repository that deals with RPM packages.
*
@ -124,12 +119,10 @@ public abstract class RPMRepository<T extends RPMRepoPackage> extends Repository
throws RepositoryException {
try {
Multimap<Path, Digest> measurements = rpmMeasurer.measure(rpmPath);
Set<IMABaselineRecord> packageRecords = new HashSet<>();
Set<Object> packageRecords = new HashSet<>();
for (Map.Entry<Path, Collection<Digest>> e : measurements.asMap().entrySet()) {
for (Digest digest : e.getValue()) {
packageRecords.add(new IMABaselineRecord(
e.getKey().toAbsolutePath().toString(), digest
));
packageRecords.add(digest);
}
}

View File

@ -2,11 +2,8 @@ package hirs.repository.measurement;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import hirs.data.persist.Digest;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.data.persist.baseline.IMABaselineRecord;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -20,12 +17,8 @@ import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* This abstract class implements the basic functionality for measuring a software package. It
@ -216,22 +209,4 @@ public abstract class PackageMeasurer {
return new Digest(digestAlgorithm, value);
}
/**
* Measures the files at the specified file path.
* @param filePath the file path root to measure files
* @return set of IMA Baseline Records
* @throws IOException if an IO error occurrs processing files at the file path
*/
public Set<IMABaselineRecord> measureAndGetRecords(final Path filePath) throws IOException {
Set<IMABaselineRecord> records = new HashSet<>();
Multimap<Path, Digest> map = measure(filePath);
for (Map.Entry<Path, Collection<Digest>> e : map.asMap().entrySet()) {
for (Digest digest : e.getValue()) {
records.add(new IMABaselineRecord(e.getKey().toString(), digest));
}
}
return records;
}
}

View File

@ -1,671 +0,0 @@
package hirs.tpm;
import hirs.data.persist.DeviceInfoReport;
import hirs.data.persist.Digest;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.data.persist.info.FirmwareInfo;
import hirs.data.persist.info.HardwareInfo;
import hirs.data.persist.IntegrityReport;
import hirs.data.persist.info.OSInfo;
import hirs.data.persist.Report;
import hirs.data.persist.baseline.TPMBaseline;
import hirs.data.persist.info.TPMInfo;
import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.TPMReport;
import hirs.data.persist.baseline.TpmBlackListBaseline;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* Class used to process comma separated value files containing TPM PCR
* measurements or HIRS integrity reports to generate a TPM measurement
* baseline. Generating a TPM measurement baseline from a HIRS integrity report
* is considered experimental and provided as a tool to assist with creating,
* analyzing, and refining measurement baselines.
*/
public class TPMBaselineGenerator {
private static final Logger LOGGER
= LogManager.getLogger(TPMBaselineGenerator.class);
private static final String KERNEL_UPDATE_BASELINE_NAME = "Kernel Update %s %s";
private static final String VALID_REGEX = "[0-9a-zA-Z./()_,\" -]+";
/**
* Enumerates the device info fields looked for within a TPMBaseline CSV file.
*/
public enum TPMBaselineFields {
/**
* FirmwareInfo's BIOS Vendor.
*/
BIOS_VENDOR,
/**
* FirmwareInfo's BIOS Version.
*/
BIOS_VERSION,
/**
* FirmwareInfo's BIOS Release Date.
*/
BIOS_RELEASE_DATE,
/**
* HardwareInfo's Manufacturer.
*/
MANUFACTURER,
/**
* HardwareInfo's Product Name.
*/
PRODUCT_NAME,
/**
* HardwareInfo's Version.
*/
VERSION,
/**
* HardwareInfo's Serial number.
*/
SYSTEM_SERIAL_NUMBER,
/**
* HardwareInfo's Chassis serial number.
*/
CHASSIS_SERIAL_NUMBER,
/**
* HardwareInfo's baseboard serial number.
*/
BASEBOARD_SERIAL_NUMBER,
/**
* OSInfo's OS Name.
*/
OS_NAME,
/**
* OSInfo's OS Version.
*/
OS_VERSION,
/**
* OSInfo's OS Arch.
*/
OS_ARCH,
/**
* OSInfo's Distribution.
*/
DISTRIBUTION,
/**
* OSInfo's Distribution Release.
*/
DISTRIBUTION_RELEASE,
/**
* TPMInfo's TPM Make.
*/
TPM_MAKE,
/**
* TPMInfo's TPM Version Major.
*/
TPM_VERSION_MAJOR,
/**
* TPMInfo's TPM Version Minor.
*/
TPM_VERSION_MINOR,
/**
* TPMInfo's TPM Version Rev Major.
*/
TPM_VERSION_REV_MAJOR,
/**
* TPMInfo's TPM Version Rev Minor.
*/
TPM_VERSION_REV_MINOR;
/**
* Generates a CSV String from a map of TPMBaselineFields to values.
* @param map Map&lt;TPMBaselineFields, String&gt;
* @return CSV-escaped String corresponding to the map of values
*/
public static String toCSV(final Map<TPMBaselineFields, String> map) {
if (map == null) {
throw new IllegalArgumentException("TPMBaselineFields.toCSV:"
+ " This method should not have been called with a null parameter.");
}
final StringBuilder builder = new StringBuilder();
for (final Entry<TPMBaselineFields, String> field : map.entrySet()) {
builder.append(field.getKey().name())
.append(",")
.append(StringEscapeUtils.escapeCsv(field.getValue()))
.append(System.lineSeparator());
}
return builder.toString();
}
/**
* Creates a new FirmwareInfo object from the supplied data field changes. Any
* fields not supplied will retain their existing values from the given default
* FirmwareInfo object.
* @param map Map<TPMBaselineFields, String> correlating field keys to values.
* @param defaultInfo the FirmwareInfo object to reference for default values.
* @return new FirmwareInfo object with updated fields.
*/
private static FirmwareInfo toFirmwareInfo(final Map<TPMBaselineFields, String> map,
final FirmwareInfo defaultInfo) {
if (map == null || defaultInfo == null) {
throw new IllegalArgumentException("TPMBaselineFields.toFirmwareInfo:"
+ " This method should not have been called with a null parameter.");
}
final String biosVendor =
StringUtils.defaultIfBlank(
map.get(TPMBaselineFields.BIOS_VENDOR), defaultInfo.getBiosVendor());
final String biosVersion =
StringUtils.defaultIfBlank(
map.get(TPMBaselineFields.BIOS_VERSION), defaultInfo.getBiosVersion());
final String biosReleaseDate =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.BIOS_RELEASE_DATE),
defaultInfo.getBiosReleaseDate());
return new FirmwareInfo(biosVendor, biosVersion, biosReleaseDate);
}
/**
* Creates a new HardwareInfo object from the supplied data field changes. Any
* fields not supplied will retain their existing values from the given default
* HardwareInfo object.
* @param map Map<TPMBaselineFields, String> correlating field keys to values.
* @param defaultInfo the HardwareInfo object to reference for default values.
* @return new HardwareInfo object with updated fields.
*/
private static HardwareInfo toHardwareInfo(final Map<TPMBaselineFields, String> map,
final HardwareInfo defaultInfo) {
if (map == null || defaultInfo == null) {
throw new IllegalArgumentException("TPMBaselineFields.toHardwareInfo:"
+ " This method should not have been called with a null parameter.");
}
final String manufacturer =
StringUtils.defaultIfBlank(
map.get(TPMBaselineFields.MANUFACTURER), defaultInfo.getManufacturer());
final String productName =
StringUtils.defaultIfBlank(
map.get(TPMBaselineFields.PRODUCT_NAME), defaultInfo.getProductName());
final String version =
StringUtils.defaultIfBlank(
map.get(TPMBaselineFields.VERSION), defaultInfo.getVersion());
final String serialNumber =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.SYSTEM_SERIAL_NUMBER),
defaultInfo.getSystemSerialNumber());
final String chassisSerialNumber =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.CHASSIS_SERIAL_NUMBER),
defaultInfo.getChassisSerialNumber());
final String baseboardSerialNumber =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.BASEBOARD_SERIAL_NUMBER),
defaultInfo.getBaseboardSerialNumber());
return new HardwareInfo(
manufacturer,
productName,
version,
serialNumber,
chassisSerialNumber,
baseboardSerialNumber
);
}
/**
* Creates a new OSInfo object from the supplied data field changes. Any
* fields not supplied will retain their existing values from the given default
* OSInfo object.
* @param map Map<TPMBaselineFields, String> correlating field keys to values.
* @param defaultInfo the HardwareInfo object to reference for default values.
* @return new OSInfo object with updated fields.
*/
private static OSInfo toOSInfo(final Map<TPMBaselineFields, String> map,
final OSInfo defaultInfo) {
if (map == null || defaultInfo == null) {
throw new IllegalArgumentException("TPMBaselineFields.toOSInfo:"
+ " This method should not have been called with a null parameter.");
}
final String osName =
StringUtils.defaultIfBlank(
map.get(TPMBaselineFields.OS_NAME), defaultInfo.getOSName());
final String osVersion =
StringUtils.defaultIfBlank(
map.get(TPMBaselineFields.OS_VERSION), defaultInfo.getOSVersion());
final String osArch =
StringUtils.defaultIfBlank(
map.get(TPMBaselineFields.OS_ARCH), defaultInfo.getOSArch());
final String distribution =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.DISTRIBUTION),
defaultInfo.getDistribution());
final String distributionRelease =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.DISTRIBUTION_RELEASE),
defaultInfo.getDistributionRelease());
return new OSInfo(osName, osVersion, osArch, distribution, distributionRelease);
}
/**
* Creates a new TPMInfo object from the supplied data field changes. Any
* fields not supplied will retain their existing values from the given default
* TPMInfo object.
* @param map Map<TPMBaselineFields, String> correlating field keys to values.
* @param defaultInfo the HardwareInfo object to reference for default values.
* @return new TPMInfo object with updated fields.
*/
private static TPMInfo toTPMInfo(final Map<TPMBaselineFields, String> map,
final TPMInfo defaultInfo) {
if (map == null || defaultInfo == null) {
throw new IllegalArgumentException("TPMBaselineFields.toTPMInfo:"
+ " This method should not have been called with a null parameter.");
}
final String tpmMake =
StringUtils.defaultIfBlank(
map.get(TPMBaselineFields.TPM_MAKE), defaultInfo.getTPMMake());
final String tpmVersionMajor =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.TPM_VERSION_MAJOR),
"" + defaultInfo.getTPMVersionMajor());
final String tpmVersionMinor =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.TPM_VERSION_MINOR),
"" + defaultInfo.getTPMVersionMinor());
final String tpmVersionRevMajor =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.TPM_VERSION_REV_MAJOR),
"" + defaultInfo.getTPMVersionRevMajor());
final String tpmVersionRevMinor =
StringUtils.defaultIfBlank(map.get(TPMBaselineFields.TPM_VERSION_REV_MINOR),
"" + defaultInfo.getTPMVersionMinor());
return new TPMInfo(tpmMake, Short.valueOf(tpmVersionMajor),
Short.valueOf(tpmVersionMinor), Short.valueOf(tpmVersionRevMajor),
Short.valueOf(tpmVersionRevMinor));
}
}
/**
* Method generates a TPM measurement white list baseline from a .csv file containing
* PCR measurement entries. An off-line PCR measurement baseline process is
* used to generate the .csv file. TPM measurement records are expected to
* adhere to the following record structure with a comma separating them:
* <ul>
* <li>PCR index</li>
* <li>SHA-1 hash</li>
* </ul>
*
* @param baselineName
* of baseline to generate
* @param in
* is input stream containing PCR measurement entries
* @return tpm baseline
* @throws IOException
* if error encountered reading data from input stream
* @throws ParseException
* if error encountered parsing data
* @throws TPMBaselineGeneratorException
* if error encountered when retrieving measurement entries from
* input stream
*/
public final TpmWhiteListBaseline generateWhiteListBaselineFromCSVFile(
final String baselineName, final InputStream in)
throws IOException, ParseException, TPMBaselineGeneratorException {
checkBaselineCreationArgs(baselineName, in);
TpmWhiteListBaseline tpmBaseline = parseWhiteListCsvFile(baselineName, in);
LOGGER.debug("measurement baseline initialized: {}", tpmBaseline);
return tpmBaseline;
}
/**
* Method generates a TPM measurement black list baseline from a .csv file containing
* PCR measurement entries. An off-line PCR measurement baseline process is
* used to generate the .csv file. TPM measurement records are expected to
* adhere to the following record structure with a comma separating them:
* <ul>
* <li>PCR index</li>
* <li>SHA-1 hash</li>
* </ul>
*
* @param baselineName
* of baseline to generate
* @param in
* is input stream containing PCR measurement entries
* @return tpm baseline
* @throws IOException
* if error encountered reading data from input stream
* @throws ParseException
* if error encountered parsing data
* @throws TPMBaselineGeneratorException
* if error encountered when retrieving measurement entries from
* input stream
*/
public TpmBlackListBaseline generateBlackListBaselineFromCSVFile(final String baselineName,
final InputStream in) throws ParseException, TPMBaselineGeneratorException, IOException {
checkBaselineCreationArgs(baselineName, in);
TpmBlackListBaseline tpmBaseline = parseBlackListCsvFile(baselineName, in);
LOGGER.debug("measurement baseline initialized: {}", tpmBaseline);
return tpmBaseline;
}
private void checkBaselineCreationArgs(final String baselineName, final InputStream in) {
if (baselineName == null) {
LOGGER.error("null argument: baselineName");
throw new NullPointerException("baselineName");
}
if (in == null) {
LOGGER.error("null argument: in");
throw new NullPointerException("in");
}
}
/**
* Generates a TPM baseline from a <code>IntegrityReport</code>. This
* extracts the PCR composite object from the report and verifies that valid
* number of TPM PCRs are provided. The method creates a new
* <code>TPMBaseline</code> object and then uses each PCR value obtained
* from the PCR composite object to add it to the <code>TPMBaseline</code>
* object.
*
* @param baselineName
* name of baseline to be created
* @param report
* integrity report that containing PCR values for baseline
* @return baseline that contains the PCR values from the report
* @throws NullPointerException
* if either baselineName or report parameters are null.
*/
public final TpmWhiteListBaseline generateBaselineFromIntegrityReport(
final String baselineName, final IntegrityReport report)
throws NullPointerException {
if (baselineName == null) {
LOGGER.error("null argument: baselineName");
throw new NullPointerException("baselineName");
}
if (report == null) {
LOGGER.error("null argument: report");
throw new NullPointerException("report");
}
final TpmWhiteListBaseline baseline = new TpmWhiteListBaseline(baselineName);
LOGGER.debug("generating TPM baseline from report");
if (report.contains(TPMReport.class)) {
final TPMReport tpmReport = report.extractReport(TPMReport.class);
final List<TPMMeasurementRecord> pcrs = tpmReport.getTPMMeasurementRecords();
for (TPMMeasurementRecord p : pcrs) {
int id = p.getPcrId();
final Digest sha1 = p.getHash();
baseline.addToBaseline(new TPMMeasurementRecord(id, sha1));
}
} else {
LOGGER.debug(String.format(
"In generateBaselineFromIntegrityReport of %s, "
+ "the IntegrityReport did not include a TPMReport",
getClass().getSimpleName()));
}
LOGGER.debug("retrieving Device Info data from report");
if (report.contains(DeviceInfoReport.class)) {
Report reportBuffer = report.extractReport(DeviceInfoReport.class);
final DeviceInfoReport diReport = (DeviceInfoReport) reportBuffer;
baseline.setFirmwareInfo(diReport.getFirmwareInfo());
baseline.setHardwareInfo(diReport.getHardwareInfo());
baseline.setOSInfo(diReport.getOSInfo());
baseline.setTPMInfo(diReport.getTPMInfo());
} else {
LOGGER.debug(String.format(
"In generateBaselineFromIntegrityReport of %s, "
+ "the IntegrityReport did not include a DeviceInfoReport",
getClass().getSimpleName()));
}
return baseline;
}
/**
* Generates a TPM whitelist baseline from a <code>IntegrityReport</code>. This
* extracts the PCR composite object from the report and verifies that valid
* number of TPM PCRs are provided. The method creates a new
* <code>TPMBaseline</code> object and then uses each PCR value obtained
* from the PCR composite object to add it to the <code>TPMBaseline</code>
* object.
* @param baselineName name of baseline to be created
* @param report integrity report that containing PCR values for baseline
* @param kernelPcrMask the kernel PCR mask from a TPM Policy
* @return baseline that contains the PCR values from the report and the device info
* @throws NullPointerException if either baselineName or report parameters are null.
*/
public final TpmWhiteListBaseline generateWhiteListBaselineOnKernelUpdate(
final String baselineName, final IntegrityReport report, final int kernelPcrMask)
throws NullPointerException {
if (baselineName == null) {
LOGGER.error("null argument: baselineName");
throw new NullPointerException("baselineName");
}
LOGGER.debug("generating TPM baseline on kernel update from report");
// Generate a temporary reference baseline from the given report. The name can be blank.
final TpmWhiteListBaseline referenceBaseline =
generateBaselineFromIntegrityReport("", report);
final Set<TPMMeasurementRecord> records = referenceBaseline.getPcrRecords();
final TpmWhiteListBaseline newBaseline = new TpmWhiteListBaseline(baselineName);
// Copy each of the kernel PCR values from the reference baseline to the new one
for (final TPMMeasurementRecord record : records) {
final int shifted = 1 << record.getPcrId();
if ((shifted & kernelPcrMask) == shifted) {
newBaseline.addToBaseline(record);
}
}
LOGGER.debug("retrieving Device Info data from referenced baseline");
// Copy the criteria from the device info report corroborated the kernel update.
final OSInfo referenceOSInfo = referenceBaseline.getOSInfo();
final HashMap<TPMBaselineFields, String> map = new HashMap<>();
map.put(TPMBaselineFields.OS_NAME, referenceOSInfo.getOSName());
map.put(TPMBaselineFields.OS_VERSION, referenceOSInfo.getOSVersion());
final OSInfo osInfo = TPMBaselineFields.toOSInfo(map, new OSInfo());
newBaseline.setOSInfo(osInfo);
return newBaseline;
}
/**
* Provides a standard name for baselines that are automatically created during a kernel
* update event.
* @param report IntegrityReport from which a kernel update was detected.
* @return String of the name that can be used for a corresponding TPM baseline.
* @throws NullPointerException If the parameter is null.
* @throws TPMBaselineGeneratorException If the report doesn't contain a device info report.
*/
public final String generateNameForKernelUpdateBaseline(final IntegrityReport report)
throws NullPointerException, TPMBaselineGeneratorException {
LOGGER.debug("retrieving Device Info data to create kernel update baseline name");
if (report == null) {
LOGGER.error("null argument: report");
throw new NullPointerException("report");
}
if (report.contains(DeviceInfoReport.class)) {
final DeviceInfoReport diReport = report.extractReport(DeviceInfoReport.class);
final OSInfo osInfo = diReport.getOSInfo();
return String.format(KERNEL_UPDATE_BASELINE_NAME,
osInfo.getOSName(), osInfo.getOSVersion());
}
final String msg = "The integrity report did not contain a device info report."
+ " Investigate how the appraiser got this far.";
throw new TPMBaselineGeneratorException(msg);
}
/**
* Method parses a .csv file containing TPM measurement entries and
* initializes and returns a new TPM baseline object.
*
* @param baselineName the name of the baseline.
* @param inStream
* containing file contents to be read. inStream is closed by
* this method.
* @return a TPM baseline initialized with measurement entries imported from
* .csv TPM baseline file
* @exception NullPointerException
* if baselineName is a null value
* @exception NullPointerException
* if inStream is a null value
* @throws IOException
* if error encountered reading data from input stream
* @throws ParseException
* if error encountered parsing data
* @throws TPMBaselineGeneratorException
* if error encountered when retrieving measurement entries from
* input stream
*/
private TpmWhiteListBaseline parseWhiteListCsvFile(final String baselineName,
final InputStream inStream) throws IOException, ParseException,
TPMBaselineGeneratorException {
TpmWhiteListBaseline baseline = new TpmWhiteListBaseline(baselineName);
parseBaseline(baselineName, inStream, baseline);
return baseline;
}
private TpmBlackListBaseline parseBlackListCsvFile(final String baselineName,
final InputStream inStream) throws IOException, ParseException,
TPMBaselineGeneratorException {
TpmBlackListBaseline baseline = new TpmBlackListBaseline(baselineName);
parseBaseline(baselineName, inStream, baseline);
return baseline;
}
private void parseBaseline(final String baselineName, final InputStream inStream,
final TPMBaseline baseline)
throws IOException, TPMBaselineGeneratorException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
inStream, "UTF8"));
String dataRow = reader.readLine();
HashMap<TPMBaselineFields, String> fieldMap = new HashMap<>();
try {
while (dataRow != null && dataRow.matches(VALID_REGEX)) {
String[] dataArray = dataRow.split(",", 2); // looking for two values per row
if (dataArray.length != 2) { // could be 1, if there were no commas
final String msg = String.format(
"invalid number of fields: %d", dataArray.length);
LOGGER.error(msg);
throw new TPMBaselineGeneratorException(msg);
} else if (!dataArray[1].matches(VALID_REGEX)) {
final String msg = String.format("One record contained invalid data"
+ "while parsing a CSV file for TPM Baseline '%s'.", baselineName);
LOGGER.error(msg);
throw new TPMBaselineGeneratorException(msg);
}
// Measurements will start with a number,
// Device info records will start with the field name of the device info to set
try {
TPMBaselineFields field =
TPMBaselineFields.valueOf(dataArray[0].toUpperCase());
fieldMap.put(field, StringEscapeUtils.unescapeCsv(dataArray[1]));
} catch (IllegalArgumentException e) {
// Wasn't in the list of fields, treat it as a measurement record
int id = Integer.parseInt(dataArray[0]);
final byte[] sha1Bytes
= Hex.decodeHex(dataArray[1].toCharArray());
final Digest sha1 = new Digest(DigestAlgorithm.SHA1, sha1Bytes);
baseline.addToBaseline(new TPMMeasurementRecord(id, sha1));
}
dataRow = reader.readLine();
}
// Use the map to overwrite new device info data
baseline.setFirmwareInfo(
TPMBaselineFields.toFirmwareInfo(fieldMap, baseline.getFirmwareInfo()));
baseline.setHardwareInfo(
TPMBaselineFields.toHardwareInfo(fieldMap, baseline.getHardwareInfo()));
baseline.setOSInfo(
TPMBaselineFields.toOSInfo(fieldMap, baseline.getOSInfo()));
baseline.setTPMInfo(
TPMBaselineFields.toTPMInfo(fieldMap, baseline.getTPMInfo()));
if (baseline.isEmpty()) {
throw new TPMBaselineGeneratorException("TPM baseline is empty!");
}
//Checks that PCR values are actual
} catch (NumberFormatException nfe) {
String recordInfo = "";
if (dataRow != null) {
recordInfo = " record: \"" + dataRow + "\"";
}
String msg = "TPMBaselineGenerator.parseWhiteListCsvFile: Error when attempting to "
+ "parse a number in CSV file" + recordInfo + ".";
LOGGER.error(msg + "\n" + nfe.getMessage());
throw new TPMBaselineGeneratorException(msg);
} catch (IllegalArgumentException iae) {
//Removes the Exception header to hide it from the user explanation
LOGGER.error(iae.getMessage());
String message = iae.getMessage().substring(
iae.getMessage().indexOf(":") + 1);
String error = "Baseline import failed due to "
+ message.replaceAll("(.*):(.*)", "$1");
throw new TPMBaselineGeneratorException(error);
} catch (Exception ex) {
LOGGER.error(ex.getMessage());
throw new TPMBaselineGeneratorException("Error when attempting to "
+ "parse CSV file. Is file formatted correctly for a TPM"
+ " Baseline?");
} finally {
reader.close();
}
}
}

View File

@ -1,46 +0,0 @@
package hirs.tpm;
/**
* This class represents an <code>Exception</code> generated by
* <code>CreateTPMBaseline</code>.
*/
public class TPMBaselineGeneratorException extends Exception {
private static final long serialVersionUID = 8850867303391694668L;
/**
* Creates a new <code>CreateTPMBaselineException</code> that has the
* message <code>msg</code>.
*
* @param msg
* exception message
*/
TPMBaselineGeneratorException(final String msg) {
super(msg);
}
/**
* Creates a new <code>CreateTPMBaselineException</code> that wraps the
* given <code>Throwable</code>.
*
* @param t
* root cause
*/
TPMBaselineGeneratorException(final Throwable t) {
super(t);
}
/**
* Creates a new <code>CreateTPMBaselineException</code> that has the
* message <code>msg</code> and wraps the root cause.
*
* @param msg
* exception message
* @param t
* root cause
*/
TPMBaselineGeneratorException(final String msg, final Throwable t) {
super(msg, t);
}
}

View File

@ -1,5 +1,17 @@
package hirs.tpm.eventlog;
import hirs.data.persist.AbstractDigest;
import hirs.data.persist.Digest;
import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.tpm.eventlog.events.EvConstants;
import hirs.tpm.eventlog.uefi.UefiConstants;
import hirs.utils.HexUtils;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
@ -10,20 +22,6 @@ import java.security.cert.CertificateException;
import java.util.Collection;
import java.util.LinkedHashMap;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import hirs.data.persist.AbstractDigest;
import hirs.data.persist.Digest;
import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.tpm.eventlog.events.EvConstants;
import hirs.tpm.eventlog.uefi.UefiConstants;
import hirs.utils.HexUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Class for handling different formats of TCG Event logs.
*/
@ -178,8 +176,8 @@ public final class TCGEventLog {
* @param name name to call the TPM Baseline
* @return whitelist baseline
*/
public TpmWhiteListBaseline createTPMBaseline(final String name) {
TpmWhiteListBaseline baseline = new TpmWhiteListBaseline(name);
public void createTPMBaseline(final String name) {
// TpmWhiteListBaseline baseline = new TpmWhiteListBaseline(name);
TPMMeasurementRecord record;
String pcrValue;
for (int i = 0; i < PCR_COUNT; i++) {
@ -194,9 +192,9 @@ public final class TCGEventLog {
final Digest hash = new Digest(DigestAlgorithm.SHA256, hexValue);
record = new TPMMeasurementRecord(i, hash);
}
baseline.addToBaseline(record);
// baseline.addToBaseline(record);
}
return baseline;
// return baseline;
}
/**

View File

@ -1,6 +1,5 @@
package hirs;
import hirs.data.persist.IMAReport;
import org.testng.Assert;
import org.testng.annotations.Test;

View File

@ -3,8 +3,6 @@ package hirs.appraiser;
import hirs.data.persist.Digest;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.data.persist.baseline.IMABaselineRecord;
import hirs.data.persist.IMAMeasurementRecord;
import hirs.data.persist.IMAReport;
import hirs.data.persist.baseline.ImaIgnoreSetBaseline;
import hirs.data.persist.baseline.SimpleImaBaseline;
import org.apache.commons.codec.binary.Base64;

View File

@ -13,7 +13,6 @@ import java.util.Set;
import java.util.UUID;
import java.util.HashSet;
import hirs.tpm.TPMBaselineGenerator;
import org.hibernate.Session;
import org.testng.Assert;

View File

@ -2,7 +2,6 @@ package hirs.ima;
import hirs.data.persist.DeviceInfoReport;
import hirs.data.persist.Digest;
import hirs.data.persist.ImaBlacklistRecord;
import hirs.data.persist.ImaBlacklistRecordTest;
import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.baseline.IMABaselineRecord;
@ -14,8 +13,6 @@ import hirs.data.persist.info.FirmwareInfo;
import hirs.data.persist.info.HardwareInfo;
import hirs.data.persist.info.OSInfo;
import hirs.data.persist.info.TPMInfo;
import hirs.tpm.TPMBaselineGenerator;
import hirs.tpm.TPMBaselineGeneratorException;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;

View File

@ -6,7 +6,6 @@ import org.testng.annotations.Test;
import java.io.IOException;
import java.io.InputStream;
import hirs.data.persist.baseline.ImaBlacklistBaseline;
import hirs.data.persist.ImaBlacklistRecord;
/**
* Tests that the {@link ImaBlacklistBaselineGenerator} works as expected.

View File

@ -1,6 +1,5 @@
package hirs.ima;
import hirs.data.persist.IMAReport;
import hirs.data.persist.baseline.SimpleImaBaseline;
import hirs.data.persist.DeviceInfoReport;
import hirs.data.persist.Digest;

View File

@ -2,7 +2,6 @@ package hirs.ima.matching;
import hirs.data.persist.Digest;
import hirs.data.persist.baseline.IMABaselineRecord;
import hirs.data.persist.IMAMeasurementRecord;
import hirs.data.persist.enums.ReportMatchStatus;
import hirs.data.persist.baseline.SimpleImaBaseline;
import hirs.data.persist.SimpleImaBaselineTest;

View File

@ -3,7 +3,6 @@ package hirs.ima.matching;
import hirs.data.persist.Digest;
import hirs.data.persist.DigestTest;
import hirs.data.persist.baseline.IMABaselineRecord;
import hirs.data.persist.IMAMeasurementRecord;
import hirs.data.persist.baseline.ImaAcceptableRecordBaseline;
import hirs.data.persist.enums.ReportMatchStatus;
import hirs.data.persist.baseline.SimpleImaBaseline;

View File

@ -3,7 +3,6 @@ package hirs.persist;
import hirs.data.persist.Device;
import hirs.data.persist.DeviceGroup;
import hirs.data.persist.DeviceState;
import hirs.data.persist.IMADeviceState;
import hirs.data.persist.SpringPersistenceTest;
import hirs.data.persist.TPMDeviceState;
import hirs.data.persist.TPMReport;

View File

@ -2,7 +2,6 @@ package hirs.persist;
import hirs.data.persist.Device;
import hirs.data.persist.DeviceGroup;
import hirs.data.persist.IMADeviceState;
import hirs.data.persist.SpringPersistenceTest;
import org.testng.Assert;

View File

@ -8,8 +8,6 @@ import hirs.data.persist.enums.DigestAlgorithm;
import hirs.data.persist.enums.ExamineState;
import hirs.data.persist.info.FirmwareInfo;
import hirs.data.persist.info.HardwareInfo;
import hirs.data.persist.IMAMeasurementRecord;
import hirs.data.persist.IMAReport;
import hirs.data.persist.IntegrityReport;
import hirs.data.persist.info.NetworkInfo;
import hirs.data.persist.info.OSInfo;

View File

@ -3,7 +3,6 @@ package hirs.persist;
import hirs.data.persist.baseline.Baseline;
import hirs.data.persist.Digest;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.data.persist.ImaBlacklistRecord;
import hirs.data.persist.baseline.ImaBlacklistBaseline;
import java.io.UnsupportedEncodingException;

View File

@ -20,7 +20,6 @@ import hirs.data.persist.Digest;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.data.persist.info.FirmwareInfo;
import hirs.data.persist.info.HardwareInfo;
import hirs.data.persist.IMAReport;
import hirs.data.persist.IntegrityReport;
import hirs.data.persist.info.OSInfo;
import hirs.data.persist.TPMReport;