Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
SampleFileIngestModule.java
Go to the documentation of this file.
1 /*
2  * Sample module in the public domain. Feel free to use this as a template
3  * for your modules.
4  *
5  * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
6  *
7  * This is free and unencumbered software released into the public domain.
8  *
9  * Anyone is free to copy, modify, publish, use, compile, sell, or
10  * distribute this software, either in source code form or as a compiled
11  * binary, for any purpose, commercial or non-commercial, and by any
12  * means.
13  *
14  * In jurisdictions that recognize copyright laws, the author or authors
15  * of this software dedicate any and all copyright interest in the
16  * software to the public domain. We make this dedication for the benefit
17  * of the public at large and to the detriment of our heirs and
18  * successors. We intend this dedication to be an overt act of
19  * relinquishment in perpetuity of all present and future rights to this
20  * software under copyright law.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  * OTHER DEALINGS IN THE SOFTWARE.
29  */
30 package org.sleuthkit.autopsy.examples;
31 
32 import java.util.HashMap;
33 import java.util.logging.Level;
50 
56 class SampleFileIngestModule implements FileIngestModule {
57 
58  private static final HashMap<Long, Long> artifactCountsForIngestJobs = new HashMap<>();
59  private static int attrId = -1;
60  private final boolean skipKnownFiles;
61  private IngestJobContext context = null;
62  private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
63 
64  SampleFileIngestModule(SampleModuleIngestJobSettings settings) {
65  this.skipKnownFiles = settings.skipKnownFiles();
66  }
67 
68  @Override
69  public void startUp(IngestJobContext context) throws IngestModuleException {
70  this.context = context;
71  refCounter.incrementAndGet(context.getJobId());
72 
73  synchronized (SampleFileIngestModule.class) {
74  if (attrId == -1) {
75  // For this sample, make a new attribute type to use to post
76  // results to the blackboard. There are many standard blackboard
77  // artifact and attribute types and you should use them instead
78  // creating new ones to facilitate use of your results by other
79  // modules.
80  Case autopsyCase = Case.getCurrentCase();
81  SleuthkitCase sleuthkitCase = autopsyCase.getSleuthkitCase();
82  try {
83  // See if the attribute type has already been defined.
84  attrId = sleuthkitCase.getAttrTypeID("ATTR_SAMPLE");
85  if (attrId == -1) {
86  attrId = sleuthkitCase.addAttrType("ATTR_SAMPLE", "Sample Attribute");
87  }
88  } catch (TskCoreException ex) {
89  IngestServices ingestServices = IngestServices.getInstance();
90  Logger logger = ingestServices.getLogger(SampleIngestModuleFactory.getModuleName());
91  logger.log(Level.SEVERE, "Failed to create blackboard attribute", ex);
92  attrId = -1;
93  throw new IngestModuleException(ex.getLocalizedMessage());
94  }
95  }
96  }
97  }
98 
99  @Override
100  public IngestModule.ProcessResult process(AbstractFile file) {
101  if (attrId == -1) {
102  return IngestModule.ProcessResult.ERROR;
103  }
104 
105  // Skip anything other than actual file system files.
106  if ((file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
107  || (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
108  || (file.isFile() == false)) {
109  return IngestModule.ProcessResult.OK;
110  }
111 
112  // Skip NSRL / known files.
113  if (skipKnownFiles && file.getKnown() == TskData.FileKnown.KNOWN) {
114  return IngestModule.ProcessResult.OK;
115  }
116 
117  // Do a nonsensical calculation of the number of 0x00 bytes
118  // in the first 1024-bytes of the file. This is for demo
119  // purposes only.
120  try {
121  byte buffer[] = new byte[1024];
122  int len = file.read(buffer, 0, 1024);
123  int count = 0;
124  for (int i = 0; i < len; i++) {
125  if (buffer[i] == 0x00) {
126  count++;
127  }
128  }
129 
130  // Make an attribute using the ID for the attribute type that
131  // was previously created.
132  BlackboardAttribute attr = new BlackboardAttribute(attrId, SampleIngestModuleFactory.getModuleName(), count);
133 
134  // Add the to the general info artifact for the file. In a
135  // real module, you would likely have more complex data types
136  // and be making more specific artifacts.
137  BlackboardArtifact art = file.getGenInfoArtifact();
138  art.addAttribute(attr);
139 
140  // This method is thread-safe with per ingest job reference counted
141  // management of shared data.
142  addToBlackboardPostCount(context.getJobId(), 1L);
143 
144  // Fire an event to notify any listeners for blackboard postings.
145  ModuleDataEvent event = new ModuleDataEvent(SampleIngestModuleFactory.getModuleName(), ARTIFACT_TYPE.TSK_GEN_INFO);
146  IngestServices.getInstance().fireModuleDataEvent(event);
147 
148  return IngestModule.ProcessResult.OK;
149 
150  } catch (TskCoreException ex) {
151  IngestServices ingestServices = IngestServices.getInstance();
152  Logger logger = ingestServices.getLogger(SampleIngestModuleFactory.getModuleName());
153  logger.log(Level.SEVERE, "Error processing file (id = " + file.getId() + ")", ex);
154  return IngestModule.ProcessResult.ERROR;
155  }
156  }
157 
158  @Override
159  public void shutDown() {
160  // This method is thread-safe with per ingest job reference counted
161  // management of shared data.
162  reportBlackboardPostCount(context.getJobId());
163  }
164 
165  synchronized static void addToBlackboardPostCount(long ingestJobId, long countToAdd) {
166  Long fileCount = artifactCountsForIngestJobs.get(ingestJobId);
167 
168  // Ensures that this job has an entry
169  if (fileCount == null) {
170  fileCount = 0L;
171  artifactCountsForIngestJobs.put(ingestJobId, fileCount);
172  }
173 
174  fileCount += countToAdd;
175  artifactCountsForIngestJobs.put(ingestJobId, fileCount);
176  }
177 
178  synchronized static void reportBlackboardPostCount(long ingestJobId) {
179  Long refCount = refCounter.decrementAndGet(ingestJobId);
180  if (refCount == 0) {
181  Long filesCount = artifactCountsForIngestJobs.remove(ingestJobId);
182  String msgText = String.format("Posted %d times to the blackboard", filesCount);
183  IngestMessage message = IngestMessage.createMessage(
184  IngestMessage.MessageType.INFO,
185  SampleIngestModuleFactory.getModuleName(),
186  msgText);
187  IngestServices.getInstance().postMessage(message);
188  }
189  }
190 }

Copyright © 2012-2015 Basis Technology. Generated on: Mon Oct 19 2015
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.