/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Copyright 2010 psiinon@gmail.com * * 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.zaproxy.zap.extension.ascan; import java.awt.Event; import java.awt.EventQueue; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.lang.reflect.InvocationTargetException; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JToolBar; import javax.swing.KeyStroke; import org.apache.log4j.Logger; import org.parosproxy.paros.Constant; import org.parosproxy.paros.core.scanner.Alert; import org.parosproxy.paros.core.scanner.HostProcess; import org.parosproxy.paros.core.scanner.ScannerListener; import org.parosproxy.paros.network.HttpMessage; import org.parosproxy.paros.view.View; import org.zaproxy.zap.model.ScanController; import org.zaproxy.zap.model.ScanListenner2; import org.zaproxy.zap.utils.DisplayUtils; import org.zaproxy.zap.view.ScanPanel2; import org.zaproxy.zap.view.table.HistoryReferencesTable; public class ActiveScanPanel extends ScanPanel2<ActiveScan, ScanController<ActiveScan>> implements ScanListenner2, ScannerListener { private static final Logger LOGGER = Logger.getLogger(ActiveScanPanel.class); private static final long serialVersionUID = 1L; /** * @deprecated (2.3.0) Replaced by {@link #MESSAGE_CONTAINER_NAME}. */ @Deprecated public static final String PANEL_NAME = "ascan"; /** * The name of the active scan HTTP messages container. * * @see org.zaproxy.zap.view.messagecontainer.http.HttpMessageContainer */ public static final String MESSAGE_CONTAINER_NAME = "ActiveScanMessageContainer"; private static final String ZERO_REQUESTS_LABEL_TEXT = "0"; private static final ActiveScanTableModel EMPTY_RESULTS_MODEL = new ActiveScanTableModel(); private ExtensionActiveScan extension; private JScrollPane jScrollPane; private HistoryReferencesTable messagesTable; private JButton policyButton = null; private JButton scanButton = null; private JButton progressButton; private JLabel numRequests; /** * Constructs an {@code ActiveScanPanel} with the given extension. * * @param extension the active scan extension, to access options and start scans */ public ActiveScanPanel(ExtensionActiveScan extension) { // 'fire' icon super("ascan", new ImageIcon(ActiveScanPanel.class.getResource("/resource/icon/16/093.png")), extension); this.extension = extension; this.setDefaultAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | Event.ALT_MASK | Event.SHIFT_MASK, false)); this.setMnemonic(Constant.messages.getChar("ascan.panel.mnemonic")); } @Override protected int addToolBarElements(JToolBar panelToolbar, Location loc, int x) { // Override to add elements into the toolbar if (Location.start.equals(loc)) { panelToolbar.add(getPolicyManagerButton(), getGBC(x++,0)); } if (Location.beforeProgressBar.equals(loc)) { panelToolbar.add(getProgressButton(), getGBC(x++,0)); } if (Location.afterProgressBar.equals(loc)) { panelToolbar.add(new JToolBar.Separator(), getGBC(x++, 0)); panelToolbar.add(new JLabel(Constant.messages.getString("ascan.toolbar.requests.label")), getGBC(x++,0)); panelToolbar.add(getNumRequests(), getGBC(x++,0)); } return x; } private JButton getPolicyManagerButton() { if (policyButton == null) { policyButton = new JButton(); policyButton.setToolTipText(Constant.messages.getString("menu.analyse.scanPolicy")); policyButton.setIcon(DisplayUtils.getScaledIcon(new ImageIcon(ActiveScanPanel.class.getResource("/resource/icon/fugue/equalizer.png")))); policyButton.addActionListener(new ActionListener () { @Override public void actionPerformed(ActionEvent e) { extension.showPolicyManagerDialog(); } }); } return policyButton; } @Override public JButton getNewScanButton() { if (scanButton == null) { scanButton = new JButton(Constant.messages.getString("ascan.toolbar.button.new")); scanButton.setIcon(DisplayUtils.getScaledIcon(new ImageIcon(ActiveScanPanel.class.getResource("/resource/icon/16/093.png")))); scanButton.addActionListener(new ActionListener () { @Override public void actionPerformed(ActionEvent e) { extension.showCustomScanDialog(null); } }); } return scanButton; } private JButton getProgressButton() { if (progressButton == null) { progressButton = new JButton(); progressButton.setEnabled(false); progressButton.setToolTipText(Constant.messages.getString("ascan.toolbar.button.progress")); progressButton.setIcon(DisplayUtils.getScaledIcon(new ImageIcon(ActiveScanPanel.class.getResource("/resource/icon/fugue/system-monitor.png")))); progressButton.addActionListener(new ActionListener () { @Override public void actionPerformed(ActionEvent e) { showScanProgressDialog(); } }); } return progressButton; } private JLabel getNumRequests() { if (numRequests == null) { numRequests = new JLabel(ZERO_REQUESTS_LABEL_TEXT); } return numRequests; } private void showScanProgressDialog() { ActiveScan scan = this.getSelectedScanner(); if (scan != null) { ScanProgressDialog spp = new ScanProgressDialog(View.getSingleton().getMainFrame(), scan.getDisplayName(), this.extension); spp.setActiveScan(scan); spp.setVisible(true); } } @Override public void clearFinishedScans() { if (extension.getScannerParam().isPromptToClearFinishedScans()) { // Prompt to double check int res = View.getSingleton().showConfirmDontPromptDialog( View.getSingleton().getMainFrame(), Constant.messages.getString("ascan.toolbar.confirm.clear")); if (View.getSingleton().isDontPromptLastDialogChosen()) { extension.getScannerParam().setPromptToClearFinishedScans(false); } if (res != JOptionPane.YES_OPTION) { return; } } super.clearFinishedScans(); } @Override protected JScrollPane getWorkPanel() { if (jScrollPane == null) { jScrollPane = new JScrollPane(); jScrollPane.setViewportView(getMessagesTable()); } return jScrollPane; } private void resetMessagesTable() { getMessagesTable().setModel(EMPTY_RESULTS_MODEL); } private HistoryReferencesTable getMessagesTable() { if (messagesTable == null) { messagesTable = new HistoryReferencesTable(EMPTY_RESULTS_MODEL); messagesTable.setName(MESSAGE_CONTAINER_NAME); messagesTable.setAutoCreateColumnsFromModel(false); } return messagesTable; } @Override public void switchView(final ActiveScan scanner) { if (View.isInitialised() && !EventQueue.isDispatchThread()) { try { EventQueue.invokeAndWait(new Runnable() { @Override public void run() { switchView(scanner); } }); } catch (InvocationTargetException | InterruptedException e) { LOGGER.error("Failed to switch view: " + e.getMessage(), e); } return; } if (scanner != null) { getMessagesTable().setModel(scanner.getMessagesTableModel()); this.getNumRequests().setText(Integer.toString(scanner.getTotalRequests())); this.getProgressButton().setEnabled(true); if (scanner instanceof AttackScan) { // Its the custom scanner - none of these controls make sense this.getProgressBar().setEnabled(false); this.getProgressButton().setEnabled(false); this.getPauseScanButton().setEnabled(false); this.getStopScanButton().setEnabled(false); } } else { resetMessagesTable(); this.getNumRequests().setText(ZERO_REQUESTS_LABEL_TEXT); this.getProgressButton().setEnabled(false); } } @Override public void alertFound(Alert alert) { // Nothing to do, ActiveScanController (through ActiveScan) already raises the alerts. } @Override public void hostComplete(int id, String hostAndPort) { this.scanFinshed(id, hostAndPort); } @Override public void hostNewScan(int id, String hostAndPort, HostProcess hostThread) { } @Override public void hostProgress(int id, String hostAndPort, String msg, int percentage) { this.scanProgress(id, hostAndPort, percentage, 100); updateRequestCount(); } @Override public void scannerComplete(int id) { this.scanFinshed(id, this.getName()); } private void updateRequestCount() { ActiveScan ac = this.getSelectedScanner(); if (ac != null) { this.getNumRequests().setText(Integer.toString(ac.getTotalRequests())); } } @Override public void notifyNewMessage(HttpMessage msg) { } @Override public void reset() { super.reset(); this.resetMessagesTable(); this.getProgressButton().setEnabled(false); } @Override protected int getNumberOfScansToShow() { return extension.getScannerParam().getMaxScansInUI(); } }