added files sets to standard sets

This commit is contained in:
Greg DiCristofaro 2020-06-02 09:51:01 -04:00
parent 555feb94f2
commit cb5af3e93a
7 changed files with 182 additions and 112 deletions

View File

@ -45,7 +45,7 @@ public final class FilesSet implements Serializable {
private final boolean ignoreKnownFiles; private final boolean ignoreKnownFiles;
private final boolean ignoreUnallocatedSpace; private final boolean ignoreUnallocatedSpace;
private final boolean readOnly; private final boolean standardSet;
private final int versionNumber; private final int versionNumber;
private final Map<String, Rule> rules = new HashMap<>(); private final Map<String, Rule> rules = new HashMap<>();
@ -75,13 +75,16 @@ public final class FilesSet implements Serializable {
* the set. * the set.
* @param ignoreUnallocatedSpace Whether or not to exclude unallocated space * @param ignoreUnallocatedSpace Whether or not to exclude unallocated space
* from the set. * from the set.
* @param readOnly Whether or not the FilesSet should be read only (if not it is editable). * @param standardSet Whether or not the FilesSet is considered a
* @param versionNumber The versionNumber for the FilesSet so that older versions can be replaced with newer versions. * standard interesting set file.
* @param versionNumber The versionNumber for the FilesSet so that
* older versions can be replaced with newer
* versions.
* @param rules The rules that define the set. May be null, * @param rules The rules that define the set. May be null,
* but a set with no rules is the empty set. * but a set with no rules is the empty set.
*/ */
public FilesSet(String name, String description, boolean ignoreKnownFiles, boolean ignoreUnallocatedSpace, Map<String, Rule> rules, public FilesSet(String name, String description, boolean ignoreKnownFiles, boolean ignoreUnallocatedSpace, Map<String, Rule> rules,
boolean readOnly, int versionNumber) { boolean standardSet, int versionNumber) {
if ((name == null) || (name.isEmpty())) { if ((name == null) || (name.isEmpty())) {
throw new IllegalArgumentException("Interesting files set name cannot be null or empty"); throw new IllegalArgumentException("Interesting files set name cannot be null or empty");
} }
@ -90,7 +93,7 @@ public final class FilesSet implements Serializable {
throw new IllegalArgumentException("version number must be >= 0"); throw new IllegalArgumentException("version number must be >= 0");
} }
this.readOnly = readOnly; this.standardSet = standardSet;
this.versionNumber = versionNumber; this.versionNumber = versionNumber;
this.name = name; this.name = name;
@ -103,23 +106,21 @@ public final class FilesSet implements Serializable {
} }
/** /**
* Returns whether or not the file set is read only. * @return Whether or not the FilesSet is considered a standard interesting
* @return Whether or not the file set is read only. * set file.
*/ */
boolean isReadOnly() { boolean isStandardSet() {
return readOnly; return standardSet;
} }
/** /**
* Returns he versionNumber for the FilesSet so that older versions can be replaced with newer versions. * @return The versionNumber for the FilesSet so that older versions can be
* @return The versionNumber for the FilesSet so that older versions can be replaced with newer versions. * replaced with newer versions.
*/ */
int getVersionNumber() { int getVersionNumber() {
return versionNumber; return versionNumber;
} }
/** /**
* Gets the name of this interesting files set. * Gets the name of this interesting files set.
* *
@ -673,7 +674,6 @@ public final class FilesSet implements Serializable {
* To ensure compatibility with existing serialized configuration * To ensure compatibility with existing serialized configuration
* settings, this class cannot have a 'serialVersionUID'. * settings, this class cannot have a 'serialVersionUID'.
*/ */
private final TextMatcher textMatcher; private final TextMatcher textMatcher;
/** /**
@ -832,7 +832,6 @@ public final class FilesSet implements Serializable {
* To ensure compatibility with existing serialized configuration * To ensure compatibility with existing serialized configuration
* settings, this class cannot have a 'serialVersionUID'. * settings, this class cannot have a 'serialVersionUID'.
*/ */
private final static long SECS_PER_DAY = 60 * 60 * 24; private final static long SECS_PER_DAY = 60 * 60 * 24;
private int daysIncluded; private int daysIncluded;

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<INTERESTING_FILE_SETS>
<INTERESTING_FILE_SET description="Identifies installed cloud storage applications" ignoreKnown="false" name="Cloud Storage">
<NAME name="CloudMe" regex="false" typeFilter="file">CloudMe.exe</NAME>
<NAME name="Resilio" regex="false" typeFilter="file">Resilio Sync.exe</NAME>
<NAME name="pCloud" regex="false" typeFilter="file">pcloud.exe</NAME>
<NAME name="Slack" regex="false" typeFilter="file">slack.exe</NAME>
<NAME name="iCloud Drive" regex="false" typeFilter="file">iCloudDrive.exe</NAME>
<NAME name="Google Stream" regex="false" typeFilter="file">GoogleDriveFS.exe</NAME>
<NAME name="GoodSync" regex="false" typeFilter="file">goodsync.exe</NAME>
<NAME name="Synqion" regex="false" typeFilter="file">synqion.exe</NAME>
<NAME name="NextCloud" regex="false" typeFilter="file">nextcloud.exe</NAME>
<NAME name="OneDrive Windows App" regex="false" typeFilter="file">microsoft.microsoftskydrive.exe</NAME>
<NAME name="Carbonite Safe Server" regex="false" typeFilter="file">CloudScheduler.exe</NAME>
<NAME name="Google Drive" regex="false" typeFilter="file">googledrivesync.exe</NAME>
<NAME name="DropBox Installer" regex="false" typeFilter="file">dropbox.exe</NAME>
<NAME name="SugarSync" regex="false" typeFilter="file">sugarsync.exe</NAME>
<NAME name="Carbonite" regex="false" typeFilter="file">carboniteUI.exe</NAME>
<NAME name="OwnCloud" regex="false" typeFilter="file">owncloud.exe</NAME>
<NAME name="Adobe Creative Cloud" regex="false" typeFilter="file">creative cloud.exe</NAME>
<NAME name="DropBox Windows App" regex="false" typeFilter="file">DropboxUniversal.exe </NAME>
<NAME name="MEGA Privacy Windows App" regex="false" typeFilter="file">MegaApp.exe</NAME>
<NAME name="Yandex Disk" regex="false" typeFilter="file">yandexdisk2.exe</NAME>
<NAME name="eFileCabinet" regex="false" typeFilter="file">efcClient.exe</NAME>
<NAME name="Amazon Photo Backup" regex="false" typeFilter="file">amazonphotos.exe</NAME>
<NAME name="Zoho Docs" regex="false" typeFilter="file">zohodocs.exe</NAME>
<NAME name="MEGAsync" regex="false" typeFilter="file">MEGAsync.exe</NAME>
<NAME name="SpiderOak One " regex="false" typeFilter="file">SpiderOakONE.exe</NAME>
<NAME name="Box" regex="false" typeFilter="file">box.exe</NAME>
<NAME name="OneDrive" regex="false" typeFilter="file">onedrive.exe</NAME>
<NAME name="Sync" regex="false" typeFilter="file">sync-taskbar.exe</NAME>
</INTERESTING_FILE_SET>
</INTERESTING_FILE_SETS>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<INTERESTING_FILE_SETS>
<INTERESTING_FILE_SET description="" ignoreKnown="false" name="Cryptocurrency Wallets">
<NAME name="Electrum Portable" regex="true" typeFilter="file">^electrum(.*)portable.exe</NAME>
<NAME name="Jaxx" regex="false" typeFilter="file">jaxx liberty.exe</NAME>
<NAME name="Electron Cash Standalone" regex="true" typeFilter="file">^electron-cash(.*).exe$</NAME>
<NAME name="Exodus" regex="false" typeFilter="file">exodus.exe</NAME>
<NAME name="Bitcoin Wallet" regex="false" typeFilter="file">bitcoin-qt.exe</NAME>
<NAME name="Dogecoin" regex="false" typeFilter="file">dogecoin-qt.exe</NAME>
<NAME name="Zecwallet" regex="false" typeFilter="file">Zecwallet Fullnode.exe</NAME>
<NAME name="Litecoin" regex="false" typeFilter="file">litecoin-qt.exe</NAME>
<NAME name="Zel Core" regex="false" typeFilter="file">zelcore.exe</NAME>
<NAME name="BitPay" regex="false" typeFilter="file">bitpay.exe</NAME>
<NAME name="Verge Tor QT Wallet" regex="false" typeFilter="file">verge-qt.exe</NAME>
<NAME name="Atomic Wallet" regex="false" typeFilter="file">atomic wallet.exe</NAME>
<NAME name="Bitcoin Armory" regex="false" typeFilter="file">armoryqt.exe</NAME>
<NAME name="Eidoo Wallet" regex="false" typeFilter="file">eidoo.exe</NAME>
<NAME name="Electron Cash Portable" regex="true" typeFilter="file">^electron-cash(.*)portable.exe$</NAME>
<NAME name="Monero GUI Wallet" regex="false" typeFilter="file">monero-wallet-gui.exe</NAME>
<NAME name="Coinomi Wallet" regex="false" typeFilter="file">coinomi.exe</NAME>
<NAME name="Electron Cash" regex="false" typeFilter="file">electron-cash.exe</NAME>
<NAME name="Zel Core Portable" regex="false" typeFilter="file">zelcore-portable.exe</NAME>
<NAME name="Qtum Core" regex="false" typeFilter="file">qtum-qt.exe</NAME>
<NAME name="Dash Core Wallet" regex="false" typeFilter="file">dash-qt.exe</NAME>
<NAME name="Zecwallet Lite" regex="false" typeFilter="file">Zecwallet Lite.exe</NAME>
<NAME name="Copay" regex="false" typeFilter="file">copay.exe</NAME>
<NAME name="Multidoge Wallet" regex="false" typeFilter="file">multidoge.exe</NAME>
<NAME name="Neon Wallet" regex="false" typeFilter="file">neon.exe</NAME>
<NAME name="Dash Electrum Wallet" regex="true" typeFilter="file">^electrum-dash(.*).exe$</NAME>
<NAME name="Lisk Wallet" regex="false" typeFilter="file">lisk.exe</NAME>
<NAME name="Stargazer Wallet" regex="false" typeFilter="file">stargazer.exe</NAME>
<NAME name="GreenAddress Wallet" regex="false" typeFilter="file">GreenAddress Wallet.exe</NAME>
<NAME name="Electrum" regex="true" typeFilter="file">^electrum(.*).exe</NAME>
<NAME name="Qtum Electrum" regex="true" typeFilter="file">^Qtum-electrum-win-(.*).exe$</NAME>
<NAME name="Bither" regex="false" typeFilter="file">BitherWinLauncher.exe</NAME>
<NAME name="Toast Wallet" regex="false" typeFilter="file">toastwallet.exe</NAME>
<NAME name="Guarda Wallet" regex="false" typeFilter="file">guarda.exe</NAME>
</INTERESTING_FILE_SET>
</INTERESTING_FILE_SETS>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<INTERESTING_FILE_SETS>
<INTERESTING_FILE_SET description="Finds Encryption Programs installed on the machine" ignoreKnown="false" name="Encryption Programs">
<NAME name="CryptoExpert 8" regex="false" typeFilter="file">cexpertcmd.exe</NAME>
<NAME name="aescrypt" regex="false" typeFilter="file">aescrypt.exe</NAME>
<NAME name="7z" regex="false" typeFilter="file">7z.exe</NAME>
<NAME name="Gpg4win" regex="false" typeFilter="file">gdbus.exe</NAME>
<NAME name="AxCrypt" regex="false" typeFilter="file">AxCrypt.exe</NAME>
<NAME name="Encrypto" regex="false" typeFilter="file">Encrypto.exe</NAME>
<NAME name="Cryptomator" regex="false" typeFilter="file">Cryptomator.exe</NAME>
<NAME name="KeePass" regex="false" typeFilter="file">KeePass.exe</NAME>
<NAME name="certainsafe" regex="false" typeFilter="file">certainsafe.exe</NAME>
<NAME name="Tutanota Desktop" regex="false" typeFilter="file">Tutanota Desktop.exe</NAME>
<NAME name="BitLocker" regex="false" typeFilter="all">BitLockerDeviceEncryption.exe</NAME>
<NAME name="EncFSMP" regex="false" typeFilter="file">EncFSMP.exe</NAME>
<NAME name="HTTPS Everywhere" regex="false" typeFilter="file">HTTPS Everywhere</NAME>
<NAME name="Tor Browser" regex="false" typeFilter="all">Tor Browser</NAME>
<NAME name="CryptoExpert 8" regex="false" typeFilter="file"> cexpert_gui.exe</NAME>
<NAME name="GnuPG" regex="false" typeFilter="file"> gpg.exe</NAME>
<NAME name="Folder Lock" regex="false" typeFilter="file">Folder Lock.exe</NAME>
<NAME name="Gihosoft File Encryption" regex="false" typeFilter="file">GFileEncryption.exe</NAME>
<NAME name="VeraCrypt" regex="false" typeFilter="file">VeraCrypt.exe</NAME>
<NAME name="Proton Bridge" regex="false" typeFilter="file">Desktop-Bridge.exe</NAME>
</INTERESTING_FILE_SET>
</INTERESTING_FILE_SETS>

View File

@ -0,0 +1,2 @@
Whenever files are added or removed from this folder, StandardInterestingFilesSetsLoader.INTERESTING_FILESETS_RULES_NAMES needs to be altered accordingly.

View File

@ -80,7 +80,7 @@ class InterestingItemsFilesSetSettings implements Serializable {
private static final Logger logger = Logger.getLogger(InterestingItemsFilesSetSettings.class.getName()); private static final Logger logger = Logger.getLogger(InterestingItemsFilesSetSettings.class.getName());
private static final String TYPE_FILTER_ATTR = "typeFilter"; //NON-NLS private static final String TYPE_FILTER_ATTR = "typeFilter"; //NON-NLS
private static final String EXTENSION_RULE_TAG = "EXTENSION"; //NON-NLS private static final String EXTENSION_RULE_TAG = "EXTENSION"; //NON-NLS
private static final String READONLY = "readOnly"; private static final String STANDARD_SET = "standardSet";
private static final String VERSION_NUMBER = "versionNumber"; private static final String VERSION_NUMBER = "versionNumber";
private Map<String, FilesSet> filesSets; private Map<String, FilesSet> filesSets;
@ -382,15 +382,15 @@ class InterestingItemsFilesSetSettings implements Serializable {
ignoreUnallocatedSpace = Boolean.parseBoolean(ignoreUnallocated); ignoreUnallocatedSpace = Boolean.parseBoolean(ignoreUnallocated);
} }
String isReadonlyString = setElem.getAttribute(READONLY); String isStandardSetString = setElem.getAttribute(STANDARD_SET);
boolean isReadOnly = false; boolean isStandardSet = false;
if (StringUtils.isNotBlank(isReadonlyString)) { if (StringUtils.isNotBlank(isStandardSetString)) {
isReadOnly = Boolean.parseBoolean(isReadonlyString); isStandardSet = Boolean.parseBoolean(isStandardSetString);
} }
String versionNumberString = setElem.getAttribute(VERSION_NUMBER); String versionNumberString = setElem.getAttribute(VERSION_NUMBER);
int versionNumber = 0; int versionNumber = 0;
if (StringUtils.isNotBlank(isReadonlyString)) { if (StringUtils.isNotBlank(isStandardSetString)) {
try { try {
versionNumber = Integer.parseInt(versionNumberString); versionNumber = Integer.parseInt(versionNumberString);
} }
@ -424,7 +424,7 @@ class InterestingItemsFilesSetSettings implements Serializable {
// Make the files set. Note that degenerate sets with no rules are // Make the files set. Note that degenerate sets with no rules are
// allowed to facilitate the separation of set definition and rule // allowed to facilitate the separation of set definition and rule
// definitions. A set without rules is simply the empty set. // definitions. A set without rules is simply the empty set.
FilesSet set = new FilesSet(setName, description, ignoreKnownFiles, ignoreUnallocatedSpace, rules, isReadOnly, versionNumber); FilesSet set = new FilesSet(setName, description, ignoreKnownFiles, ignoreUnallocatedSpace, rules, isStandardSet, versionNumber);
filesSets.put(set.getName(), set); filesSets.put(set.getName(), set);
} }
// Note: This method takes a file path to support the possibility of // Note: This method takes a file path to support the possibility of
@ -479,7 +479,7 @@ class InterestingItemsFilesSetSettings implements Serializable {
} }
Document doc = XMLUtil.loadDoc(InterestingItemsFilesSetSettings.class, xmlFile.getPath()); Document doc = XMLUtil.loadDoc(InterestingItemsFilesSetSettings.class, xmlFile.getPath());
return readDefinitionsXML(doc, xmlFile); return readDefinitionsXML(doc, xmlFile.getPath());
} }
/** /**
@ -495,25 +495,25 @@ class InterestingItemsFilesSetSettings implements Serializable {
* @throws * @throws
* org.sleuthkit.autopsy.modules.interestingitems.FilesSetsManager.FilesSetsManagerException * org.sleuthkit.autopsy.modules.interestingitems.FilesSetsManager.FilesSetsManagerException
*/ */
static Map<String, FilesSet> readDefinitionsXML(Document doc, File xmlFile) throws FilesSetsManager.FilesSetsManagerException { static Map<String, FilesSet> readDefinitionsXML(Document doc, String resourceName) throws FilesSetsManager.FilesSetsManagerException {
// Parse the XML in the file. // Parse the XML in the file.
Map<String, FilesSet> filesSets = new HashMap<>(); Map<String, FilesSet> filesSets = new HashMap<>();
if (doc == null) { if (doc == null) {
logger.log(Level.SEVERE, "FilesSet definition file at {0}", (xmlFile == null) ? "<null>" : xmlFile.getPath()); // NON-NLS logger.log(Level.SEVERE, "FilesSet definition file at {0}", resourceName); // NON-NLS
return filesSets; return filesSets;
} }
// Get the root element. // Get the root element.
Element root = doc.getDocumentElement(); Element root = doc.getDocumentElement();
if (root == null) { if (root == null) {
logger.log(Level.SEVERE, "Failed to get root {0} element tag of FilesSet definition file at {1}", logger.log(Level.SEVERE, "Failed to get root {0} element tag of FilesSet definition file at {1}",
new Object[]{FILE_SETS_ROOT_TAG, (xmlFile == null) ? "<null>" : xmlFile.getPath()}); // NON-NLS new Object[]{FILE_SETS_ROOT_TAG, resourceName}); // NON-NLS
return filesSets; return filesSets;
} }
// Read in the files set definitions. // Read in the files set definitions.
NodeList setElems = root.getElementsByTagName(FILE_SET_TAG); NodeList setElems = root.getElementsByTagName(FILE_SET_TAG);
for (int i = 0; i < setElems.getLength(); ++i) { for (int i = 0; i < setElems.getLength(); ++i) {
readFilesSet((Element) setElems.item(i), filesSets, xmlFile.getPath()); readFilesSet((Element) setElems.item(i), filesSets, resourceName);
} }
return filesSets; return filesSets;
} }
@ -561,7 +561,7 @@ class InterestingItemsFilesSetSettings implements Serializable {
setElement.setAttribute(NAME_ATTR, set.getName()); setElement.setAttribute(NAME_ATTR, set.getName());
setElement.setAttribute(DESC_ATTR, set.getDescription()); setElement.setAttribute(DESC_ATTR, set.getDescription());
setElement.setAttribute(IGNORE_KNOWN_FILES_ATTR, Boolean.toString(set.ignoresKnownFiles())); setElement.setAttribute(IGNORE_KNOWN_FILES_ATTR, Boolean.toString(set.ignoresKnownFiles()));
setElement.setAttribute(READONLY, Boolean.toString(set.isReadOnly())); setElement.setAttribute(STANDARD_SET, Boolean.toString(set.isStandardSet()));
setElement.setAttribute(VERSION_NUMBER, Integer.toString(set.getVersionNumber())); setElement.setAttribute(VERSION_NUMBER, Integer.toString(set.getVersionNumber()));
// Add the child elements for the set membership rules. // Add the child elements for the set membership rules.
// All conditions of a rule will be written as a single element in the xml // All conditions of a rule will be written as a single element in the xml

View File

@ -18,28 +18,24 @@
*/ */
package org.sleuthkit.autopsy.modules.interestingitems; package org.sleuthkit.autopsy.modules.interestingitems;
import com.google.common.collect.ImmutableList;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level; import java.util.logging.Level;
import org.apache.commons.io.FileUtils; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.openide.modules.OnStart; import org.openide.modules.OnStart;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.util.io.NbObjectOutputStream;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
/** /**
* When the interesting items module loads, this runnable loads standard * When the interesting items module loads, this runnable loads standard
@ -48,6 +44,14 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
@OnStart @OnStart
public class StandardInterestingFilesSetsLoader implements Runnable { public class StandardInterestingFilesSetsLoader implements Runnable {
// The list of class resources representing the standard interesting files sets
// NOTE: This list must be updated to correspond to the standard interesting files sets in 'InterestingFileSetRules'
private final static List<String> INTERESTING_FILESETS_RULES_NAMES = ImmutableList.of(
"Cloud Storage.xml",
"Cryptocurrency Wallets.xml",
"Encryption Programs.xml"
);
private static final Logger LOGGER = Logger.getLogger(StandardInterestingFilesSetsLoader.class.getName()); private static final Logger LOGGER = Logger.getLogger(StandardInterestingFilesSetsLoader.class.getName());
private static final String CONFIG_DIR = "InterestingFileSetRules"; private static final String CONFIG_DIR = "InterestingFileSetRules";
@ -116,43 +120,6 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
return standardInterestingFileSets; return standardInterestingFileSets;
} }
private static List<String> getResourceFolderContents(String directory) {
// taken from https://stackoverflow.com/questions/11012819/how-can-i-get-a-resource-folder-from-inside-my-jar-file
final File jarFile = new File(StandardInterestingFilesSetsLoader.class.getProtectionDomain().getCodeSource().getLocation().getPath());
List<String> toRet = new ArrayList<>();
if(jarFile.isFile()) {
JarFile jar = null;
try {
jar = new JarFile(jarFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
while(entries.hasMoreElements()) {
final String name = entries.nextElement().getName();
if (name.startsWith(directory + "/")) { //filter according to the path
toRet.add(name);
}
}
jar.close();
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "There was an error reading contents of jar file.", ex);
} finally {
if (jar != null) {
try {
jar.close();
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "There was an error closing jar resources while loading contents.", ex);
}
}
}
} else {
LOGGER.log(Level.WARNING, "Jar file could not be opened. No standard interesting files sets will be loaded.");
}
return toRet;
}
/** /**
* Add the InterestingFileSetRules directory to the users app data config * Add the InterestingFileSetRules directory to the users app data config
* directory for Autopsy if not already present. * directory for Autopsy if not already present.
@ -162,14 +129,14 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
* non-null. * non-null.
*/ */
private static void copyRulesDirectory(File rulesConfigDir) { private static void copyRulesDirectory(File rulesConfigDir) {
for (String resourceFile : INTERESTING_FILESETS_RULES_NAMES) {
try { String resourcePath = "./" + CONFIG_DIR + "/" + resourceFile;
for (String resourceFile : getResourceFolderContents(DEFAULT_XML_FILTER)) { if (StandardInterestingFilesSetsLoader.class.getResource(resourcePath) == null) {
updateStandardFilesSetConfigFile(rulesConfigDir, resourceFile); LOGGER.log(Level.SEVERE, String.format("Expected resource: %s could not be found at %s.", resourceFile, resourcePath));
} else {
InputStream fileSetStream = StandardInterestingFilesSetsLoader.class.getResourceAsStream(resourcePath);
updateStandardFilesSetConfigFile(rulesConfigDir, fileSetStream, resourceFile);
} }
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, String.format("There was an error copying %s to %s.",
resourceDirectory.getAbsolutePath(), rulesConfigDir.getAbsolutePath()), ex);
} }
} }
@ -178,17 +145,22 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
* corresponding files set on disk or the files set on disk has an older * corresponding files set on disk or the files set on disk has an older
* version. * version.
* *
* @param rulesConfigDir The directory for standard interesting files sets. * @param rulesConfigDir The directory for standard interesting files
* @param resourceInputStream The standard interesting files set resource file * sets.
* located within the jar. * @param resourceInputStream The standard interesting files set resource
* file located within the jar.
* @param resourceName The filename of the resource to be copied.
*/ */
private static void updateStandardFilesSetConfigFile(File rulesConfigDir, InputStream resourceInputStream, String resourceName) { private static void updateStandardFilesSetConfigFile(File rulesConfigDir, InputStream resourceInputStream, String resourceName) {
File configDirFile = new File(rulesConfigDir, resourceName); File configDirFile = new File(rulesConfigDir, resourceName);
Map<String, FilesSet> resourceFilesSet = null; Map<String, FilesSet> resourceFilesSet = null;
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
try { try {
resourceFilesSet = InterestingItemsFilesSetSettings.readDefinitionsXML(resourceFile); DocumentBuilder builder = builderFactory.newDocumentBuilder();
} catch (FilesSetsManager.FilesSetsManagerException ex) { Document xmlDoc = builder.parse(resourceInputStream);
resourceFilesSet = InterestingItemsFilesSetSettings.readDefinitionsXML(xmlDoc, resourceName);
} catch (ParserConfigurationException | SAXException | IOException | FilesSetsManager.FilesSetsManagerException ex) {
LOGGER.log(Level.SEVERE, "Unable to read FilesSet data from resource file: " + resourceName, ex); LOGGER.log(Level.SEVERE, "Unable to read FilesSet data from resource file: " + resourceName, ex);
return; return;
} }
@ -243,8 +215,8 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
if (destFileSet != null) { if (destFileSet != null) {
// If and only if there is a naming conflict with a user-defined rule set, append (Custom) // If and only if there is a naming conflict with a user-defined rule set, append (Custom)
// to the user-defined rule set and add it back to the Map. // to the user-defined rule set and add it back to the Map.
if (appendCustom && srcFileSet.isReadOnly() != destFileSet.isReadOnly()) { if (appendCustom && srcFileSet.isStandardSet() != destFileSet.isStandardSet()) {
if (srcFileSet.isReadOnly()) { if (srcFileSet.isStandardSet()) {
addCustomFile(dest, key, destFileSet); addCustomFile(dest, key, destFileSet);
} else { } else {
addCustomFile(dest, key, srcFileSet); addCustomFile(dest, key, srcFileSet);
@ -280,8 +252,8 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
"StandardInterestingFileSetsLoader.customSuffixed={0} (Custom)" "StandardInterestingFileSetsLoader.customSuffixed={0} (Custom)"
}) })
private static void addCustomFile(Map<String, FilesSet> dest, String key, FilesSet srcFilesSet) { private static void addCustomFile(Map<String, FilesSet> dest, String key, FilesSet srcFilesSet) {
if (srcFilesSet.isReadOnly()) { if (srcFilesSet.isStandardSet()) {
LOGGER.log(Level.SEVERE, "An attempt to create a custom file that was not readonly"); LOGGER.log(Level.SEVERE, "An attempt to create a custom file that was a standard set.");
return; return;
} }