mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
commit
2e1922be82
@ -64,8 +64,8 @@ file.reference.postgresql-42.3.5.jar=release/modules/ext/postgresql-42.3.5.jar
|
||||
file.reference.Rejistry-1.1-SNAPSHOT.jar=release/modules/ext/Rejistry-1.1-SNAPSHOT.jar
|
||||
file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbinding-AllPlatforms.jar
|
||||
file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
|
||||
file.reference.sleuthkit-4.11.1.jar=release/modules/ext/sleuthkit-4.11.1.jar
|
||||
file.reference.sleuthkit-caseuco-4.11.1.jar=release/modules/ext/sleuthkit-caseuco-4.11.1.jar
|
||||
file.reference.sleuthkit-4.12.0.jar=release/modules/ext/sleuthkit-4.12.0.jar
|
||||
file.reference.sleuthkit-caseuco-4.12.0.jar=release/modules/ext/sleuthkit-caseuco-4.12.0.jar
|
||||
file.reference.snakeyaml-1.30.jar=release/modules/ext/snakeyaml-1.30.jar
|
||||
file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar
|
||||
file.reference.spotbugs-annotations-4.6.0.jar=release/modules/ext/spotbugs-annotations-4.6.0.jar
|
||||
|
@ -613,12 +613,12 @@
|
||||
<binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-4.11.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-4.11.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/sleuthkit-4.12.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-4.12.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.11.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.11.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.12.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.12.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/snakeyaml-1.30.jar</runtime-relative-path>
|
||||
|
@ -1,3 +1,3 @@
|
||||
<project name="TSK_VERSION">
|
||||
<property name="TSK_VERSION" value="4.11.1"/>
|
||||
<property name="TSK_VERSION" value="4.12.0"/>
|
||||
</project>
|
||||
|
@ -50,6 +50,15 @@
|
||||
<specification-version>10.24</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.sleuthkit.autopsy.corelibs</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>3</release-version>
|
||||
<specification-version>1.4</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.sleuthkit.autopsy.coretestlibs</code-name-base>
|
||||
<build-prerequisite/>
|
||||
|
@ -25,18 +25,33 @@ import java.awt.Toolkit;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DateFormat;
|
||||
import java.text.MessageFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.tree.TreePath;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
import org.netbeans.jellytools.MainWindowOperator;
|
||||
import org.netbeans.jellytools.NbDialogOperator;
|
||||
import org.netbeans.jellytools.WizardOperator;
|
||||
@ -59,6 +74,7 @@ import org.netbeans.jemmy.operators.JTreeOperator;
|
||||
import org.netbeans.jemmy.operators.JTreeOperator.NoSuchPathException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
|
||||
@ -68,6 +84,13 @@ public class AutopsyTestCases {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AutopsyTestCases.class.getName()); // DO NOT USE AUTOPSY LOGGER
|
||||
private long start;
|
||||
|
||||
// by default, how many minutes jemmy waits for a dialog to appear (default is 1 minute).
|
||||
private static final long DIALOG_FIND_TIMEOUT_MINUTES = 5;
|
||||
|
||||
static {
|
||||
Timeouts.setDefault("Waiter.WaitingTime", DIALOG_FIND_TIMEOUT_MINUTES * 60 * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the slashes in a file or directory path.
|
||||
@ -104,8 +127,9 @@ public class AutopsyTestCases {
|
||||
JButtonOperator jbo = new JButtonOperator(nbdo, 0); // the "New Case" button
|
||||
jbo.pushNoBlock();
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,8 +149,9 @@ public class AutopsyTestCases {
|
||||
start = System.currentTimeMillis();
|
||||
wo.btFinish().clickMouse();
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,8 +184,9 @@ public class AutopsyTestCases {
|
||||
comboBoxOperator.setSelectedItem("(GMT-5:00) America/New_York");
|
||||
wo.btNext().clickMouse();
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,8 +220,9 @@ public class AutopsyTestCases {
|
||||
fileChooserOperator.chooseFile(new File(getEscapedPath(System.getProperty("img_path"))).getName());
|
||||
wo.btNext().clickMouse();
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,8 +235,9 @@ public class AutopsyTestCases {
|
||||
logger.log(Level.INFO, "Add image took {0}ms", (System.currentTimeMillis() - start));
|
||||
wo.btFinish().clickMouse();
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,8 +262,9 @@ public class AutopsyTestCases {
|
||||
jbo1.pushNoBlock();
|
||||
logger.info("Pushed Global Settings button for hash lookup module in ingest job settings panel");
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,8 +302,9 @@ public class AutopsyTestCases {
|
||||
JButtonOperator jbo4 = new JButtonOperator(hashMainDialogOperator, "OK", 0);
|
||||
jbo4.pushNoBlock();
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,8 +323,9 @@ public class AutopsyTestCases {
|
||||
jbo1.pushNoBlock();
|
||||
logger.info("Pushed Global Settings button for keyword search module in ingest job settings panel");
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,8 +357,9 @@ public class AutopsyTestCases {
|
||||
new Timeout("pausing", 10000).sleep(); // let things catch up
|
||||
wo.btNext().clickMouse();
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,8 +379,9 @@ public class AutopsyTestCases {
|
||||
Random rand = new Random();
|
||||
new Timeout("pausing", 10000 + (rand.nextInt(15000) + 5000)).sleep();
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
|
||||
}
|
||||
@ -362,8 +395,9 @@ public class AutopsyTestCases {
|
||||
TreePath tp = jto.findPath(nodeNames);
|
||||
expandNodes(jto, tp);
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,8 +408,9 @@ public class AutopsyTestCases {
|
||||
JButtonOperator jbo = new JButtonOperator(mwo, "Generate Report");
|
||||
jbo.pushNoBlock();
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -409,8 +444,9 @@ public class AutopsyTestCases {
|
||||
new Timeout("pausing", 10000).sleep();
|
||||
System.setProperty("ReportStr", datenotime);
|
||||
} catch (TimeoutExpiredException ex) {
|
||||
screenshot("TimeoutScreenshot");
|
||||
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||
logSystemDiagnostics();
|
||||
screenshot("TimeoutScreenshot");
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,6 +492,7 @@ public class AutopsyTestCases {
|
||||
UserPreferences.setDatabaseConnectionInfo(connectionInfo);
|
||||
} catch (UserPreferencesException ex) {
|
||||
logger.log(Level.SEVERE, "Error saving case database connection info", ex); //NON-NLS
|
||||
logSystemDiagnostics();
|
||||
}
|
||||
//Solr Index settings
|
||||
UserPreferences.setIndexingServerHost(System.getProperty("solrHost"));
|
||||
@ -470,6 +507,7 @@ public class AutopsyTestCases {
|
||||
UserPreferences.setMessageServiceConnectionInfo(msgServiceInfo);
|
||||
} catch (UserPreferencesException ex) {
|
||||
logger.log(Level.SEVERE, "Error saving messaging service connection info", ex); //NON-NLS
|
||||
logSystemDiagnostics();
|
||||
}
|
||||
|
||||
UserPreferences.setZkServerHost(System.getProperty("zooKeeperHost"));
|
||||
@ -484,6 +522,253 @@ public class AutopsyTestCases {
|
||||
}
|
||||
} catch (NoSuchPathException ne) {
|
||||
logger.log(Level.SEVERE, "Error expanding tree path", ne);
|
||||
logSystemDiagnostics();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void logSystemDiagnostics() {
|
||||
logger.log(Level.INFO, getSystemDiagnostics());
|
||||
}
|
||||
|
||||
private static final String NEWLINE = System.lineSeparator();
|
||||
|
||||
private static final int TOP_NUM = 10;
|
||||
|
||||
private static Set<String> IGNORED_PROCESSES = Stream.of("_Total", "Idle", "Memory Compression").collect(Collectors.toSet());
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return A string of system diagnostic information.
|
||||
*
|
||||
* NOTE: currently only works for windows.
|
||||
*/
|
||||
private static String getSystemDiagnostics() {
|
||||
if (PlatformUtil.isWindowsOS()) {
|
||||
try {
|
||||
List<Map<String, String>> processPerformance = getWmicTable("wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime,IOReadBytesPerSec,IOWriteBytesPerSec,WorkingSetPeak").stream()
|
||||
.filter(obj -> !IGNORED_PROCESSES.contains(obj.get("name")))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Pair<String, Long>> cpuUsageProcesses = getKeyValLimited(processPerformance, "name", "percentprocessortime");
|
||||
List<Pair<String, Long>> memUsageProcesses = getKeyValLimited(processPerformance, "name", "workingsetpeak");
|
||||
|
||||
List<Triple<String, Long, Long>> ioProcesses = getFilteredLimited(
|
||||
processPerformance,
|
||||
obj -> {
|
||||
String key = obj.get("name");
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return Triple.of(key, Long.parseLong(obj.get("ioreadbytespersec")), Long.parseLong(obj.get("iowritebytespersec")));
|
||||
} catch (NumberFormatException | NullPointerException ex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
},
|
||||
Comparator.comparing(pr -> -(pr.getMiddle() + pr.getRight())));
|
||||
|
||||
String cpuLoad = getWmicString("wmic cpu get loadpercentage", "loadpercentage");
|
||||
String cpuCores = getWmicString("wmic cpu get numberofcores", "numberofcores");
|
||||
String freePhysicalMemory = getWmicString("wmic OS get FreeSpaceInPagingFiles", "freespaceinpagingfiles"); // in kb
|
||||
String totalPhysicalMemory = getWmicString("wmic ComputerSystem get TotalPhysicalMemory", "totalphysicalmemory"); // bytes
|
||||
String memUsage;
|
||||
try {
|
||||
double freeMemMb = Double.parseDouble(freePhysicalMemory) / 1000;
|
||||
double totalMemMb = Double.parseDouble(totalPhysicalMemory) / 1000 / 1000;
|
||||
memUsage = MessageFormat.format("Free Physical Memory: {0,number,#.##}MB and total physical: {1,number,#.##}MB", freeMemMb, totalMemMb);
|
||||
} catch (NumberFormatException ex) {
|
||||
memUsage = MessageFormat.format("Free Physical Memory: \"{0}\" and total physical: \"{1}\"", freePhysicalMemory, totalPhysicalMemory);
|
||||
}
|
||||
|
||||
List<Triple<String, Long, String>> networkStatus = getFilteredLimited(
|
||||
getWmicTable("wmic path win32_networkadapter where \"netconnectionstatus = 2 OR NOT errordescription IS NULL\" get netconnectionid, name, speed, maxspeed, errordescription"),
|
||||
(Map<String, String> obj) -> {
|
||||
String name = obj.get("netconnectionid");
|
||||
if (StringUtils.isBlank(name)) {
|
||||
name = obj.get("name");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String errorDescription = obj.get("errordescription");
|
||||
|
||||
Long speed = 0L;
|
||||
try {
|
||||
speed = Long.parseLong(obj.get("speed"));
|
||||
} catch (NumberFormatException | NullPointerException ex) {
|
||||
}
|
||||
|
||||
return Triple.of(name, speed, errorDescription);
|
||||
},
|
||||
(a, b) -> StringUtils.compareIgnoreCase(a.getLeft(), b.getRight()));
|
||||
|
||||
List<Pair<String, Long>> diskStatus = getKeyValLimited(
|
||||
getWmicTable("wmic path Win32_PerfFormattedData_PerfDisk_LogicalDisk get AvgDiskQueueLength,Name").stream()
|
||||
.filter(obj -> !IGNORED_PROCESSES.contains(obj.get("name")))
|
||||
.collect(Collectors.toList()),
|
||||
"name",
|
||||
"avgdiskqueuelength");
|
||||
|
||||
return "SYSTEM DIAGNOSTICS:" + NEWLINE
|
||||
+ MessageFormat.format("CPU Load Percentage: {0}% with {1} cores", cpuLoad, cpuCores) + NEWLINE
|
||||
+ MessageFormat.format("Memory Usage: {0}", memUsage) + NEWLINE
|
||||
+ "Disk Usage (disk to average disk queue length): " + NEWLINE
|
||||
+ diskStatus.stream().map(pr -> pr.getKey() + ": " + pr.getValue()).collect(Collectors.joining(NEWLINE)) + NEWLINE
|
||||
+ NEWLINE
|
||||
+ "Network Status (of only connected or error): " + NEWLINE
|
||||
+ networkStatus.stream().map(obj -> {
|
||||
String errorString = StringUtils.isBlank(obj.getRight()) ? "" : MessageFormat.format(" (error: {0})", obj.getRight());
|
||||
return MessageFormat.format("{0}: {1,number,#.##}MB/S possible {2}", obj.getLeft(), ((double) obj.getMiddle()) / 1000 / 1000, errorString);
|
||||
}).collect(Collectors.joining(NEWLINE)) + NEWLINE
|
||||
+ NEWLINE
|
||||
+ "CPU consuming processes: " + NEWLINE
|
||||
+ cpuUsageProcesses.stream().map(pr -> MessageFormat.format("{0}: {1}%", pr.getKey(), pr.getValue())).collect(Collectors.joining(NEWLINE)) + NEWLINE
|
||||
+ NEWLINE
|
||||
+ "Memory consuming processes (working set peak): " + NEWLINE
|
||||
+ memUsageProcesses.stream()
|
||||
.map(
|
||||
pr -> MessageFormat.format(
|
||||
"{0}: {1,number,#.##}MB",
|
||||
pr.getKey(),
|
||||
((double) pr.getValue()) / 1000 / 1000
|
||||
)
|
||||
)
|
||||
.collect(Collectors.joining(NEWLINE)) + NEWLINE
|
||||
+ NEWLINE
|
||||
+ "I/O consuming processes (read/write): " + NEWLINE
|
||||
+ ioProcesses.stream()
|
||||
.map(
|
||||
pr -> MessageFormat.format(
|
||||
"{0}: {1,number,#.##}MB/{2,number,#.##}MB", pr.getLeft(),
|
||||
((double) pr.getMiddle()) / 1000 / 1000,
|
||||
((double) pr.getRight()) / 1000 / 1000
|
||||
)
|
||||
)
|
||||
.collect(Collectors.joining(NEWLINE)) + NEWLINE;
|
||||
} catch (Throwable ex) {
|
||||
return "SYSTEM DIAGNOSTICS:" + NEWLINE
|
||||
+ "Encountered IO exception: " + ex.getMessage() + NEWLINE;
|
||||
}
|
||||
|
||||
} else {
|
||||
return "System diagnostics only implemented for windows at this time.";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pair of a string key and long number value limited to TOP_NUM of the highest number values.
|
||||
* @param objects The list of objects.
|
||||
* @param keyId The id of the key in the map.
|
||||
* @param valId The id of the value in the map.
|
||||
* @return The highest valued key value pairs.
|
||||
*/
|
||||
private static List<Pair<String, Long>> getKeyValLimited(List<Map<String, String>> objects, String keyId, String valId) {
|
||||
return getFilteredLimited(
|
||||
objects,
|
||||
obj -> {
|
||||
String key = obj.get(keyId);
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return Pair.of(key, Long.parseLong(obj.get(valId)));
|
||||
} catch (NumberFormatException | NullPointerException ex) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
Comparator.comparing(pr -> -pr.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of a given type limited to TOP_NUM of the first values.
|
||||
* @param objects The objects to sort and filter.
|
||||
* @param keyObjMapper Maps the list of map objects to the new new value.
|
||||
* @param comparator Comparator determining first values.
|
||||
* @return The list capped at TOP_NUM.
|
||||
*/
|
||||
private static <T> List<T> getFilteredLimited(List<Map<String, String>> objects, Function<Map<String, String>, T> keyObjMapper, Comparator<T> comparator) {
|
||||
return objects.stream()
|
||||
.map(keyObjMapper)
|
||||
.filter(a -> a != null)
|
||||
.sorted(comparator)
|
||||
.limit(TOP_NUM)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command line entry returning standard output.
|
||||
* @param cmd The command.
|
||||
* @return The standard output.
|
||||
* @throws IOException
|
||||
*/
|
||||
private static String getProcStdOut(String... cmd) throws IOException {
|
||||
ProcessBuilder pb = new ProcessBuilder(cmd);
|
||||
String output = IOUtils.toString(pb.start().getInputStream(), StandardCharsets.UTF_8);
|
||||
return output;
|
||||
}
|
||||
|
||||
// matches key=value
|
||||
private static final Pattern EQUALS_PATTERN = Pattern.compile("^([^=]*)=(.*)$");
|
||||
|
||||
/**
|
||||
* Returns a list of maps mapping the wmic header column (lower cased) to
|
||||
* the value for the row.
|
||||
*
|
||||
* @param cmd The wmic command to run.
|
||||
*
|
||||
* @return The list of rows.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private static List<Map<String, String>> getWmicTable(String cmd) throws IOException {
|
||||
String stdOut = getProcStdOut("cmd", "/c", cmd + " /format:list");
|
||||
|
||||
List<Map<String, String>> rows = new ArrayList<>();
|
||||
Map<String, String> curObj = new HashMap<>();
|
||||
for (String line : stdOut.split("\\r?\\n")) {
|
||||
// if line, try to parse as key=value
|
||||
if (StringUtils.isNotBlank(line)) {
|
||||
Matcher matcher = EQUALS_PATTERN.matcher(line);
|
||||
if (matcher.find()) {
|
||||
String key = matcher.group(1).trim().toLowerCase();
|
||||
String value = matcher.group(2).trim();
|
||||
curObj.put(key, value);
|
||||
}
|
||||
// if no line and the object has keys, we have finished an entry, add it to the list.
|
||||
} else if (!curObj.isEmpty()) {
|
||||
rows.add(curObj);
|
||||
curObj = new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
if (!curObj.isEmpty()) {
|
||||
rows.add(curObj);
|
||||
curObj = new HashMap<>();
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string from a wmic query.
|
||||
* @param wmicQuery The wmic query.
|
||||
* @param key The key column to return.
|
||||
* @return The first row's value for the given key.
|
||||
* @throws IOException
|
||||
*/
|
||||
private static String getWmicString(String wmicQuery, String key) throws IOException {
|
||||
List<Map<String, String>> retVal = getWmicTable(wmicQuery);
|
||||
if (retVal != null && !retVal.isEmpty() && retVal.get(0) != null && retVal.get(0).get(key) != null) {
|
||||
return retVal.get(0).get(key);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ ActiveMQ is a messaging service that allows the Autopsy clients to communicate w
|
||||
|
||||
You will need:
|
||||
- 64-bit version of the Java 8 Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild (<a href="https://github.com/ojdkbuild/ojdkbuild/releases/download/java-1.8.0-openjdk-1.8.0.242-1.b08/java-1.8.0-openjdk-1.8.0.242-1.b08.ojdkbuild.windows.x86_64.msi"> Link to installer</a>)
|
||||
- Download ActiveMQ from: http://activemq.apache.org/download.html . Autopsy has been tested with ActiveMQ version 5.14.0.
|
||||
- Download ActiveMQ from: http://activemq.apache.org/download.html . Autopsy has been tested with ActiveMQ version 5.14.0. Note that newer versions will not work with Java 8.
|
||||
|
||||
|
||||
\section install_activemq_install Installation
|
||||
@ -29,7 +29,9 @@ If you need the JRE, install it with the default settings.
|
||||
|
||||
<li>Open the <i>conf\\activemq.xml</i> file in the extracted folder in a text editor and make the following changes:
|
||||
<ul>
|
||||
<li> Add <i>"schedulePeriodForDestinationPurge="10000""</i> to the _broker_ tag then add <i>"gcInactiveDestinations="true" inactiveTimoutBeforeGC="30000""</i> to the _policyEntry_ tag. This is highlighted in yellow below:
|
||||
<li> Add <i>"schedulePeriodForDestinationPurge="10000""</i> to the _broker_ tag</li>
|
||||
<li> Add <i>"gcInactiveDestinations="true" inactiveTimoutBeforeGC="30000""</i> to the _policyEntry_ tag.
|
||||
<li> These are both highlighted in yellow below:
|
||||
|
||||
\image html activeMQ_node_cleanup.png
|
||||
|
||||
@ -41,6 +43,8 @@ If you need the JRE, install it with the default settings.
|
||||
|
||||
<li>Install ActiveMQ as a service by navigating to the folder <i>bin\\win64</i>, right-clicking _InstallService.bat_, clicking _Run as administrator_, then click _Yes_.
|
||||
|
||||
<li>Add the bin\\win64\\wrapper.exe and java.exe (from the JRE) to the Windows firewall so that they can accept network communications.
|
||||
|
||||
<li>Start the ActiveMQ service by pressing _Start_, type _services.msc_, and press _Enter_. Find _ActiveMQ_ in the list and press the _Start the service_ link.
|
||||
|
||||
<li>ActiveMQ should now be installed and configured using the default credentials.
|
||||
@ -48,7 +52,7 @@ If you need the JRE, install it with the default settings.
|
||||
|
||||
\subsection install_activemq_test Testing
|
||||
|
||||
To test your installation, you can access the admin pages in your web browser via a URL like this: http://localhost:8161/admin.
|
||||
To test your installation, you can access the admin pages in your web browser (on the server) via a URL like this: http://localhost:8161/admin. NOTE that you cannot access this page from other hosts unless you go into jetty.xml and change org.apache.activemq.web.WebConsolePort so that host is 0.0.0.0 (and ensure that it is properly secured).
|
||||
|
||||
The default administrator username is _admin_ with a password of _admin_ and the default regular username is _user_ with a default password of _password_. You can change these passwords by following the instructions below.
|
||||
|
||||
@ -57,7 +61,7 @@ If you can see a page that looks like the following, it confirms that the Active
|
||||
\image html activemq.PNG
|
||||
<br><br>
|
||||
|
||||
You can confirm that your ActiveMQ installation is visible to other computers on the network by attempting to connect to a URL like the following (replacing the host name with that of the ActiveMQ computer) in a web browser: http://activemq-computer:61616
|
||||
You can also confirm that your ActiveMQ installation is visible to other computers on the network by attempting to connect to a URL like the following (replacing the host name with that of the ActiveMQ computer) in a web browser: http://activemq-computer:61616. This will not give you a nice web page, but will give you data from the server.
|
||||
|
||||
If you are unable to connect to this address:
|
||||
- Double check that the ActiveMQ service is running
|
||||
|
@ -40,7 +40,7 @@ To install PostgreSQL, perform the following steps:
|
||||
<br><br>
|
||||
\image html newPassword.PNG
|
||||
<br><br>
|
||||
- Check <i>"Can create databases"</i> on the <i>"Role Privileges"</i> tab.
|
||||
- For <i>"Role Privileges"</i>, give the user <i>"Can Login?"</i> and <i>"Can create databases"</i>.
|
||||
<br><br>
|
||||
\image html newRights.PNG
|
||||
<br><br>
|
||||
@ -86,7 +86,7 @@ To this:
|
||||
Note the removal of the leading number symbol-this uncomments that entry.
|
||||
<br><br>
|
||||
|
||||
4. Still in <i id="max_connections">"C:\Program Files\PostgreSQL\9.5\data\postgresql.conf"</i>, find the entry named _max_connections_ and set it to the number of suggested connections for your configuration. A rule of thumb is add 100 connections for each Automated Ingest Node and 100 connections for each Reviewer node you plan to have in the network. See the screenshot below.
|
||||
4. Still in <i id="max_connections">"C:\Program Files\PostgreSQL\9.5\data\postgresql.conf"</i>, find the entry named _max_connections_ and set it to the number of suggested connections for your configuration. A rule of thumb is 100 connections per each Automated Ingest node and reviewer node. See the screenshot below.
|
||||
<br><br>
|
||||
\image html maxConnections.PNG
|
||||
<br><br>
|
||||
@ -98,6 +98,8 @@ Note the removal of the leading number symbol-this uncomments that entry.
|
||||
\image html postgresqlinstall7.PNG
|
||||
<br><br>
|
||||
|
||||
6. Add the bin\\postgres.exe file to the Windows firewall to allow it to receive connections.
|
||||
|
||||
|
||||
\section install_post_test Testing
|
||||
|
||||
|
@ -114,6 +114,10 @@ Start the "Solr_8.6.3" service, and verify that the service status changes to "R
|
||||
|
||||
\image html solr_start_2.png
|
||||
|
||||
\subsection install_solr_security AntiVirus Settings
|
||||
|
||||
We have observed that Antivirus may detect strings in the Solr indexes as being malware. You should add the Solr data directory to the exclusion list for your security product. We saw this with Windows Defender.
|
||||
|
||||
\section install_solr_testing Testing
|
||||
|
||||
There are two tests that you should perform to confirm that the Solr machine is configured correctly.
|
||||
|
@ -1,14 +1,14 @@
|
||||
et-xmlfile==1.0.1
|
||||
gitdb==4.0.5
|
||||
GitPython==3.1.12
|
||||
jdcal==1.4.1
|
||||
jproperties==2.1.0
|
||||
lml==0.1.0
|
||||
openpyxl==3.0.6
|
||||
pyexcel==0.6.6
|
||||
pyexcel-io==0.6.4
|
||||
pyexcel-xlsx==0.6.0
|
||||
six==1.15.0
|
||||
smmap==3.0.4
|
||||
texttable==1.6.3
|
||||
XlsxWriter==1.3.7
|
||||
et-xmlfile>=1.1.0
|
||||
gitdb>=4.0.10
|
||||
GitPython>=3.1.29
|
||||
jdcal>=1.4.1
|
||||
jproperties>=2.1.1
|
||||
lml>=0.1.0
|
||||
openpyxl>=3.0.10
|
||||
pyexcel>=0.7.0
|
||||
pyexcel-io>=0.6.6
|
||||
pyexcel-xlsx>=0.6.0
|
||||
six>=1.16.0
|
||||
smmap>=5.0.0
|
||||
texttable>=1.6.7
|
||||
XlsxWriter>=3.0.3
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
# NOTE: update_sleuthkit_version.pl updates this value and relies
|
||||
# on it keeping the same name and whitespace. Don't change it.
|
||||
TSK_VERSION=4.11.1
|
||||
TSK_VERSION=4.12.0
|
||||
|
||||
|
||||
usage() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user