All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zaproxy.zap.view.ScanPanel2 Maven / Gradle / Ivy

Go to download

The Zed Attack Proxy (ZAP) is an easy to use integrated penetration testing tool for finding vulnerabilities in web applications. It is designed to be used by people with a wide range of security experience and as such is ideal for developers and functional testers who are new to penetration testing. ZAP provides automated scanners as well as a set of tools that allow you to find security vulnerabilities manually.

The newest version!
/*
 * Zed Attack Proxy (ZAP) and its related class files.
 *
 * ZAP is an HTTP/HTTPS proxy for assessing web application security.
 *
 * Copyright 2014 The ZAP Development Team
 *
 * 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.view;

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control;
import org.parosproxy.paros.control.Control.Mode;
import org.parosproxy.paros.extension.AbstractPanel;
import org.parosproxy.paros.model.Model;
import org.parosproxy.paros.model.Session;
import org.parosproxy.paros.view.View;
import org.zaproxy.zap.model.GenericScanner2;
import org.zaproxy.zap.model.ScanController;
import org.zaproxy.zap.utils.DisplayUtils;
import org.zaproxy.zap.utils.SortedComboBoxModel;

/*
 * This is a cleaner version of ScanPanel which doesn't mix functionality and the UI.
 * Implemented as a new set of classes for backwards compatibility with existing add-ons
 */
@SuppressWarnings("serial")
public abstract class ScanPanel2>
        extends AbstractPanel {
    private static final long serialVersionUID = 1L;

    protected enum Location {
        start,
        beforeSites,
        beforeButtons,
        beforeProgressBar,
        afterProgressBar
    }

    private final String prefix;

    private final SC controller;
    private JPanel panelCommand = null;
    private JToolBar panelToolbar = null;
    private JLabel scannedCountNameLabel = null;
    private JLabel foundCountNameLabel = null;

    private JComboBox> progressSelect = null;
    private SortedComboBoxModel> progressModel = new SortedComboBoxModel<>();
    private final ScanEntry selectScanEntry;

    private JButton stopScanButton = null;
    private ZapToggleButton pauseScanButton = null;
    private JButton newScanButton = null;
    private JButton clearScansButton = null;
    private JButton optionsButton = null;
    private JProgressBar progressBar = null;
    private ScanStatus scanStatus = null;
    private Mode mode = Control.getSingleton().getMode();

    private static final Logger LOGGER = LogManager.getLogger(ScanPanel2.class);

    /**
     * Constructs a {@code ScanPanel2} with the given message resources prefix, tab icon and scan
     * controller.
     *
     * @param prefix the prefix for the resource messages
     * @param icon the icon for the tab of the panel
     * @param controller the scan controller
     * @since 2.6.0
     */
    public ScanPanel2(String prefix, ImageIcon icon, SC controller) {
        super();
        this.prefix = prefix;
        this.controller = controller;
        selectScanEntry =
                new ScanEntry<>(Constant.messages.getString(prefix + ".toolbar.progress.select"));
        initialize(icon);
        LOGGER.debug("Constructor {}", prefix);
    }

    /** This method initializes this */
    private void initialize(ImageIcon icon) {
        this.setLayout(new CardLayout());
        if (Model.getSingleton().getOptionsParam().getViewParam().getWmUiHandlingOption() == 0) {
            this.setSize(474, 251);
        }
        this.setName(Constant.messages.getString(prefix + ".panel.title"));
        this.setIcon(icon);
        this.add(getPanelCommand(), prefix + ".panel");
        scanStatus = new ScanStatus(icon, Constant.messages.getString(prefix + ".panel.title"));

        if (View.isInitialised()) {
            View.getSingleton()
                    .getMainFrame()
                    .getMainFooterPanel()
                    .addFooterToolbarRightLabel(scanStatus.getCountLabel());
        }
    }

    /**
     * This method initializes panelCommand
     *
     * @return javax.swing.JPanel
     */
    private javax.swing.JPanel getPanelCommand() {
        if (panelCommand == null) {

            panelCommand = new javax.swing.JPanel();
            panelCommand.setLayout(new java.awt.GridBagLayout());
            panelCommand.setName(prefix + ".panel");

            GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
            GridBagConstraints gridBagConstraints2 = new GridBagConstraints();

            gridBagConstraints1.gridx = 0;
            gridBagConstraints1.gridy = 0;
            gridBagConstraints1.insets = new java.awt.Insets(2, 2, 2, 2);
            gridBagConstraints1.anchor = java.awt.GridBagConstraints.NORTHWEST;
            gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
            gridBagConstraints1.weightx = 1.0D;
            gridBagConstraints2.gridx = 0;
            gridBagConstraints2.gridy = 1;
            gridBagConstraints2.weightx = 1.0;
            gridBagConstraints2.weighty = 1.0;
            gridBagConstraints2.fill = java.awt.GridBagConstraints.BOTH;
            gridBagConstraints2.insets = new java.awt.Insets(0, 0, 0, 0);
            gridBagConstraints2.anchor = java.awt.GridBagConstraints.NORTHWEST;

            panelCommand.add(this.getPanelToolbar(), gridBagConstraints1);
            panelCommand.add(getWorkPanel(), gridBagConstraints2);
        }
        return panelCommand;
    }

    protected GridBagConstraints getGBC(int gridx, int gridy) {
        return this.getGBC(gridx, gridy, 0.0, new Insets(0, 2, 0, 0));
    }

    protected GridBagConstraints getGBC(int gridx, int gridy, double weightx, Insets insets) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = gridx;
        gbc.gridy = gridy;
        gbc.weightx = weightx;
        if (weightx > 0.0) {
            gbc.fill = java.awt.GridBagConstraints.HORIZONTAL;
        }
        gbc.insets = insets;
        gbc.anchor = java.awt.GridBagConstraints.WEST;
        return gbc;
    }

    private javax.swing.JToolBar getPanelToolbar() {
        if (panelToolbar == null) {

            panelToolbar = new javax.swing.JToolBar();
            panelToolbar.setLayout(new GridBagLayout());
            panelToolbar.setEnabled(true);
            panelToolbar.setFloatable(false);
            panelToolbar.setRollover(true);
            panelToolbar.setPreferredSize(new java.awt.Dimension(800, 30));
            panelToolbar.setName(prefix + ".toolbar");

            int x = 0;

            x = this.addToolBarElements(panelToolbar, Location.start, x);

            newScanButton = getNewScanButton();

            if (newScanButton != null) {
                panelToolbar.add(newScanButton, getGBC(x++, 0));
                newScanButton.setEnabled(!Mode.safe.equals(mode));
                panelToolbar.addSeparator();
                x++;
            }

            panelToolbar.add(
                    new JLabel(Constant.messages.getString(prefix + ".toolbar.progress.label")),
                    getGBC(x++, 0));
            panelToolbar.add(getProgressSelect(), getGBC(x++, 0));

            x = this.addToolBarElements(panelToolbar, Location.beforeButtons, x);

            panelToolbar.add(getPauseScanButton(), getGBC(x++, 0));
            panelToolbar.add(getStopScanButton(), getGBC(x++, 0));

            x = this.addToolBarElements(panelToolbar, Location.beforeProgressBar, x);

            panelToolbar.add(getProgressBar(), getGBC(x++, 0, 1.0, new Insets(0, 5, 0, 5)));

            panelToolbar.add(getClearScansButton(), getGBC(x++, 0));

            panelToolbar.add(getActiveScansNameLabel(), getGBC(x++, 0));
            panelToolbar.add(getActiveScansValueLabel(), getGBC(x++, 0));

            x = this.addToolBarElements(panelToolbar, Location.afterProgressBar, x);

            panelToolbar.add(new JLabel(), getGBC(x++, 0, 1.0, new Insets(0, 0, 0, 0))); // Spacer
            if (hasOptionsButton()) {
                panelToolbar.add(getOptionsButton(), getGBC(x++, 0));
            }
        }
        return panelToolbar;
    }

    /**
     * Tells whether or not the tool bar should have a button to open the Options dialogue.
     *
     * 

Returns {@code true} by default. * * @return {@code true} if the panel's tool bar should have an options button, {@code false} * otherwise. * @since 2.8.0 * @see #addToolBarElements(JToolBar, Location, int) */ protected boolean hasOptionsButton() { return true; } /** * Adds elements to the tool bar. The method is called while initializing the ScanPanel, at the * points specified by the {@link Location} enumeration. Should be overridden by all subclasses * that want to add new elements to the ScanPanel's tool bar. * *

The tool bar uses a {@code GridBagLayout}, so elements have to be added with a {@code * GridBagConstraints}. For this, the {@code getGBC} methods can be used. The {@code gridX} * parameter specifies the cell (as used in {@code GridBagConstraints.gridx}) of the current row * where the elements can be added. * *

The method must return the new coordinates of the current cell, after the elements have * been added. * *

Note: A button is added at the end of the tool bar to show the Options * dialogue, unless {@link #hasOptionsButton()} returns {@code false}. The name of the options * panel to show is obtained from the resource message with the key {@code prefix + * ".options.title"}. * * @param toolBar the tool bar * @param location the current location where elements will be added * @param gridX the x coordinates of the current cell in the {@code GridBagLayout} * @return the new coordinates of the current cell, after the elements have been added. * @see #getGBC(int, int) * @see #getGBC(int, int, double, Insets) * @see GridBagConstraints * @see GridBagLayout */ protected int addToolBarElements(JToolBar toolBar, Location location, int gridX) { return gridX; } private JLabel getActiveScansNameLabel() { if (scannedCountNameLabel == null) { scannedCountNameLabel = new javax.swing.JLabel(); scannedCountNameLabel.setText( Constant.messages.getString(prefix + ".toolbar.ascans.label")); } return scannedCountNameLabel; } private JLabel getActiveScansValueLabel() { if (foundCountNameLabel == null) { foundCountNameLabel = new javax.swing.JLabel(); foundCountNameLabel.setText(String.valueOf(controller.getActiveScans().size())); } return foundCountNameLabel; } private void setActiveScanLabelsEventHandler() { List ascans = controller.getActiveScans(); getActiveScansValueLabel().setText(String.valueOf(ascans.size())); StringBuilder sb = new StringBuilder(); sb.append(""); for (GS ascan : ascans) { sb.append(ascan.getDisplayName()); sb.append("
"); } sb.append(""); final String toolTip = sb.toString(); getActiveScansNameLabel().setToolTipText(toolTip); getActiveScansValueLabel().setToolTipText(toolTip); scanStatus.setScanCount(ascans.size()); this.getClearScansButton().setEnabled(controller.getAllScans().size() - ascans.size() > 0); } protected JProgressBar getProgressBar() { if (progressBar == null) { progressBar = new JProgressBar(0, 100); progressBar.setValue(0); progressBar.setSize(new Dimension(80, 20)); progressBar.setStringPainted(true); progressBar.setEnabled(false); } return progressBar; } protected JButton getStopScanButton() { if (stopScanButton == null) { stopScanButton = new JButton(); stopScanButton.setToolTipText( Constant.messages.getString(prefix + ".toolbar.button.stop")); stopScanButton.setIcon( DisplayUtils.getScaledIcon( new ImageIcon( ScanPanel2.class.getResource("/resource/icon/16/142.png")))); stopScanButton.setEnabled(false); stopScanButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { GS scanner = getSelectedScanner(); if (scanner != null) { controller.stopScan(scanner.getScanId()); } } }); } return stopScanButton; } protected JToggleButton getPauseScanButton() { if (pauseScanButton == null) { pauseScanButton = new ZapToggleButton(); pauseScanButton.setToolTipText( Constant.messages.getString(prefix + ".toolbar.button.pause")); pauseScanButton.setSelectedToolTipText( Constant.messages.getString(prefix + ".toolbar.button.unpause")); pauseScanButton.setIcon( DisplayUtils.getScaledIcon( new ImageIcon( ScanPanel2.class.getResource("/resource/icon/16/141.png")))); pauseScanButton.setRolloverIcon( DisplayUtils.getScaledIcon( new ImageIcon( ScanPanel2.class.getResource("/resource/icon/16/141.png")))); pauseScanButton.setSelectedIcon( DisplayUtils.getScaledIcon( new ImageIcon( ScanPanel2.class.getResource("/resource/icon/16/131.png")))); pauseScanButton.setRolloverSelectedIcon( DisplayUtils.getScaledIcon( new ImageIcon( ScanPanel2.class.getResource("/resource/icon/16/131.png")))); pauseScanButton.setEnabled(false); pauseScanButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { GS scanner = getSelectedScanner(); if (scanner != null) { if (pauseScanButton.isSelected()) { controller.pauseScan(scanner.getScanId()); } else { controller.resumeScan(scanner.getScanId()); } } } }); } return pauseScanButton; } private JButton getOptionsButton() { if (optionsButton == null) { optionsButton = new JButton(); optionsButton.setToolTipText( Constant.messages.getString(prefix + ".toolbar.button.options")); optionsButton.setIcon( DisplayUtils.getScaledIcon( new ImageIcon( ScanPanel2.class.getResource("/resource/icon/16/041.png")))); optionsButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Control.getSingleton() .getMenuToolsControl() .options( Constant.messages.getString(prefix + ".options.title")); } }); } return optionsButton; } private JButton getClearScansButton() { if (clearScansButton == null) { clearScansButton = new JButton(); clearScansButton.setToolTipText( Constant.messages.getString(prefix + ".toolbar.button.clear")); clearScansButton.setIcon( DisplayUtils.getScaledIcon( new ImageIcon( ScanPanel2.class.getResource( "/resource/icon/fugue/broom.png")))); clearScansButton.setEnabled(false); clearScansButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { clearFinishedScans(); } }); } return clearScansButton; } public void clearFinishedScans() { // Remove via controller int count = controller.removeFinishedScans(); if (count > 0) { // Some were removed - remove all and add back the remaining ones progressModel.removeAllElements(); progressModel.addElement(selectScanEntry); for (GS scan : controller.getAllScans()) { progressModel.addElement(new ScanEntry<>(scan)); } updateScannerUI(); } clearScansButton.setEnabled(false); } public GS getSelectedScanner() { Object selectedItem = progressModel.getSelectedItem(); if (selectedItem == null) { return null; } @SuppressWarnings("unchecked") GS scan = ((ScanEntry) selectedItem).getScan(); return scan; } protected JComboBox> getProgressSelect() { if (progressSelect == null) { progressSelect = new JComboBox<>(progressModel); progressSelect.addItem(selectScanEntry); progressSelect.setSelectedIndex(0); progressSelect.setEnabled(false); progressSelect.addActionListener( new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent e) { scannerSelected(getSelectedScanner()); } }); } return progressSelect; } public void updateScannerUI() { scannerSelected(this.getSelectedScanner()); } private void scannerSelected(GS scanner) { updateProgressAndButtonsState(scanner); switchView(scanner); } private void updateProgressAndButtonsState(GS scanner) { if (scanner == null || Mode.safe.equals(Control.getSingleton().getMode())) { // Disable everything getStopScanButton().setEnabled(false); getPauseScanButton().setEnabled(false); getPauseScanButton().setSelected(false); getProgressBar().setEnabled(false); } else if (scanner.isStopped()) { getStopScanButton().setEnabled(false); getPauseScanButton().setEnabled(false); getPauseScanButton().setSelected(false); getProgressBar().setEnabled(false); } else { getStopScanButton().setEnabled(true); getPauseScanButton().setEnabled(true); getPauseScanButton().setSelected(scanner.isPaused()); getProgressBar().setEnabled(true); } if (scanner != null) { getProgressBar().setValue(scanner.getProgress()); getProgressBar().setMaximum(scanner.getMaximum()); } else { getProgressBar().setValue(0); } } public void scanFinshed(final int id, final String host) { if (EventQueue.isDispatchThread()) { scanFinshedEventHandler(id, host); } else { try { EventQueue.invokeLater( new Runnable() { @Override public void run() { scanFinshedEventHandler(id, host); } }); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } } } private void scanFinshedEventHandler(int id, String host) { LOGGER.debug("scanFinished {} on {}", prefix, host); if (this.getSelectedScanner() != null && this.getSelectedScanner().getScanId() == id) { updateProgressAndButtonsState(getSelectedScanner()); } setActiveScanLabelsEventHandler(); } public void scanProgress( final int id, final String host, final int progress, final int maximum) { if (EventQueue.isDispatchThread()) { scanProgressEventHandler(id, host, progress, maximum); } else { EventQueue.invokeLater( new Runnable() { @Override public void run() { scanProgressEventHandler(id, host, progress, maximum); } }); } } private void scanProgressEventHandler(int id, String host, int progress, int maximum) { // log.debug("scanProgress " + prefix + " on " + currentSite + " " + progress); if (this.getSelectedScanner() != null && id == this.getSelectedScanner().getScanId()) { updateProgressAndButtonsState(getSelectedScanner()); } setActiveScanLabelsEventHandler(); } public void scannerStarted(GS scanner) { ScanEntry scanEntry = new ScanEntry<>(scanner); this.progressModel.addElement(scanEntry); this.getProgressSelect().setEnabled(true); this.getProgressSelect().setSelectedItem(scanEntry); this.trimProgressList(); this.scannerSelected(scanner); } public void trimProgressList() { /* * We only trim scans that have completed, so if the user kicks off a load of scans then * we could have a lot more in the list than the 'maximum' */ if (this.progressModel.getSize() > this.getNumberOfScansToShow() + 1) { // Trim past results - the +1 is for the initial 'select scan' message for (int i = 1; i < this.progressModel.getSize(); i++) { GS scan = this.progressModel.getElementAt(i).getScan(); if (scan != null && scan.isStopped()) { controller.removeScan(scan.getScanId()); this.progressModel.removeElementAt(i); if (this.progressModel.getSize() <= this.getNumberOfScansToShow() + 1) { // Have removed enough break; } // Need to remove more, but the indexes will have changed so go back 1 i--; } } } } public void reset() { LOGGER.debug("reset {}", prefix); progressModel.removeAllElements(); progressSelect.addItem(selectScanEntry); progressSelect.setSelectedIndex(0); clearScansButton.setEnabled(false); } public void sessionScopeChanged(Session session) {} public void sessionModeChanged(Mode mode) { if (newScanButton != null) { this.newScanButton.setEnabled(!Mode.safe.equals(mode)); } // This will handle the remaining changes needed updateScannerUI(); } protected void unload() { if (View.isInitialised()) { View.getSingleton() .getMainFrame() .getMainFooterPanel() .removeFooterToolbarRightLabel(scanStatus.getCountLabel()); } } protected SC getController() { return controller; } protected abstract Component getWorkPanel(); protected abstract void switchView(GS scanner); /* * Returns the scan button. Can return null if not relevant */ protected abstract JButton getNewScanButton(); protected abstract int getNumberOfScansToShow(); private static class ScanEntry implements Comparable> { private final GS scan; private final String label; public ScanEntry(String label) { this.scan = null; this.label = label; } public ScanEntry(GS scan) { this.scan = scan; this.label = scan.getScanId() + ": " + scan.getDisplayName(); } public GS getScan() { return scan; } @Override public int hashCode() { return 31 + ((scan == null) ? 0 : scan.getScanId()); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ScanEntry other = (ScanEntry) obj; if (scan == null) { return (other.scan == null); } else if (other.scan == null) { return false; } return scan.getScanId() == other.scan.getScanId(); } @Override public int compareTo(ScanEntry other) { if (other == null || other.scan == null) { return 1; } if (scan == null) { return -1; } return scan.getScanId() - other.scan.getScanId(); } @Override public String toString() { return label; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy