Autopsy  3.1
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 2014 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.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.UnsupportedEncodingException;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.logging.Level;
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;
44 import org.xml.sax.SAXException;
45 
61 final class UserDefinedFileTypesManager {
62 
63  private static final Logger logger = Logger.getLogger(UserDefinedFileTypesManager.class.getName());
64  private static final String FILE_TYPE_DEFINITIONS_SCHEMA_FILE = "FileTypes.xsd"; //NON-NLS
65  private static final String USER_DEFINED_TYPE_DEFINITIONS_FILE = "UserFileTypeDefinitions.xml"; //NON-NLS
66  private static final String FILE_TYPES_TAG_NAME = "FileTypes"; //NON-NLS
67  private static final String FILE_TYPE_TAG_NAME = "FileType"; //NON-NLS
68  private static final String MIME_TYPE_TAG_NAME = "MimeType"; //NON-NLS
69  private static final String SIGNATURE_TAG_NAME = "Signature"; //NON-NLS
70  private static final String SIGNATURE_TYPE_ATTRIBUTE = "type"; //NON-NLS
71  private static final String BYTES_TAG_NAME = "Bytes"; //NON-NLS
72  private static final String OFFSET_TAG_NAME = "Offset"; //NON-NLS
73  private static final String INTERESTING_FILES_SET_TAG_NAME = "InterestingFileSset"; //NON-NLS
74  private static final String ALERT_ATTRIBUTE = "alert"; //NON-NLS
75  private static final String ENCODING_FOR_XML_FILE = "UTF-8"; //NON-NLS
76  private static final String ASCII_ENCODING = "US-ASCII"; //NON-NLS
77  private static UserDefinedFileTypesManager instance;
78 
85  private final Map<String, FileType> userDefinedFileTypes = new HashMap<>();
86 
94  private final Map<String, FileType> fileTypes = new HashMap<>();
95 
103  synchronized static UserDefinedFileTypesManager getInstance() {
104  if (instance == null) {
105  instance = new UserDefinedFileTypesManager();
106  }
107  return instance;
108  }
109 
114  private UserDefinedFileTypesManager() {
115  }
116 
124  synchronized Map<String, FileType> getFileTypes() throws UserDefinedFileTypesException {
125  loadFileTypes();
126 
133  return new HashMap<>(fileTypes);
134  }
135 
143  synchronized Map<String, FileType> getUserDefinedFileTypes() throws UserDefinedFileTypesException {
144  loadFileTypes();
145 
152  return new HashMap<>(userDefinedFileTypes);
153  }
154 
162  private void loadFileTypes() throws UserDefinedFileTypesException {
163  fileTypes.clear();
164  userDefinedFileTypes.clear();
169  loadPredefinedFileTypes();
170  loadUserDefinedFileTypes();
171  }
172 
180  private void loadPredefinedFileTypes() throws UserDefinedFileTypesException {
181  try {
182  FileType fileType = new FileType("text/xml", new Signature("<?xml".getBytes(ASCII_ENCODING), 0L, FileType.Signature.Type.ASCII), "", false); //NON-NLS
183  fileTypes.put(fileType.getMimeType(), fileType);
184 
185  } catch (UnsupportedEncodingException ex) {
189  fileTypes.clear();
190  throwUserDefinedFileTypesException(ex, "UserDefinedFileTypesManager.loadFileTypes.errorMessage");
191  }
192  }
193 
201  private void loadUserDefinedFileTypes() throws UserDefinedFileTypesException {
202  try {
203  String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPE_DEFINITIONS_FILE);
204  File file = new File(filePath);
205  if (file.exists() && file.canRead()) {
206  for (FileType fileType : XmlReader.readFileTypes(filePath)) {
207  addUserDefinedFileType(fileType);
208  }
209  }
210 
211  } catch (IOException | ParserConfigurationException | SAXException ex) {
215  fileTypes.clear();
216  userDefinedFileTypes.clear();
217  throwUserDefinedFileTypesException(ex, "UserDefinedFileTypesManager.loadFileTypes.errorMessage");
218  }
219  }
220 
227  private void addUserDefinedFileType(FileType fileType) {
228  userDefinedFileTypes.put(fileType.getMimeType(), fileType);
229  fileTypes.put(fileType.getMimeType(), fileType);
230  }
231 
238  synchronized void setUserDefinedFileTypes(Map<String, FileType> newFileTypes) throws UserDefinedFileTypesException {
239  try {
240  String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPE_DEFINITIONS_FILE);
241  XmlWriter.writeFileTypes(newFileTypes.values(), filePath);
242  } catch (ParserConfigurationException | FileNotFoundException | UnsupportedEncodingException | TransformerException ex) {
243  throwUserDefinedFileTypesException(ex, "UserDefinedFileTypesManager.saveFileTypes.errorMessage");
244  } catch (IOException ex) {
245  throwUserDefinedFileTypesException(ex, "UserDefinedFileTypesManager.saveFileTypes.errorMessage");
246  }
247  }
248 
255  private static String getFileTypeDefinitionsFilePath(String fileName) {
256  Path filePath = Paths.get(PlatformUtil.getUserConfigDirectory(), fileName);
257  return filePath.toAbsolutePath().toString();
258  }
259 
264  private static class XmlWriter {
265 
277  private static void writeFileTypes(Collection<FileType> fileTypes, String filePath) throws ParserConfigurationException, IOException, FileNotFoundException, UnsupportedEncodingException, TransformerException {
278  Document doc = XMLUtil.createDocument();
279  Element fileTypesElem = doc.createElement(FILE_TYPES_TAG_NAME);
280  doc.appendChild(fileTypesElem);
281  for (FileType fileType : fileTypes) {
282  Element fileTypeElem = XmlWriter.createFileTypeElement(fileType, doc);
283  fileTypesElem.appendChild(fileTypeElem);
284  }
285  XMLUtil.saveDocument(doc, ENCODING_FOR_XML_FILE, filePath);
286  }
287 
295  private static Element createFileTypeElement(FileType fileType, Document doc) {
296  Element fileTypeElem = doc.createElement(FILE_TYPE_TAG_NAME);
297  XmlWriter.addMimeTypeElement(fileType, fileTypeElem, doc);
298  XmlWriter.addSignatureElement(fileType, fileTypeElem, doc);
299  XmlWriter.addInterestingFilesSetElement(fileType, fileTypeElem, doc);
300  XmlWriter.addAlertAttribute(fileType, fileTypeElem);
301  return fileTypeElem;
302  }
303 
311  private static void addMimeTypeElement(FileType fileType, Element fileTypeElem, Document doc) {
312  Element typeNameElem = doc.createElement(MIME_TYPE_TAG_NAME);
313  typeNameElem.setTextContent(fileType.getMimeType());
314  fileTypeElem.appendChild(typeNameElem);
315  }
316 
324  private static void addSignatureElement(FileType fileType, Element fileTypeElem, Document doc) {
325  Signature signature = fileType.getSignature();
326  Element signatureElem = doc.createElement(SIGNATURE_TAG_NAME);
327 
328  Element bytesElem = doc.createElement(BYTES_TAG_NAME);
329  bytesElem.setTextContent(DatatypeConverter.printHexBinary(signature.getSignatureBytes()));
330  signatureElem.appendChild(bytesElem);
331 
332  Element offsetElem = doc.createElement(OFFSET_TAG_NAME);
333  offsetElem.setTextContent(DatatypeConverter.printLong(signature.getOffset()));
334  signatureElem.appendChild(offsetElem);
335 
336  signatureElem.setAttribute(SIGNATURE_TYPE_ATTRIBUTE, signature.getType().toString());
337  fileTypeElem.appendChild(signatureElem);
338  }
339 
347  private static void addInterestingFilesSetElement(FileType fileType, Element fileTypeElem, Document doc) {
348  if (!fileType.getFilesSetName().isEmpty()) {
349  Element filesSetElem = doc.createElement(INTERESTING_FILES_SET_TAG_NAME);
350  filesSetElem.setTextContent(fileType.getFilesSetName());
351  fileTypeElem.appendChild(filesSetElem);
352  }
353  }
354 
361  private static void addAlertAttribute(FileType fileType, Element fileTypeElem) {
362  fileTypeElem.setAttribute(ALERT_ATTRIBUTE, Boolean.toString(fileType.alertOnMatch()));
363  }
364 
365  }
366 
371  private static class XmlReader {
372 
379  private static List<FileType> readFileTypes(String filePath) throws IOException, ParserConfigurationException, SAXException {
380  List<FileType> fileTypes = new ArrayList<>();
381  Document doc = XMLUtil.loadDocument(filePath, UserDefinedFileTypesManager.class, FILE_TYPE_DEFINITIONS_SCHEMA_FILE);
382  if (doc != null) {
383  Element fileTypesElem = doc.getDocumentElement();
384  if (fileTypesElem != null && fileTypesElem.getNodeName().equals(FILE_TYPES_TAG_NAME)) {
385  NodeList fileTypeElems = fileTypesElem.getElementsByTagName(FILE_TYPE_TAG_NAME);
386  for (int i = 0; i < fileTypeElems.getLength(); ++i) {
387  Element fileTypeElem = (Element) fileTypeElems.item(i);
388  FileType fileType = XmlReader.parseFileType(fileTypeElem);
389  fileTypes.add(fileType);
390  }
391  }
392  }
393  return fileTypes;
394  }
395 
404  private static FileType parseFileType(Element fileTypeElem) throws IllegalArgumentException, NumberFormatException {
405  String mimeType = XmlReader.parseMimeType(fileTypeElem);
406  Signature signature = XmlReader.parseSignature(fileTypeElem);
407  String filesSetName = XmlReader.parseInterestingFilesSet(fileTypeElem);
408  boolean alert = XmlReader.parseAlert(fileTypeElem);
409  return new FileType(mimeType, signature, filesSetName, alert);
410  }
411 
418  private static String parseMimeType(Element fileTypeElem) {
419  return getChildElementTextContent(fileTypeElem, MIME_TYPE_TAG_NAME);
420  }
421 
428  private static Signature parseSignature(Element fileTypeElem) throws IllegalArgumentException, NumberFormatException {
429  NodeList signatureElems = fileTypeElem.getElementsByTagName(SIGNATURE_TAG_NAME);
430  Element signatureElem = (Element) signatureElems.item(0);
431 
432  String sigTypeAttribute = signatureElem.getAttribute(SIGNATURE_TYPE_ATTRIBUTE);
433  Signature.Type signatureType = Signature.Type.valueOf(sigTypeAttribute);
434 
435  String sigBytesString = getChildElementTextContent(signatureElem, BYTES_TAG_NAME);
436  byte[] signatureBytes = DatatypeConverter.parseHexBinary(sigBytesString);
437 
438  String offsetString = getChildElementTextContent(signatureElem, OFFSET_TAG_NAME);
439  long offset = DatatypeConverter.parseLong(offsetString);
440 
441  return new Signature(signatureBytes, offset, signatureType);
442  }
443 
450  private static String parseInterestingFilesSet(Element fileTypeElem) {
451  String filesSetName = "";
452  NodeList filesSetElems = fileTypeElem.getElementsByTagName(INTERESTING_FILES_SET_TAG_NAME);
453  if (filesSetElems.getLength() > 0) {
454  Element filesSetElem = (Element) filesSetElems.item(0);
455  filesSetName = filesSetElem.getTextContent();
456  }
457  return filesSetName;
458  }
459 
466  private static boolean parseAlert(Element fileTypeElem) {
467  String alertAttribute = fileTypeElem.getAttribute(ALERT_ATTRIBUTE);
468  return Boolean.parseBoolean(alertAttribute);
469  }
470 
478  private static String getChildElementTextContent(Element elem, String tagName) {
479  NodeList childElems = elem.getElementsByTagName(tagName);
480  Element childElem = (Element) childElems.item(0);
481  return childElem.getTextContent();
482  }
483 
484  }
485 
496  private void throwUserDefinedFileTypesException(Exception ex, String messageKey) throws UserDefinedFileTypesException {
497  String message = NbBundle.getMessage(UserDefinedFileTypesManager.class, messageKey);
498  logger.log(Level.SEVERE, message, ex);
499  throw new UserDefinedFileTypesException(message, ex);
500  }
501 
507  static class UserDefinedFileTypesException extends Exception {
508 
509  UserDefinedFileTypesException(String message) {
510  super(message);
511  }
512 
513  UserDefinedFileTypesException(String message, Throwable throwable) {
514  super(message, throwable);
515  }
516  }
517 
518 }
static void addSignatureElement(FileType fileType, Element fileTypeElem, Document doc)
static void writeFileTypes(Collection< FileType > fileTypes, String filePath)
static void addMimeTypeElement(FileType fileType, Element fileTypeElem, Document doc)
static void addInterestingFilesSetElement(FileType fileType, Element fileTypeElem, Document doc)
static< T > Document loadDocument(String docPath, Class< T > clazz, String schemaResourceName)
Definition: XMLUtil.java:83
static void saveDocument(final Document doc, String encoding, String docPath)
Definition: XMLUtil.java:136

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.