Autopsy  4.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
UserDefinedFileTypesManager.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2016 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.modules.filetypeid;
20 
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.UnsupportedEncodingException;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.logging.Level;
32 import javax.persistence.PersistenceException;
33 import javax.xml.parsers.ParserConfigurationException;
34 import org.w3c.dom.Document;
35 import org.w3c.dom.Element;
36 import org.w3c.dom.NodeList;
37 import javax.xml.bind.DatatypeConverter;
38 import javax.xml.transform.TransformerException;
39 import org.openide.util.NbBundle;
40 import org.openide.util.io.NbObjectInputStream;
41 import org.openide.util.io.NbObjectOutputStream;
46 import org.sleuthkit.datamodel.TskCoreException;
47 import org.w3c.dom.Node;
48 import org.xml.sax.SAXException;
49 
65 final class UserDefinedFileTypesManager {
66 
67  private static final Logger logger = Logger.getLogger(UserDefinedFileTypesManager.class.getName());
68  private static final String USER_DEFINED_TYPES_XML_FILE = "UserFileTypeDefinitions.xml"; //NON-NLS
69  private static final String USER_DEFINED_TYPES_SERIALIZATION_FILE = "UserFileTypeDefinitions.settings";
70  private static final String FILE_TYPES_TAG_NAME = "FileTypes"; //NON-NLS
71  private static final String FILE_TYPE_TAG_NAME = "FileType"; //NON-NLS
72  private static final String MIME_TYPE_TAG_NAME = "MimeType"; //NON-NLS
73  private static final String SIGNATURE_TAG_NAME = "Signature"; //NON-NLS
74  private static final String SIGNATURE_TYPE_ATTRIBUTE = "type"; //NON-NLS
75  private static final String BYTES_TAG_NAME = "Bytes"; //NON-NLS
76  private static final String OFFSET_TAG_NAME = "Offset"; //NON-NLS
77  private static final String RELATIVE_ATTRIBUTE = "RelativeToStart"; //NON-NLS
78  private static final String INTERESTING_FILES_SET_TAG_NAME = "InterestingFileSset"; //NON-NLS
79  private static final String ALERT_ATTRIBUTE = "alert"; //NON-NLS
80  private static final String ENCODING_FOR_XML_FILE = "UTF-8"; //NON-NLS
81  private static UserDefinedFileTypesManager instance;
82 
89  private final List<FileType> userDefinedFileTypes = new ArrayList<>();
90 
98  private final List<FileType> fileTypes = new ArrayList<>();
99 
107  synchronized static UserDefinedFileTypesManager getInstance() {
108  if (instance == null) {
109  instance = new UserDefinedFileTypesManager();
110  }
111  return instance;
112  }
113 
118  private UserDefinedFileTypesManager() {
119  }
120 
129  synchronized List<FileType> getFileTypes() throws UserDefinedFileTypesException {
130  loadFileTypes();
131 
138  return new ArrayList<>(fileTypes);
139  }
140 
149  synchronized List<FileType> getUserDefinedFileTypes() throws UserDefinedFileTypesException {
150  loadFileTypes();
151 
158  return new ArrayList<>(userDefinedFileTypes);
159  }
160 
168  private void loadFileTypes() throws UserDefinedFileTypesException {
169  fileTypes.clear();
170  userDefinedFileTypes.clear();
175  loadPredefinedFileTypes();
176  loadUserDefinedFileTypes();
177  }
178 
186  private void loadPredefinedFileTypes() throws UserDefinedFileTypesException {
187  byte[] byteArray;
188  FileType fileType;
189 
190  try {
191  // Add rule for xml
192  fileType = new FileType("text/xml", new Signature("<?xml", 0L), "", false); //NON-NLS
193  fileTypes.add(fileType);
194 
195  // Add rule for gzip
196  byteArray = DatatypeConverter.parseHexBinary("1F8B"); //NON-NLS
197  fileType = new FileType("application/x-gzip", new Signature(byteArray, 0L), "", false); //NON-NLS
198  fileTypes.add(fileType);
199 
200  // Add rule for .wk1
201  byteArray = DatatypeConverter.parseHexBinary("0000020006040600080000000000"); //NON-NLS
202  fileType = new FileType("application/x-123", new Signature(byteArray, 0L), "", false); //NON-NLS
203  fileTypes.add(fileType);
204 
205  // Add rule for Radiance image
206  byteArray = DatatypeConverter.parseHexBinary("233F52414449414E43450A");//NON-NLS
207  fileType = new FileType("image/vnd.radiance", new Signature(byteArray, 0L), "", false); //NON-NLS
208  fileTypes.add(fileType);
209 
210  // Add rule for .dcx image
211  byteArray = DatatypeConverter.parseHexBinary("B168DE3A"); //NON-NLS
212  fileType = new FileType("image/x-dcx", new Signature(byteArray, 0L), "", false); //NON-NLS
213  fileTypes.add(fileType);
214 
215  // Add rule for .ics image
216  fileType = new FileType("image/x-icns", new Signature("icns", 0L), "", false); //NON-NLS
217  fileTypes.add(fileType);
218 
219  // Add rule for .pict image
220  byteArray = DatatypeConverter.parseHexBinary("001102FF"); //NON-NLS
221  fileType = new FileType("image/x-pict", new Signature(byteArray, 522L), "", false); //NON-NLS
222  fileTypes.add(fileType);
223  byteArray = DatatypeConverter.parseHexBinary("1100"); //NON-NLS
224  fileType = new FileType("image/x-pict", new Signature(byteArray, 522L), "", false); //NON-NLS
225  fileTypes.add(fileType);
226 
227  // Add rule for .pam
228  fileType = new FileType("image/x-portable-arbitrarymap", new Signature("P7", 0L), "", false); //NON-NLS
229  fileTypes.add(fileType);
230 
231  // Add rule for .pfm
232  fileType = new FileType("image/x-portable-floatmap", new Signature("PF", 0L), "", false); //NON-NLS
233  fileTypes.add(fileType);
234  fileType = new FileType("image/x-portable-floatmap", new Signature("Pf", 0L), "", false); //NON-NLS
235  fileTypes.add(fileType);
236 
237  // Add rule for .tga
238  byteArray = DatatypeConverter.parseHexBinary("54525545564953494F4E2D5846494C452E00"); //NON-NLS
239  fileType = new FileType("image/x-tga", new Signature(byteArray, 17, false), "", false); //NON-NLS
240  fileTypes.add(fileType);
241  } // parseHexBinary() throws this if the argument passed in is not Hex
242  catch (IllegalArgumentException e) {
243  throw new UserDefinedFileTypesException("Error creating predefined file types", e); //
244  }
245  }
246 
254  private void loadUserDefinedFileTypes() throws UserDefinedFileTypesException {
255  try {
256  File serialized = new File(getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_SERIALIZATION_FILE));
257  if (serialized.exists()) {
258  for (FileType fileType : readFileTypesSerialized()) {
259  addUserDefinedFileType(fileType);
260  }
261  } else {
262  String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_XML_FILE);
263  File xmlFile = new File(filePath);
264  if (xmlFile.exists()) {
265  for (FileType fileType : XMLDefinitionsReader.readFileTypes(filePath)) {
266  addUserDefinedFileType(fileType);
267  }
268  }
269  }
270 
271  } catch (IOException | ParserConfigurationException | SAXException ex) {
275  fileTypes.clear();
276  userDefinedFileTypes.clear();
277  throwUserDefinedFileTypesException(ex, "UserDefinedFileTypesManager.loadFileTypes.errorMessage");
278  }
279  }
280 
287  private void addUserDefinedFileType(FileType fileType) {
288  userDefinedFileTypes.add(fileType);
289  fileTypes.add(fileType);
290  }
291 
298  synchronized void setUserDefinedFileTypes(List<FileType> newFileTypes) throws UserDefinedFileTypesException {
299  String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_SERIALIZATION_FILE);
300  writeFileTypes(newFileTypes, filePath);
301  }
302 
310  private static String getFileTypeDefinitionsFilePath(String fileName) {
311  Path filePath = Paths.get(PlatformUtil.getUserConfigDirectory(), fileName);
312  return filePath.toAbsolutePath().toString();
313  }
314 
327  private static void writeFileTypes(List<FileType> fileTypes, String filePath) throws UserDefinedFileTypesException {
328  try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) {
329  UserDefinedFileTypesSettings settings = new UserDefinedFileTypesSettings(fileTypes);
330  out.writeObject(settings);
331  } catch (IOException ex) {
332  throw new UserDefinedFileTypesException(String.format("Failed to write settings to %s", filePath), ex);
333  }
334  }
335 
345  private static List<FileType> readFileTypesSerialized() throws UserDefinedFileTypesException {
346  File serializedDefs = new File(getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_SERIALIZATION_FILE));
347  try {
348  try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(serializedDefs))) {
349  UserDefinedFileTypesSettings filesSetsSettings = (UserDefinedFileTypesSettings) in.readObject();
350  return filesSetsSettings.getUserDefinedFileTypes();
351  }
352  } catch (IOException | ClassNotFoundException ex) {
353  throw new UserDefinedFileTypesException("Couldn't read serialized settings.", ex);
354  }
355  }
356 
361  private static class XMLDefinitionsReader {
362 
370  private static List<FileType> readFileTypes(String filePath) throws IOException, SAXException, ParserConfigurationException {
371  List<FileType> fileTypes = new ArrayList<>();
372  /*
373  * RC: Commenting out the loadDocument overload that validates
374  * against the XSD is a temp fix for a failure to provide an upgrade
375  * path when the RelativeToStart attribute was added to the
376  * Signature element. The upgrade path can be supplied, but the plan
377  * is to replace the use of XML with object serialization for the
378  * settings, so it may not be worth the effort.
379  */
380  // private static final String FILE_TYPE_DEFINITIONS_SCHEMA_FILE = "FileTypes.xsd"; //NON-NLS
381  // Document doc = XMLUtil.loadDocument(filePath, UserDefinedFileTypesManager.class, FILE_TYPE_DEFINITIONS_SCHEMA_FILE);
382  Document doc = XMLUtil.loadDocument(filePath);
383  if (doc != null) {
384  Element fileTypesElem = doc.getDocumentElement();
385  if (fileTypesElem != null && fileTypesElem.getNodeName().equals(FILE_TYPES_TAG_NAME)) {
386  NodeList fileTypeElems = fileTypesElem.getElementsByTagName(FILE_TYPE_TAG_NAME);
387  for (int i = 0; i < fileTypeElems.getLength(); ++i) {
388  Element fileTypeElem = (Element) fileTypeElems.item(i);
389  FileType fileType = XMLDefinitionsReader.parseFileType(fileTypeElem);
390  fileTypes.add(fileType);
391  }
392  }
393  }
394  return fileTypes;
395  }
396 
407  private static FileType parseFileType(Element fileTypeElem) throws IllegalArgumentException, NumberFormatException {
408  String mimeType = XMLDefinitionsReader.parseMimeType(fileTypeElem);
409  Signature signature = XMLDefinitionsReader.parseSignature(fileTypeElem);
410  String filesSetName = XMLDefinitionsReader.parseInterestingFilesSet(fileTypeElem);
411  boolean alert = XMLDefinitionsReader.parseAlert(fileTypeElem);
412  return new FileType(mimeType, signature, filesSetName, alert);
413  }
414 
422  private static String parseMimeType(Element fileTypeElem) {
423  return getChildElementTextContent(fileTypeElem, MIME_TYPE_TAG_NAME);
424  }
425 
433  private static Signature parseSignature(Element fileTypeElem) throws IllegalArgumentException, NumberFormatException {
434  NodeList signatureElems = fileTypeElem.getElementsByTagName(SIGNATURE_TAG_NAME);
435  Element signatureElem = (Element) signatureElems.item(0);
436 
437  String sigTypeAttribute = signatureElem.getAttribute(SIGNATURE_TYPE_ATTRIBUTE);
438  Signature.Type signatureType = Signature.Type.valueOf(sigTypeAttribute);
439 
440  String sigBytesString = getChildElementTextContent(signatureElem, BYTES_TAG_NAME);
441  byte[] signatureBytes = DatatypeConverter.parseHexBinary(sigBytesString);
442 
443  Element offsetElem = (Element) signatureElem.getElementsByTagName(OFFSET_TAG_NAME).item(0);
444  String offsetString = offsetElem.getTextContent();
445  long offset = DatatypeConverter.parseLong(offsetString);
446 
447  boolean isRelativeToStart;
448  String relativeString = offsetElem.getAttribute(RELATIVE_ATTRIBUTE);
449  if (null == relativeString || relativeString.equals("")) {
450  isRelativeToStart = true;
451  } else {
452  isRelativeToStart = DatatypeConverter.parseBoolean(relativeString);
453  }
454 
455  return new Signature(signatureBytes, offset, signatureType, isRelativeToStart);
456  }
457 
465  private static String parseInterestingFilesSet(Element fileTypeElem) {
466  String filesSetName = "";
467  NodeList filesSetElems = fileTypeElem.getElementsByTagName(INTERESTING_FILES_SET_TAG_NAME);
468  if (filesSetElems.getLength() > 0) {
469  Element filesSetElem = (Element) filesSetElems.item(0);
470  filesSetName = filesSetElem.getTextContent();
471  }
472  return filesSetName;
473  }
474 
482  private static boolean parseAlert(Element fileTypeElem) {
483  String alertAttribute = fileTypeElem.getAttribute(ALERT_ATTRIBUTE);
484  return Boolean.parseBoolean(alertAttribute);
485  }
486 
495  private static String getChildElementTextContent(Element elem, String tagName) {
496  NodeList childElems = elem.getElementsByTagName(tagName);
497  Node childNode = childElems.item(0);
498  if (childNode == null) {
499  return null;
500  }
501  Element childElem = (Element) childNode;
502  return childElem.getTextContent();
503  }
504 
510  }
511 
512  }
513 
525  private void throwUserDefinedFileTypesException(Exception ex, String messageKey) throws UserDefinedFileTypesException {
526  String message = NbBundle.getMessage(UserDefinedFileTypesManager.class, messageKey);
527  logger.log(Level.SEVERE, message, ex);
528  throw new UserDefinedFileTypesException(message, ex);
529  }
530 
536  static class UserDefinedFileTypesException extends Exception {
537 
538  private static final long serialVersionUID = 1L;
539 
540  UserDefinedFileTypesException(String message) {
541  super(message);
542  }
543 
544  UserDefinedFileTypesException(String message, Throwable throwable) {
545  super(message, throwable);
546  }
547  }
548 
549 }
static< T > Document loadDocument(String docPath, Class< T > clazz, String schemaResourceName)
Definition: XMLUtil.java:87

Copyright © 2012-2015 Basis Technology. Generated on: Wed Apr 6 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.