Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
XMLCaseManagement.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2012 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.casemodule;
20 
21 import java.io.*;
22 import java.text.DateFormat;
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25 import java.util.logging.Level;
26 import javax.swing.JOptionPane;
27 import javax.swing.JPanel;
28 import javax.xml.parsers.*;
29 import javax.xml.transform.*;
30 import javax.xml.transform.dom.*;
31 import javax.xml.transform.stream.*;
32 import org.openide.util.Exceptions;
33 import org.openide.util.NbBundle;
36 import org.w3c.dom.*;
37 import org.xml.sax.SAXException;
38 
49  class XMLCaseManagement implements CaseConfigFileInterface {
50 
51  final static String XSDFILE = "CaseSchema.xsd"; //NON-NLS
52  final static String TOP_ROOT_NAME = "AutopsyCase"; //NON-NLS
53  final static String CASE_ROOT_NAME = "Case"; //NON-NLS
54  // general metadata about the case file
55  final static String NAME = "Name"; //NON-NLS
56  final static String NUMBER = "Number"; //NON-NLS
57  final static String EXAMINER = "Examiner"; //NON-NLS
58  final static String CREATED_DATE_NAME = "CreatedDate"; //NON-NLS
59  final static String MODIFIED_DATE_NAME = "ModifiedDate"; //NON-NLS
60  final static String SCHEMA_VERSION_NAME = "SchemaVersion"; //NON-NLS
61  final static String AUTOPSY_CRVERSION_NAME = "AutopsyCreatedVersion"; //NON-NLS
62  final static String AUTOPSY_MVERSION_NAME = "AutopsySavedVersion"; //NON-NLS
63  // folders inside case directory
64  final static String LOG_FOLDER_NAME = "LogFolder"; //NON-NLS
65  final static String LOG_FOLDER_RELPATH = "Log"; //NON-NLS
66  final static String TEMP_FOLDER_NAME = "TempFolder"; //NON-NLS
67  final static String TEMP_FOLDER_RELPATH = "Temp"; //NON-NLS
68  final static String EXPORT_FOLDER_NAME = "ExportFolder"; //NON-NLS
69  final static String EXPORT_FOLDER_RELPATH = "Export"; //NON-NLS
70  final static String CACHE_FOLDER_NAME = "CacheFolder"; //NON-NLS
71  final static String CACHE_FOLDER_RELPATH = "Cache"; //NON-NLS
72  // folders attribute
73  final static String RELATIVE_NAME = "Relative"; // relevant path info NON-NLS
74  // folder attr values
75  final static String RELATIVE_TRUE = "true"; // if it's a relative path NON-NLS
76  final static String RELATIVE_FALSE = "false"; // if it's not a relative path NON-NLS
77  // the document
78  private Document doc;
79  // general info
80  private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
81  private String caseDirPath; // case directory path
82  private String caseName; // case name
83  private String caseNumber; // case number
84  private String examiner; // examiner name
85  private String schemaVersion = "1.0";
86  private String autopsySavedVersion;
87  // for error handling
88  private JPanel caller;
89  private String className = this.getClass().toString();
90  private static final Logger logger = Logger.getLogger(XMLCaseManagement.class.getName());
91 
95  XMLCaseManagement() {
96 // System.setProperty("netbeans.buildnumber", autopsyVer); // set the current autopsy version // moved to CoreComponents installer
97  autopsySavedVersion = System.getProperty("netbeans.buildnumber");
98  }
99 
105  private void setCaseDirPath(String givenPath) {
106  caseDirPath = givenPath; // change this to change the xml file if needed
107  }
108 
114  @Override
115  public void setCaseName(String givenCaseName) throws CaseActionException {
116  // change this to change the xml file if needed
117  Element nameElement = (Element) getCaseElement().getElementsByTagName(NAME).item(0);
118  nameElement.setTextContent(givenCaseName);
119  doc.normalize();
120 
121  // edit the modified data
122  String newDate = dateFormat.format(new Date());
123  Element rootEl = getRootElement();
124  rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
125 
126  writeFile();
127 
128  }
129 
135  @Override
136  public void setCaseNumber(String givenCaseNumber) throws CaseActionException {
137  // change this to change the xml file if needed
138  Element nameElement = (Element) getCaseElement().getElementsByTagName(NUMBER).item(0);
139  nameElement.setTextContent(String.valueOf(givenCaseNumber));
140  doc.normalize();
141 
142  // edit the modified data
143  String newDate = dateFormat.format(new Date());
144  Element rootEl = getRootElement();
145  rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
146 
147  writeFile();
148 
149  }
150 
156  @Override
157  public void setCaseExaminer(String givenExaminer) throws CaseActionException {
158  // change this to change the xml file if needed
159  Element nameElement = (Element) getCaseElement().getElementsByTagName(EXAMINER).item(0);
160  nameElement.setTextContent(givenExaminer);
161  doc.normalize();
162 
163  // edit the modified data
164  String newDate = dateFormat.format(new Date());
165  Element rootEl = getRootElement();
166  rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
167 
168  writeFile();
169 
170  }
171 
177  private void setName(String givenCaseName) {
178  caseName = givenCaseName; // change this to change the xml file if needed
179  }
180 
186  private void setNumber(String givenCaseNumber) {
187  caseNumber = givenCaseNumber; // change this to change the xml file if needed
188  }
189 
195  private void setExaminer(String givenExaminer) {
196  examiner = givenExaminer; // change this to change the xml file if needed
197  }
198 
204  @Override
205  public String getCaseName() {
206  if (doc == null) {
207  return "";
208  } else {
209  Element nameElement = (Element) getCaseElement().getElementsByTagName(NAME).item(0);
210  String result = nameElement.getTextContent();
211  return result;
212  }
213  }
214 
220  @Override
221  public String getCaseNumber() {
222  if (doc == null) {
223  return "";
224  } else {
225  Element numberElement = (Element) getCaseElement().getElementsByTagName(NUMBER).item(0);
226  String result = "-1";
227  if (numberElement != null) {
228  result = numberElement.getTextContent();
229  }
230  return result;
231  }
232  }
233 
239  @Override
240  public String getCaseExaminer() {
241  if (doc == null) {
242  return "";
243  } else {
244  Element examinerElement = (Element) getCaseElement().getElementsByTagName(EXAMINER).item(0);
245  String result = "";
246  if (examinerElement != null) {
247  result = examinerElement.getTextContent();
248  }
249  return result;
250  }
251  }
252 
258  public String getCaseDirectory() {
259  if (doc == null) {
260  return "";
261  } else {
262  return caseDirPath;
263  }
264  // Note: change this to get the case name from the xml file if needed
265  }
266 
272  private Element getRootElement() {
273  if (doc != null) {
274  return doc.getDocumentElement();
275  } else {
276  return null; // should throw error or exception
277  }
278  }
279 
285  protected String getCreatedDate() {
286  if (doc != null) {
287  Element crDateElement = (Element) getRootElement().getElementsByTagName(CREATED_DATE_NAME).item(0);
288  return crDateElement.getTextContent();
289  } else {
290  return ""; // should throw error or exception
291  }
292  }
293 
299  protected String getModifiedDate() {
300  if (doc != null) {
301  Element mDateElement = (Element) getRootElement().getElementsByTagName(MODIFIED_DATE_NAME).item(0);
302  return mDateElement.getTextContent();
303  } else {
304  return ""; // should throw error or exception
305  }
306  }
307 
313  protected String getCreatedVersion() {
314  if (doc != null) {
315  Element crVerElement = (Element) getRootElement().getElementsByTagName(AUTOPSY_CRVERSION_NAME).item(0);
316  return crVerElement.getTextContent();
317  } else {
318  return ""; // should throw error or exception
319  }
320  }
321 
328  protected String getSavedVersion() {
329  if (doc != null) {
330  Element mVerElement = (Element) getRootElement().getElementsByTagName(AUTOPSY_MVERSION_NAME).item(0);
331  return mVerElement.getTextContent();
332  } else {
333  return ""; // should throw error or exception
334  }
335  }
336 
342  protected String getSchemaVersion() {
343  if (doc != null) {
344  Element schemaVerElement = (Element) getRootElement().getElementsByTagName(SCHEMA_VERSION_NAME).item(0);
345  return schemaVerElement.getTextContent();
346  } else {
347  return ""; // should throw error or exception
348  }
349  }
350 
356  private Element getCaseElement() {
357  if (doc != null) {
358  return (Element) doc.getElementsByTagName(CASE_ROOT_NAME).item(0);
359  } else {
360  return null; // should throw error or exception
361  }
362  }
363 
369  protected String getLogDir() {
370  if (doc != null) {
371  Element logElement = (Element) getCaseElement().getElementsByTagName(LOG_FOLDER_NAME).item(0);
372  if (logElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
373  return caseDirPath + File.separator + logElement.getTextContent();
374  } else {
375  return logElement.getTextContent();
376  }
377  } else {
378  return ""; // should throw error or exception
379  }
380  }
381 
387  protected String getTempDir() {
388  if (doc != null) {
389  Element tempElement = (Element) getCaseElement().getElementsByTagName(TEMP_FOLDER_NAME).item(0);
390  if (tempElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
391  return caseDirPath + File.separator + tempElement.getTextContent();
392  } else {
393  return tempElement.getTextContent();
394  }
395  } else {
396  return ""; // should throw error or exception
397  }
398  }
399 
405  protected String getExportDir() {
406  if (doc != null) {
407  Element exportElement = (Element) getCaseElement().getElementsByTagName(EXPORT_FOLDER_NAME).item(0);
408  if (exportElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
409  return caseDirPath + File.separator + exportElement.getTextContent();
410  } else {
411  return exportElement.getTextContent();
412  }
413  } else {
414  return ""; // should throw error or exception
415  }
416  }
417 
423  protected String getCacheDir() {
424  if (doc != null) {
425  Element cacheElement = (Element) getCaseElement().getElementsByTagName(CACHE_FOLDER_NAME).item(0);
426  if (cacheElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
427  return caseDirPath + File.separator + cacheElement.getTextContent();
428  } else {
429  return cacheElement.getTextContent();
430  }
431  } else {
432  return ""; // should throw error or exception
433  }
434  }
435 
446  protected void create(String dirPath, String caseName, String examiner, String caseNumber) throws CaseActionException {
447  clear(); // clear the previous data
448 
449  // set the case Name and Directory and the parent directory
450  setCaseDirPath(dirPath);
451  setName(caseName);
452  setExaminer(examiner);
453  setNumber(caseNumber);
454  DocumentBuilder docBuilder;
455  DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
456 
457  // throw an error here
458  try {
459  docBuilder = docFactory.newDocumentBuilder();
460  } catch (ParserConfigurationException ex) {
461  clear();
462  throw new CaseActionException(
463  NbBundle.getMessage(this.getClass(), "XMLCaseManagement.create.exception.msg"), ex);
464  }
465 
466  doc = docBuilder.newDocument();
467  Element rootElement = doc.createElement(TOP_ROOT_NAME); // <AutopsyCase> ... </AutopsyCase>
468  doc.appendChild(rootElement);
469 
470  Element crDateElement = doc.createElement(CREATED_DATE_NAME); // <CreatedDate> ... </CreatedDate>
471  crDateElement.appendChild(doc.createTextNode(dateFormat.format(new Date())));
472  rootElement.appendChild(crDateElement);
473 
474  Element mDateElement = doc.createElement(MODIFIED_DATE_NAME); // <ModifedDate> ... </ModifedDate>
475  mDateElement.appendChild(doc.createTextNode(dateFormat.format(new Date())));
476  rootElement.appendChild(mDateElement);
477 
478  Element autVerElement = doc.createElement(AUTOPSY_CRVERSION_NAME); // <AutopsyVersion> ... </AutopsyVersion>
479  autVerElement.appendChild(doc.createTextNode(autopsySavedVersion));
480  rootElement.appendChild(autVerElement);
481 
482  Element autSavedVerElement = doc.createElement(AUTOPSY_MVERSION_NAME); // <AutopsySavedVersion> ... </AutopsySavedVersion>
483  autSavedVerElement.appendChild(doc.createTextNode(autopsySavedVersion));
484  rootElement.appendChild(autSavedVerElement);
485 
486  Element schVerElement = doc.createElement(SCHEMA_VERSION_NAME); // <SchemaVersion> ... </SchemaVersion>
487  schVerElement.appendChild(doc.createTextNode(schemaVersion));
488  rootElement.appendChild(schVerElement);
489 
490  Element caseElement = doc.createElement(CASE_ROOT_NAME); // <Case> ... </Case>
491  rootElement.appendChild(caseElement);
492 
493  Element nameElement = doc.createElement(NAME); // <Name> ... </Name>
494  nameElement.appendChild(doc.createTextNode(caseName));
495  caseElement.appendChild(nameElement);
496 
497  Element numberElement = doc.createElement(NUMBER); // <Number> ... </Number>
498  numberElement.appendChild(doc.createTextNode(String.valueOf(caseNumber)));
499  caseElement.appendChild(numberElement);
500 
501  Element examinerElement = doc.createElement(EXAMINER); // <Examiner> ... </Examiner>
502  examinerElement.appendChild(doc.createTextNode(examiner));
503  caseElement.appendChild(examinerElement);
504 
505  Element exportElement = doc.createElement(EXPORT_FOLDER_NAME); // <ExportFolder> ... </ExportFolder>
506  exportElement.appendChild(doc.createTextNode(EXPORT_FOLDER_RELPATH));
507  exportElement.setAttribute(RELATIVE_NAME, "true"); //NON-NLS
508  caseElement.appendChild(exportElement);
509 
510  Element logElement = doc.createElement(LOG_FOLDER_NAME); // <LogFolder> ... </LogFolder>
511  logElement.appendChild(doc.createTextNode(LOG_FOLDER_RELPATH));
512  logElement.setAttribute(RELATIVE_NAME, "true"); //NON-NLS
513  caseElement.appendChild(logElement);
514 
515  Element tempElement = doc.createElement(TEMP_FOLDER_NAME); // <TempFolder> ... </TempFolder>
516  tempElement.appendChild(doc.createTextNode(TEMP_FOLDER_RELPATH));
517  tempElement.setAttribute(RELATIVE_NAME, "true"); //NON-NLS
518  caseElement.appendChild(tempElement);
519 
520  Element cacheElement = doc.createElement(CACHE_FOLDER_NAME); // <CacheFolder> ... </CacheFolder>
521  cacheElement.appendChild(doc.createTextNode(CACHE_FOLDER_RELPATH));
522  cacheElement.setAttribute(RELATIVE_NAME, "true"); //NON-NLS
523  caseElement.appendChild(cacheElement);
524 
525  // write more code if needed ...
526  }
527 
533  @Override
534  public void writeFile() throws CaseActionException {
535  if (doc == null || caseName.equals("")) {
536  throw new CaseActionException(
537  NbBundle.getMessage(this.getClass(), "XMLCaseManagement.writeFile.exception.noCase.msg"));
538  }
539 
540  // Prepare the DOM document for writing
541  Source source = new DOMSource(doc);
542 
543  // Prepare the data for the output file
544  StringWriter sw = new StringWriter();
545  Result result = new StreamResult(sw);
546 
547  // Write the DOM document to the file
548  Transformer xformer;// = TransformerFactory.newInstance().newTransformer();
549  TransformerFactory tfactory = TransformerFactory.newInstance();
550 
551  try {
552  xformer = tfactory.newTransformer();
553  } catch (TransformerConfigurationException ex) {
554  logger.log(Level.SEVERE, "Could not setup tranformer and write case file"); //NON-NLS
555  throw new CaseActionException(
556  NbBundle.getMessage(this.getClass(), "XMLCaseManagement.writeFile.exception.errWriteToFile.msg"), ex);
557  }
558 
559  //Setup indenting to "pretty print"
560  xformer.setOutputProperty(OutputKeys.INDENT, "yes"); //NON-NLS
561  xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //NON-NLS
562 
563  try {
564  xformer.transform(source, result);
565  } catch (TransformerException ex) {
566  logger.log(Level.SEVERE, "Could not run tranformer and write case file"); //NON-NLS
567  throw new CaseActionException(
568  NbBundle.getMessage(this.getClass(), "XMLCaseManagement.writeFile.exception.errWriteToFile.msg"), ex);
569  }
570 
571  // preparing the output file
572  String xmlString = sw.toString();
573  File file = new File(caseDirPath + File.separator + caseName + ".aut");
574 
575  // write the file
576  try {
577  BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
578  bw.write(xmlString);
579  bw.flush();
580  bw.close();
581  } catch (IOException ex) {
582  logger.log(Level.SEVERE, "Error writing to case file"); //NON-NLS
583  throw new CaseActionException(
584  NbBundle.getMessage(this.getClass(), "XMLCaseManagement.writeFile.exception.errWriteToFile.msg"), ex);
585  }
586  }
587 
594  @Override
595  public void open(String conFilePath) throws CaseActionException {
596  clear();
597  File file = new File(conFilePath);
598 
599 
600  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
601  DocumentBuilder db = null;
602  try {
603  db = dbf.newDocumentBuilder();
604  doc = db.parse(file);
605  } catch (ParserConfigurationException ex) {
606  throw new CaseActionException(
607  NbBundle.getMessage(this.getClass(), "XMLCaseManagement.open.exception.errReadXMLFile.msg",
608  conFilePath), ex);
609  } catch (SAXException ex) {
610  throw new CaseActionException(
611  NbBundle.getMessage(this.getClass(), "XMLCaseManagement.open.exception.errReadXMLFile.msg",
612  conFilePath), ex);
613  } catch (IOException ex) {
614  throw new CaseActionException(
615  NbBundle.getMessage(this.getClass(), "XMLCaseManagement.open.exception.errReadXMLFile.msg",
616  conFilePath), ex);
617  }
618 
619 
620  doc.getDocumentElement().normalize();
621  doc.getDocumentElement().normalize();
622 
623  if (!XMLUtil.xmlIsValid(doc, XMLCaseManagement.class, XSDFILE)) {
624  logger.log(Level.WARNING, "Could not validate against [" + XSDFILE + "], results may not accurate"); //NON-NLS
625  }
626 
627  Element rootEl = doc.getDocumentElement();
628  String rootName = rootEl.getNodeName();
629 
630  // check if it's the autopsy case, if not, throws an error
631  if (!rootName.equals(TOP_ROOT_NAME)) {
632  // throw an error ...
633  clear();
634  JOptionPane.showMessageDialog(caller,
635  NbBundle.getMessage(this.getClass(),
636  "XMLCaseManagement.open.msgDlg.notAutCase.msg",
637  file.getName(), className),
638  NbBundle.getMessage(this.getClass(),
639  "XMLCaseManagement.open.msgDlg.notAutCase.title"),
640  JOptionPane.ERROR_MESSAGE);
641  } else {
642  /* Autopsy Created Version */
643  String createdVersion = getCreatedVersion(); // get the created version
644 
645  // check if it has the same autopsy version as the current one
646  if (!createdVersion.equals(autopsySavedVersion)) {
647  // if not the same version, update the saved version in the xml to the current version
648  getRootElement().getElementsByTagName(AUTOPSY_MVERSION_NAME).item(0).setTextContent(autopsySavedVersion);
649  }
650 
651  /* Schema Version */
652  String schemaVer = getSchemaVersion();
653  // check if it has the same schema version as the current one
654  if (!schemaVer.equals(schemaVersion)) {
655  // do something here if not the same version
656  // ... @Override
657  }
658 
659  // set the case Directory and Name
660  setCaseDirPath(file.getParent());
661  String fullFileName = file.getName();
662  String fileName = fullFileName.substring(0, fullFileName.lastIndexOf(".")); // remove the extension
663  setName(fileName);
664  }
665  }
666 
667 
674  @Override
675  public void close() throws CaseActionException {
676  writeFile(); // write any changes to xml
677  clear();
678  }
679 
685  private void clear() {
686  doc = null;
687  caseDirPath = "";
688  caseName = "";
689  caseNumber = "";
690  examiner = "";
691  }
692 }

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.