20 package org.sleuthkit.autopsy.report;
 
   22 import javax.swing.JPanel;
 
   24 import org.openide.util.NbBundle;
 
   30 import java.io.BufferedReader;
 
   31 import java.io.BufferedWriter;
 
   33 import java.io.FileOutputStream;
 
   34 import java.io.FileReader;
 
   35 import java.io.FileWriter;
 
   36 import java.io.IOException;
 
   37 import java.io.InputStream;
 
   38 import java.io.OutputStream;
 
   39 import java.util.logging.Level;
 
   40 import org.jdom2.Document;
 
   41 import org.jdom2.Element;
 
   42 import org.jdom2.Namespace;
 
   43 import org.jdom2.output.Format;
 
   44 import org.jdom2.output.XMLOutputter;
 
   45 import org.apache.commons.lang.StringEscapeUtils;
 
   50 class ReportKML 
implements GeneralReportModule {
 
   52     private static final Logger logger = Logger.getLogger(ReportKML.class.getName());
 
   53     private static ReportKML instance = null;
 
   54     private Case currentCase;
 
   55     private SleuthkitCase skCase;
 
   56     private String reportPath;
 
   63     public static synchronized ReportKML getDefault() {
 
   64         if (instance == null) {
 
   65             instance = 
new ReportKML();
 
   77     public void generateReport(String baseReportDir, ReportProgressPanel progressPanel) {
 
   80         progressPanel.setIndeterminate(
false);
 
   81         progressPanel.start();
 
   82         progressPanel.updateStatusLabel(NbBundle.getMessage(
this.getClass(), 
"ReportKML.progress.querying"));
 
   83         reportPath = baseReportDir + 
"ReportKML.kml"; 
 
   84         String reportPath2 = baseReportDir + 
"ReportKML.txt"; 
 
   85         currentCase = Case.getCurrentCase();
 
   86         skCase = currentCase.getSleuthkitCase();
 
   88         progressPanel.updateStatusLabel(NbBundle.getMessage(
this.getClass(), 
"ReportKML.progress.loading"));
 
   90         String ingestwarning = 
"";
 
   91         if (IngestManager.getInstance().isIngestRunning()) {
 
   92             ingestwarning = NbBundle.getMessage(this.getClass(), 
"ReportBodyFile.ingestWarning.text");
 
   94         progressPanel.setMaximumProgress(5);
 
   95         progressPanel.increment();
 
  101             try (BufferedWriter out = 
new BufferedWriter(
new FileWriter(reportPath2))) {
 
  107                 String imageName = 
"";
 
  110                 for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF)) {
 
  114                     String extractedToPath;
 
  115                     for (BlackboardAttribute attribute : artifact.getAttributes()) {
 
  116                         if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()) 
 
  119                             lat = attribute.getValueDouble();
 
  121                         if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()) 
 
  123                             lon = attribute.getValueDouble();
 
  126                     if (lon != 0 && lat != 0) {
 
  127                         aFile = artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID());
 
  130                             extractedToPath = reportPath + aFile.getName();
 
  131                             geoPath = extractedToPath;
 
  132                             f = 
new File(extractedToPath);
 
  134                             copyFileUsingStream(aFile, f);
 
  135                             imageName = aFile.getName();
 
  137                         out.write(String.valueOf(lat));
 
  139                         out.write(String.valueOf(lon));
 
  141                         out.write(String.valueOf(geoPath));
 
  143                         out.write(String.valueOf(imageName));
 
  149                 for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT)) {
 
  152                     for (BlackboardAttribute attribute : artifact.getAttributes()) {
 
  153                         if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()) 
 
  155                             lat = attribute.getValueDouble();
 
  157                         if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()) 
 
  159                             lon = attribute.getValueDouble();
 
  162                     if (lon != 0 && lat != 0) {
 
  163                         out.write(lat + 
";" + lon + 
"\n");
 
  167                 for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE)) {
 
  173                     String location = 
"";
 
  174                     for (BlackboardAttribute attribute : artifact.getAttributes()) {
 
  175                         if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID()) 
 
  177                             lat = attribute.getValueDouble();
 
  178                         } 
else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END.getTypeID()) 
 
  180                             destlat = attribute.getValueDouble();
 
  181                         } 
else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START.getTypeID()) 
 
  183                             lon = attribute.getValueDouble();
 
  184                         } 
else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END.getTypeID()) 
 
  186                             destlon = attribute.getValueDouble();
 
  187                         } 
else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()) 
 
  189                             name = attribute.getValueString();
 
  190                         } 
else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION.getTypeID()) 
 
  192                             location = attribute.getValueString();
 
  197                     String display = name;
 
  198                     if (display.isEmpty()) {
 
  202                     if (lon != 0 && lat != 0) {
 
  203                         out.write(NbBundle.getMessage(
this.getClass(), 
"ReportKML.latLongStartPoint", lat, lon, display));
 
  205                     if (destlat != 0 && destlon != 0) {
 
  206                         out.write(NbBundle.getMessage(
this.getClass(), 
"ReportKML.latLongEndPoint", destlat, destlon,
 
  213                 progressPanel.increment();
 
  217                 Namespace ns = Namespace.getNamespace(
"", 
"http://earth.google.com/kml/2.2"); 
 
  219                 Element kml = 
new Element(
"kml", ns); 
 
  220                 Document kmlDocument = 
new Document(kml);
 
  223                 Element document = 
new Element(
"Document", ns); 
 
  224                 kml.addContent(document);
 
  227                 Element name = 
new Element(
"name", ns); 
 
  228                 name.setText(
"Java Generated KML Document"); 
 
  229                 document.addContent(name);
 
  235                 Element style = 
new Element(
"Style", ns); 
 
  236                 style.setAttribute(
"id", 
"redIcon"); 
 
  237                 document.addContent(style);
 
  240                 Element iconStyle = 
new Element(
"IconStyle", ns); 
 
  241                 style.addContent(iconStyle);
 
  244                 Element color = 
new Element(
"color", ns); 
 
  245                 color.setText(
"990000ff"); 
 
  246                 iconStyle.addContent(color);
 
  249                 Element icon = 
new Element(
"Icon", ns); 
 
  250                 iconStyle.addContent(icon);
 
  253                 Element href = 
new Element(
"href", ns); 
 
  254                 href.setText(
"http://www.cs.mun.ca/~hoeber/teaching/cs4767/notes/02.1-kml/circle.png"); 
 
  255                 icon.addContent(href);
 
  256                 progressPanel.increment();
 
  262                 File file = 
new File(reportPath2);
 
  263                 try (BufferedReader reader = 
new BufferedReader(
new FileReader(file))) {
 
  264                     String line = reader.readLine();
 
  265                     while (line != null) {
 
  266                         String[] lineParts = line.split(
";");
 
  267                         if (lineParts.length > 1) {
 
  268                             String coordinates = lineParts[1].trim() + 
"," + lineParts[0].trim(); 
 
  270                             Element placemark = 
new Element(
"Placemark", ns); 
 
  271                             document.addContent(placemark);
 
  273                             if (lineParts.length == 4) {
 
  275                                 Element pmName = 
new Element(
"name", ns); 
 
  276                                 pmName.setText(lineParts[3].trim());
 
  277                                 placemark.addContent(pmName);
 
  279                                 String savedPath = lineParts[2].trim();
 
  280                                 if (savedPath.isEmpty() == 
false) {
 
  282                                     Element pmPath = 
new Element(
"Path", ns); 
 
  283                                     pmPath.setText(savedPath);
 
  284                                     placemark.addContent(pmPath);
 
  287                                     Element pmDescription = 
new Element(
"description", ns); 
 
  288                                     String xml = 
"<![CDATA[  \n" + 
" <img src='file:///" + savedPath + 
"' width='400' /><br/>  \n"; 
 
  289                                     StringEscapeUtils.unescapeXml(xml);
 
  290                                     pmDescription.setText(xml);
 
  291                                     placemark.addContent(pmDescription);
 
  296                             Element pmStyleUrl = 
new Element(
"styleUrl", ns); 
 
  297                             pmStyleUrl.setText(
"#redIcon"); 
 
  298                             placemark.addContent(pmStyleUrl);
 
  301                             Element pmPoint = 
new Element(
"Point", ns); 
 
  302                             placemark.addContent(pmPoint);
 
  305                             Element pmCoordinates = 
new Element(
"coordinates", ns); 
 
  307                             pmCoordinates.setText(coordinates);
 
  308                             pmPoint.addContent(pmCoordinates);
 
  313                         line = reader.readLine();
 
  317                 progressPanel.increment();
 
  321                 try (FileOutputStream writer = 
new FileOutputStream(reportPath)) {
 
  322                     XMLOutputter outputter = 
new XMLOutputter(Format.getPrettyFormat());
 
  323                     outputter.output(kmlDocument, writer);
 
  324                     Case.getCurrentCase().addReport(reportPath, NbBundle.getMessage(
this.getClass(),
 
  325                             "ReportKML.genReport.srcModuleName.text"), 
"");
 
  326                 } 
catch (IOException ex) {
 
  327                     logger.log(Level.WARNING, 
"Could not write the KML file.", ex); 
 
  328                 } 
catch (TskCoreException ex) {
 
  329                     String errorMessage = String.format(
"Error adding %s to case as a report", reportPath); 
 
  330                     logger.log(Level.SEVERE, errorMessage, ex);
 
  332             } 
catch (IOException ex) {
 
  333                 logger.log(Level.WARNING, 
"Could not write the KML report.", ex); 
 
  335             progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
 
  336         } 
catch (TskCoreException ex) {
 
  337             logger.log(Level.WARNING, 
"Failed to get the unique path.", ex); 
 
  339         progressPanel.increment();
 
  340         progressPanel.complete(ReportProgressPanel.ReportStatus.COMPLETE);
 
  343     public static void copyFileUsingStream(AbstractFile file, File jFile) 
throws IOException {
 
  344         InputStream is = 
new ReadContentInputStream(file);
 
  345         OutputStream os = 
new FileOutputStream(jFile);
 
  346         byte[] buffer = 
new byte[8192];
 
  349             while ((length = is.read(buffer)) != -1) {
 
  350                 os.write(buffer, 0, length);
 
  360     public String getName() {
 
  361         String name = NbBundle.getMessage(this.getClass(), 
"ReportKML.getName.text");
 
  366     public String getRelativeFilePath() {
 
  367         return "ReportKML.kml"; 
 
  371     public String getDescription() {
 
  372         String desc = NbBundle.getMessage(this.getClass(), 
"ReportKML.getDesc.text");
 
  377     public JPanel getConfigurationPanel() {