/* * Autopsy Forensic Browser * * Copyright 2011-2016 Basis Technology Corp. * Contact: carrier <at> sleuthkit <dot> org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sleuthkit.autopsy.directorytree; import java.awt.Desktop; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.JOptionPane; import org.openide.nodes.Node; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.SlackFileNode; /** * Extracts a File object to a temporary file in the case directory, and then * tries to open it in the user's system with the default or user specified * associated application. */ public class ExternalViewerAction extends AbstractAction { private final static Logger logger = Logger.getLogger(ExternalViewerAction.class.getName()); private org.sleuthkit.datamodel.AbstractFile fileObject; private String fileObjectExt; final static String[] EXECUTABLE_EXT = {".exe", ".dll", ".com", ".bat", ".msi", ".reg", ".scr", ".cmd"}; //NON-NLS public ExternalViewerAction(String title, Node fileNode) { super(title); this.fileObject = fileNode.getLookup().lookup(org.sleuthkit.datamodel.AbstractFile.class); long size = fileObject.getSize(); String fileName = fileObject.getName(); int extPos = fileName.lastIndexOf('.'); boolean isExecutable = false; if (extPos != -1) { String extension = fileName.substring(extPos, fileName.length()).toLowerCase(); fileObjectExt = extension; for (int i = 0; i < EXECUTABLE_EXT.length; ++i) { if (EXECUTABLE_EXT[i].equals(extension)) { isExecutable = true; break; } } } else { fileObjectExt = ""; } // no point opening a file if it's empty, and java doesn't know how to // find an application for files without an extension // or if file is executable (for security reasons) // Also skip slack files since their extension is the original extension + "-slack" if (!(size > 0) || extPos == -1 || isExecutable || (fileNode instanceof SlackFileNode)) { this.setEnabled(false); } } @Override public void actionPerformed(ActionEvent e) { // Get the temp folder path of the case String tempPath = Case.getCurrentCase().getTempDirectory(); tempPath = tempPath + File.separator + this.fileObject.getName(); // create the temporary file File tempFile = new File(tempPath); if (tempFile.exists()) { tempFile.delete(); } try { tempFile.createNewFile(); ContentUtils.writeToFile(fileObject, tempFile); } catch (IOException ex) { logger.log(Level.WARNING, "Can't save to temporary file.", ex); //NON-NLS } ExternalViewerAction.openFile(fileObject.getMIMEType(), fileObjectExt, tempFile); // delete the temporary file on exit tempFile.deleteOnExit(); } /** * Opens a file, taking into account user preferences and then the default * associated application. * * @param mimeType MIME type of the file * @param ext extension of the file * @param file the file object */ @Messages({ "ExternalViewerAction.actionPerformed.failure.title=Open File Failure", "ExternalViewerAction.actionPerformed.failure.IO.message=There is no associated editor for files of this type or the associated application failed to launch.", "ExternalViewerAction.actionPerformed.failure.support.message=This platform (operating system) does not support opening a file in an editor this way.", "ExternalViewerAction.actionPerformed.failure.missingFile.message=The file no longer exists.", "ExternalViewerAction.actionPerformed.failure.permission.message=Permission to open the file was denied."}) public static void openFile(String mimeType, String ext, File file) { /** * Check if the file MIME type or extension exists in the user defined * settings. Otherwise open with the default associated application. */ String exePath = ExternalViewerRulesManager.getInstance().getExePathForName(mimeType); if (exePath.equals("")) { exePath = ExternalViewerRulesManager.getInstance().getExePathForName(ext); } if (!exePath.equals("")) { Runtime runtime = Runtime.getRuntime(); String[] s = new String[]{exePath, file.getAbsolutePath()}; try { runtime.exec(s); } catch (IOException ex) { logger.log(Level.WARNING, "Could not open the specified viewer for the given file: " + file.getName(), ex); //NON-NLS JOptionPane.showMessageDialog(null, Bundle.ExternalViewerAction_actionPerformed_failure_IO_message(), Bundle.ExternalViewerAction_actionPerformed_failure_title(), JOptionPane.ERROR_MESSAGE); } } else { try { Desktop.getDesktop().open(file); } catch (IOException ex) { logger.log(Level.WARNING, "Could not find a viewer for the given file: " + file.getName(), ex); //NON-NLS JOptionPane.showMessageDialog(null, Bundle.ExternalViewerAction_actionPerformed_failure_IO_message(), Bundle.ExternalViewerAction_actionPerformed_failure_title(), JOptionPane.ERROR_MESSAGE); } catch (UnsupportedOperationException ex) { logger.log(Level.WARNING, "Platform cannot open " + file.getName() + " in the defined editor.", ex); //NON-NLS JOptionPane.showMessageDialog(null, Bundle.ExternalViewerAction_actionPerformed_failure_support_message(), Bundle.ExternalViewerAction_actionPerformed_failure_title(), JOptionPane.ERROR_MESSAGE); } catch (IllegalArgumentException ex) { logger.log(Level.WARNING, "Could not find the given file: " + file.getName(), ex); //NON-NLS JOptionPane.showMessageDialog(null, Bundle.ExternalViewerAction_actionPerformed_failure_missingFile_message(), Bundle.ExternalViewerAction_actionPerformed_failure_title(), JOptionPane.ERROR_MESSAGE); } catch (SecurityException ex) { logger.log(Level.WARNING, "Could not get permission to open the given file: " + file.getName(), ex); //NON-NLS JOptionPane.showMessageDialog(null, Bundle.ExternalViewerAction_actionPerformed_failure_permission_message(), Bundle.ExternalViewerAction_actionPerformed_failure_title(), JOptionPane.ERROR_MESSAGE); } } } }