Merge branch 'collaborative' of https://github.com/sleuthkit/autopsy into collaborative

This commit is contained in:
Richard Cordovano 2015-04-24 09:14:26 -04:00
commit ab5a1c27d1
16 changed files with 121 additions and 64 deletions

View File

@ -1,8 +1,8 @@
Last Updated: Sept 17, 2014
Last Updated: 21 April 2015
This file outlines what it takes to build Autopsy from source.
Note that it currently only works out of the box on Windows. We
Note that it currently only works out-of-the-box on Windows. We
are working on getting the process working under non-Windows systems.
It generally works, but needs some custom mangling to find the
correct C libraries.
@ -11,7 +11,9 @@ correct C libraries.
STEPS:
1) Get Java Setup
1a) Download and install JDK version 1.8. You can now use 32-bit or 64-bit, but special work is needed to get The Sleuth Kit to compile as 64-bit. So, 32-bit is easier.
1a) Download and install JDK version 1.8. You can now use 32-bit or 64-bit, but
special work is needed to get The Sleuth Kit to compile as 64-bit. So, 32-bit
is easier, but if you intend to use PostgreSQL, choose 64-bit.
Autopsy has been used and tested with Oracle JavaSE and the included JavaFX support
(http://www.oracle.com/technetwork/java/javase/downloads/index.html).
@ -28,8 +30,8 @@ but it is a recommended IDE to use for development of Autopsy modules.
need to set JRE_HOME_32 to the root 32-bit JRE directory and/or JRE_HOME_64
to the root 64-bit JRE directory.
1e) (optional) For some Autopsy features to be functional, you need to add java executable to the system PATH.
1e) (optional) For some Autopsy features to be functional, you need to add the
java executable to the system PATH.
2) Get Sleuth Kit Setup
@ -43,18 +45,29 @@ our 64-bit version of libewf:
2b) Set LIBEWF_HOME environment variable to root directory of LIBEWF
2c) Download and build a Release version of Sleuth Kit (TSK) 4.0. You
need to build the tsk_jni project. You can use a released version or
download the latest from github:
2c) Download and install PostgreSQL 9.4 or above. The official releases are
from: http://www.postgresql.org/download/
2d) Set the POSTGRESQL_HOME_64 environment variable to point to the
PostgreSQL folder containing, but not including, the bin folder.
Example: POSTGRESQL_HOME_64=C:\Program Files\PostgreSQL\9.4
2d) Download and build a Release version of Sleuth Kit (TSK) 4.0. See
win32\BUILDING.txt in the TSK package for more information. You need to
build the tsk_jni project. Select the Debug_PostgreSQL x64 or
Release_PostgreSQL x64 target. You can use a released version or download
the latest from github:
- git://github.com/sleuthkit/sleuthkit.git
2d) Build the TSK JAR file by typing 'ant' in bindings/java in the
TSK source code folder from a command line. You can also add the
code to a NetBeans project and build it from there.
2e) Build the TSK JAR file by typing 'ant PostgreSQL' in bindings/java in the
TSK source code folder from a command line. Note it is case sensitive. You
can also add the code to a NetBeans project and build it from there,
selecting the PostgreSQL target. For TSK, the default is SQLite, which is
not enough for Autopsy. You must use the PostgreSQL target.
2e) Set TSK_HOME environment variable to the root directory of TSK
2f) Set TSK_HOME environment variable to the root directory of TSK
2f) On Non-Windows systems, you will need to do a 'make install'
2g) On Non-Windows systems, you will need to do a 'make install'
from the TSK root directory to install the libraries and such in
the needed places (i.e. '/usr/local').
@ -85,12 +98,13 @@ and by submitting pull requests to the main Autopsy repository.
5) Compile Autopsy
5a) using Netbeans IDE:
- Start NetBeans IDE and open the Autopsy project.
- Choose to build the Autopsy project / module. It is the highest
level project that will then cause the other modules to be compiled.
- To build Autopsy, PostgreSQL is required to be installed.
- Choose to build the Autopsy project / module. It is the highest level project
that will cause the other modules to be compiled.
5b) without Netbeans IDE (requires JDK and ant >= 1.7.1):
- from root directory of Autopsy source execute:
ant build
ant
(to build Autopsy)
ant run
(to run Autopsy)
@ -102,8 +116,10 @@ the build process.
- The Sleuth Kit Java datamodel JAR file has native JNI libraries
that are copied into it. These JNI libraries have dependencies on
libewf and zlib. On non-Windows platforms, the JNI library also has
a dependency on libtsk (on Windows, it is compiled into libtsk_jni).
libewf and zlib. If you are using PostgreSQL, the dependencies are on libewf,
zlib, libpq, libintl-8, libeay32, and ssleay32 DLL files. On non-Windows
platforms, the JNI library also has a dependency on libtsk (on Windows,
it is compiled into libtsk_jni).
- NetBeans uses ant to build Autopsy. The build target copies the
TSK datamodel JAR file into the project. If you want to use the

View File

@ -149,6 +149,7 @@ CaseOpenAction.msgDlg.fileNotExist.msg=Error\: File does not exist.
CaseOpenAction.msgDlg.fileNotExist.title=Error
CaseOpenAction.msgDlg.cantOpenCase.msg=Error\: could not open the case in folder {0}\: {1}
CaseOpenAction.msgDlg.cantOpenCase.title=Error
CaseCreateAction.msgDlg.cantCreateCase.msg=Cannot create case
CasePropertiesAction.window.title=Case Properties
CasePropertiesForm.updateCaseName.msgDlg.empty.msg=The caseName cannot be empty.
CasePropertiesForm.updateCaseName.msgDlg.empty.title=Error

View File

@ -30,8 +30,6 @@
<Component id="rbSingleUserCase" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="rbMultiUserCase" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbBadMultiUserSettings" max="32767" attributes="0"/>
</Group>
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
@ -44,7 +42,8 @@
<EmptySpace max="32767" attributes="0"/>
<Component id="caseNameTextField" min="-2" pref="296" max="-2" attributes="0"/>
</Group>
<Component id="caseDirTextField" alignment="0" min="-2" pref="380" max="-2" attributes="1"/>
<Component id="caseDirTextField" alignment="0" max="32767" attributes="1"/>
<Component id="lbBadMultiUserSettings" alignment="1" min="-2" pref="372" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="caseDirBrowseButton" min="-2" max="-2" attributes="0"/>
@ -78,9 +77,10 @@
<Group type="103" groupAlignment="3" attributes="0">
<Component id="rbSingleUserCase" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="rbMultiUserCase" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbBadMultiUserSettings" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="16" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="lbBadMultiUserSettings" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>

View File

@ -198,9 +198,7 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(rbSingleUserCase)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(rbMultiUserCase)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lbBadMultiUserSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(rbMultiUserCase))
.addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(caseDirLabel)
@ -210,7 +208,8 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
.addComponent(caseNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(caseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 296, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(caseDirTextField, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 380, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(caseDirTextField, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbBadMultiUserSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 372, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(caseDirBrowseButton)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
@ -236,9 +235,10 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(rbSingleUserCase)
.addComponent(rbMultiUserCase)
.addComponent(lbBadMultiUserSettings))
.addContainerGap(16, Short.MAX_VALUE))
.addComponent(rbMultiUserCase))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lbBadMultiUserSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents

View File

@ -22,12 +22,13 @@ package org.sleuthkit.autopsy.casemodule;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.openide.WizardDescriptor;
import org.openide.WizardValidationException;
import org.openide.util.Exceptions;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
@ -174,30 +175,29 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
@Override
public void validate() throws WizardValidationException {
NewCaseVisualPanel2 currentComponent = getComponent();
final String caseNumber = currentComponent.getCaseNumber();
final String examiner = currentComponent.getExaminer();
try {
SwingUtilities.invokeLater(new Runnable(){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
Case.create(createdDirectory, caseName, caseNumber, examiner, caseType);
} catch (Exception ex) {
Exceptions.printStackTrace(ex);
JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(),
"CaseCreateAction.msgDlg.cantCreateCase.msg")+" "+caseName,
NbBundle.getMessage(this.getClass(),
"CaseOpenAction.msgDlg.cantOpenCase.title"),
JOptionPane.ERROR_MESSAGE);
}
}
});
//Case.create(createdDirectory, caseName, caseNumber, examiner);
} catch(Exception ex) {
});
} catch (Exception ex) {
throw new WizardValidationException(this.getComponent(),
NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel2.validate.errCreateCase.msg"),
null);
NbBundle.getMessage(this.getClass(), "NewCaseWizardPanel2.validate.errCreateCase.msg"), null);
}
}
}

View File

@ -18,7 +18,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
@OptionsPanelController.TopLevelRegistration(
categoryName = "#OptionsCategory_Name_FileExtMismatchOptions",
iconBase = "org/sleuthkit/autopsy/modules/fileextmismatch/options-icon.png",
position = 4,
position = 5,
keywords = "#OptionsCategory_FileExtMismatch",
keywordsCategory = "KeywordSearchOptions")
public final class FileExtMismatchOptionsPanelController extends OptionsPanelController {

View File

@ -174,6 +174,9 @@ class FileType {
* @return True or false.
*/
boolean containedIn(final AbstractFile file) {
if(file.getSize() < (offset+signatureBytes.length)) {
return false; /// too small, can't contain this signature
}
try {
byte[] buffer = new byte[signatureBytes.length];
int bytesRead = file.read(buffer, offset, signatureBytes.length);

View File

@ -17,7 +17,7 @@ import org.openide.util.Lookup;
iconBase = "org/sleuthkit/autopsy/modules/filetypeid/user-defined-file-types-settings.png",
keywords = "#OptionsCategory_Keywords_FileTypeId",
keywordsCategory = "FileTypeId",
position = 5
position = 6
)
// moved messages to Bundle.properties
//@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_FileTypeId=FileTypeId", "OptionsCategory_Keywords_FileTypeId=FileTypeId"})

View File

@ -33,7 +33,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
@OptionsPanelController.TopLevelRegistration(
categoryName = "#OptionsCategory_Name_HashDatabase",
iconBase = "org/sleuthkit/autopsy/modules/hashdatabase/options_icon.png",
position = 3,
position = 4,
keywords = "#OptionsCategory_Keywords_HashDatabase",
keywordsCategory = "HashDatabase",
id = "HashDatabase")

View File

@ -31,7 +31,7 @@ import org.openide.util.Lookup;
iconBase = "org/sleuthkit/autopsy/images/interesting_item_32x32.png",
keywords = "#OptionsCategory_Keywords_InterestingItemDefinitions",
keywordsCategory = "InterestingItemDefinitions",
position = 6
position = 7
)
public final class InterestingItemDefsOptionsPanelController extends OptionsPanelController {

View File

@ -31,7 +31,8 @@ import org.openide.util.Lookup;
categoryName = "#OptionsCategory_Name_Options",
iconBase = "org/sleuthkit/autopsy/imagegallery/images/polaroid_48_silhouette.png",
keywords = "#OptionsCategory_Keywords_Options",
keywordsCategory = "Options"
keywordsCategory = "Options",
position = 10
)
@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_Options=Image / Video Gallery", "OptionsCategory_Keywords_Options=image video gallery category "})
public final class ImageGalleryOptionsPanelController extends OptionsPanelController {

View File

@ -4,5 +4,5 @@
<Set name="contextPath"><SystemProperty name="hostContext" default="/solr"/></Set>
<Set name="war"><SystemProperty name="jetty.home"/>/webapps/solr.war</Set>
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home"/>/etc/webdefault.xml</Set>
<Set name="tempDirectory"><Property name="jetty.home" default="."/>/solr-webapp</Set>
</Configure>

View File

@ -32,7 +32,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
@OptionsPanelController.TopLevelRegistration(
categoryName = "#OptionsCategory_Name_KeywordSearchOptions",
iconBase = "org/sleuthkit/autopsy/keywordsearch/options-icon.png",
position = 2,
position = 3,
keywords = "#OptionsCategory_Keywords_KeywordSearchOptions",
keywordsCategory = "KeywordSearchOptions")
public final class KeywordSearchOptionsPanelController extends OptionsPanelController {

View File

@ -60,6 +60,7 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.datamodel.Content;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.CoreAdminResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrException;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
@ -513,9 +514,18 @@ public class Server {
* Waits for the stop command to finish before returning.
*/
synchronized void stop() {
try {
// Close any open core before stopping server
closeCore();
}
catch (KeywordSearchModuleException e) {
logger.log(Level.WARNING, "Failed to close core: ", e); //NON-NLS
}
try {
logger.log(Level.INFO, "Stopping Solr server from: " + solrFolder.getAbsolutePath()); //NON-NLS
//try graceful shutdown
final String [] SOLR_STOP_CMD = {
javaPath,
@ -653,6 +663,7 @@ public class Server {
if (currentCore == null) {
return;
}
currentCore.close();
currentCore = null;
serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STOPPED);
@ -971,11 +982,6 @@ public class Server {
NbBundle.getMessage(this.getClass(), "Server.openCore.exception.msg"));
}
CoreAdminRequest.Create createCore = new CoreAdminRequest.Create();
createCore.setDataDir(dataDir.getAbsolutePath());
createCore.setCoreName(coreName);
createCore.setConfigSet("AutopsyConfig");
if (caseType == CaseType.SINGLE_USER_CASE) {
currentSolrServer = this.localSolrServer;
//createCore.setInstanceDir(instanceDir);
@ -984,9 +990,18 @@ public class Server {
currentSolrServer = connectToRemoteSolrServer();
}
currentSolrServer.request(createCore);
if (!isCoreLoaded(coreName)) {
CoreAdminRequest.Create createCore = new CoreAdminRequest.Create();
createCore.setDataDir(dataDir.getAbsolutePath());
createCore.setCoreName(coreName);
createCore.setConfigSet("AutopsyConfig"); //NON-NLS
createCore.setIsLoadOnStartup(false);
createCore.setIsTransient(true);
final Core newCore = new Core(coreName);
currentSolrServer.request(createCore);
}
final Core newCore = new Core(coreName, caseType);
return newCore;
@ -1005,18 +1020,34 @@ public class Server {
return new HttpSolrServer("http://" + host + ":" + port + "/solr");
}
/**
* Determines whether the Solr core with the given name already exists.
* @param coreName
* @return true if core exists, otherwise false.
* @throws SolrServerException
* @throws IOException
*/
private boolean isCoreLoaded(String coreName) throws SolrServerException, IOException {
CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, currentSolrServer);
return response.getCoreStatus(coreName).get("instanceDir") != null; //NON-NLS
}
class Core {
// handle to the core in Solr
private String name;
private final String name;
private final CaseType caseType;
// the server to access a core needs to be built from a URL with the
// core in it, and is only good for core-specific operations
private HttpSolrServer solrCore;
private final HttpSolrServer solrCore;
private Core(String name) {
private Core(String name, CaseType caseType) {
this.name = name;
this.caseType = caseType;
this.solrCore = new HttpSolrServer(currentSolrServer.getBaseURL() + "/" + name);
//TODO test these settings
@ -1119,6 +1150,11 @@ public class Server {
}
synchronized void close() throws KeywordSearchModuleException {
// We only unload cores for "single-user" cases.
if (this.caseType == CaseType.MULTI_USER_CASE) {
return;
}
try {
CoreAdminRequest.unloadCore(this.name, currentSolrServer);
} catch (SolrServerException ex) {

View File

@ -273,8 +273,8 @@ class SearchEngineURLQueryAnalyzer extends Extract {
int totalQueries = 0;
try {
//from blackboard_artifacts
Collection<BlackboardArtifact> listArtifacts = currentCase.getSleuthkitCase().getMatchingArtifacts("WHERE (`artifact_type_id` = '" + ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() //NON-NLS
+ "' OR `artifact_type_id` = '" + ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID() + "') "); //List of every 'web_history' and 'bookmark' artifact NON-NLS
Collection<BlackboardArtifact> listArtifacts = currentCase.getSleuthkitCase().getMatchingArtifacts("WHERE (artifact_type_id = '" + ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() //NON-NLS
+ "' OR artifact_type_id = '" + ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID() + "') "); //List of every 'web_history' and 'bookmark' artifact NON-NLS
logger.log(Level.INFO, "Processing {0} blackboard artifacts.", listArtifacts.size()); //NON-NLS
for (BlackboardArtifact artifact : listArtifacts) {
@ -302,7 +302,7 @@ class SearchEngineURLQueryAnalyzer extends Extract {
SearchEngineURLQueryAnalyzer.SearchEngine se = null;
//from blackboard_attributes
Collection<BlackboardAttribute> listAttributes = currentCase.getSleuthkitCase().getMatchingAttributes("Where `artifact_id` = " + artifact.getArtifactID()); //NON-NLS
Collection<BlackboardAttribute> listAttributes = currentCase.getSleuthkitCase().getMatchingAttributes("Where artifact_id = " + artifact.getArtifactID()); //NON-NLS
for (BlackboardAttribute attribute : listAttributes) {
if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID()) {

View File

@ -2,7 +2,7 @@
<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
<!-- for some information on what you could do (e.g. targets to override). -->
<!-- If you delete this file and reopen the project it will be recreated. -->
<project name="Autopsy3" basedir=".">
<project name="Autopsy3" default="build" basedir=".">
<description>Builds the module suite Autopsy3.</description>
<import file="nbproject/build-impl.xml"/>