<commit_before>/*
 * Zed Attack Proxy (ZAP) and its related class files.
 * 
 * ZAP is an HTTP/HTTPS proxy for assessing web application security.
 * 
 * Copyright 2010 <EMAIL>
 * 
 * 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.Dimension;
import java.awt.Event;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.InvalidParameterException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control;
import org.parosproxy.paros.control.Control.Mode;
import org.parosproxy.paros.core.scanner.ScannerParam;
import org.parosproxy.paros.extension.CommandLineArgument;
import org.parosproxy.paros.extension.CommandLineListener;
import org.parosproxy.paros.extension.Extension;
import org.parosproxy.paros.extension.ExtensionAdaptor;
import org.parosproxy.paros.extension.ExtensionHook;
import org.parosproxy.paros.extension.SessionChangedListener;
import org.parosproxy.paros.extension.history.ProxyListenerLog;
import org.parosproxy.paros.model.Model;
import org.parosproxy.paros.model.Session;
import org.parosproxy.paros.model.SiteNode;
import org.parosproxy.paros.view.AbstractParamPanel;
import org.parosproxy.paros.view.View;
import org.zaproxy.zap.ZAP;
import org.zaproxy.zap.extension.alert.ExtensionAlert;
import org.zaproxy.zap.extension.help.ExtensionHelp;
import org.zaproxy.zap.extension.script.ExtensionScript;
import org.zaproxy.zap.extension.script.ScriptType;
import org.zaproxy.zap.model.ScanController;
import org.zaproxy.zap.model.StructuralNode;
import org.zaproxy.zap.model.StructuralSiteNode;
import org.zaproxy.zap.model.Target;
import org.zaproxy.zap.users.User;
import org.zaproxy.zap.view.ZapMenuItem;

public class ExtensionActiveScan extends ExtensionAdaptor implements
        SessionChangedListener, CommandLineListener, ScanController<ActiveScan> {

    private static final Logger logger = Logger.getLogger(ExtensionActiveScan.class);
    private static final int ARG_SCAN_IDX = 0;
    
    public static final String NAME = "ExtensionActiveScan";
    
    private static final ImageIcon SCRIPT_ICON_ACTIVE
            = new ImageIcon(ZAP.class.getResource("/resource/icon/16/script-ascan.png"));
    
    private static final ImageIcon SCRIPT_ICON_VARIANT
            = new ImageIcon(ZAP.class.getResource("/resource/icon/16/script-variant.png"));

    public static final String SCRIPT_TYPE_ACTIVE = "active";
    public static final String SCRIPT_TYPE_VARIANT = "variant";

    //Could be after the last one that saves the HttpMessage, as this ProxyListener doesn't change the HttpMessage.
    public static final int PROXY_LISTENER_ORDER = ProxyListenerLog.PROXY_LISTENER_ORDER + 1;
    private static final List<Class<? extends Extension>> DEPENDENCIES;
    
    private AttackModeScanner attackModeScanner;
    
    private ActiveScanController ascanController = null;

    static {
        List<Class<? extends Extension>> dep = new ArrayList<>(1);
        dep.add(ExtensionAlert.class);

        DEPENDENCIES = Collections.unmodifiableList(dep);
    }

    private ZapMenuItem menuItemPolicy = null;
    private ZapMenuItem menuItemCustomScan = null;
    private OptionsScannerPanel optionsScannerPanel = null;
    private OptionsVariantPanel optionsVariantPanel = null;
    private ActiveScanPanel activeScanPanel = null;
    private ScannerParam scannerParam = null;
    private final CommandLineArgument[] arguments = new CommandLineArgument[1];
    private final List<AbstractParamPanel> policyPanels = new ArrayList<>();
	private JButton policyButton = null;
	private CustomScanDialog customScanDialog = null;
	private PolicyManagerDialog policyManagerDialog = null;
	private PolicyManager policyManager = null;
    private List<CustomScanPanel> customScanPanels = new ArrayList<CustomScanPanel>();
    
    private List<String> excludeList = Collections.emptyList();

	private ActiveScanAPI activeScanApi;

    public ExtensionActiveScan() {
        super(NAME);
        this.setOrder(28);
        policyManager = new PolicyManager(this);
        ascanController = new ActiveScanController(this);

    }
    
    @Override
    public String getUIName() {
    	return Constant.messages.getString("ascan.name");
    }
    
    @Override
    public void postInit() {
    	policyManager.init();

		if (Control.getSingleton().getMode().equals(Mode.attack)) {
			if (View.isInitialised() && ! this.getScannerParam().isAllowAttackOnStart()) {
				// Disable attack mode for safeties sake (when running with the UI)
	   			View.getSingleton().getMainFrame().getMainToolbarPanel().setMode(Mode.standard);
			} else {
				// Needed to make sure the attackModeScanner starts up
				this.attackModeScanner.sessionModeChanged(Control.getSingleton().getMode());
			}
		}
    }

    @Override
    public void hook(ExtensionHook extensionHook) {
        super.hook(extensionHook);

        attackModeScanner = new AttackModeScanner(this);

        if (getView() != null) {
            extensionHook.getHookMenu().addAnalyseMenuItem(getMenuItemPolicy());
            extensionHook.getHookMenu().addToolsMenuItem(getMenuItemCustomScan());

            extensionHook.getHookView().addStatusPanel(getActiveScanPanel());
            extensionHook.getHookView().addOptionPanel(getOptionsScannerPanel());
            extensionHook.getHookView().addOptionPanel(getOptionsVariantPanel());

	        extensionHook.getHookView().addMainToolBarComponent(this.getPolicyButton());
			View.getSingleton().getMainFrame().getMainFooterPanel().addFooterToolbarRightLabel(
					attackModeScanner.getScanStatus().getCountLabel());

            ExtensionHelp.enableHelpKey(getActiveScanPanel(), "ui.tabs.ascan");
        }
        
        extensionHook.addSessionListener(this);

        extensionHook.addOptionsParamSet(getScannerParam());
        // TODO this isnt currently implemented
        //extensionHook.addCommandLine(getCommandLineArguments());

        ExtensionScript extScript = (ExtensionScript) Control.getSingleton().getExtensionLoader().getExtension(ExtensionScript.NAME);
        if (extScript != null) {
            extScript.registerScriptType(new ScriptType(SCRIPT_TYPE_ACTIVE, "ascan.scripts.type.active", SCRIPT_ICON_ACTIVE, true));
            extScript.registerScriptType(new ScriptType(SCRIPT_TYPE_VARIANT, "variant.scripts.type.variant", SCRIPT_ICON_VARIANT, true));
        }

        this.ascanController.setExtAlert((ExtensionAlert) Control.getSingleton().getExtensionLoader().getExtension(ExtensionAlert.NAME));
        this.activeScanApi = new ActiveScanAPI(this);
        this.activeScanApi.addApiOptions(getScannerParam());
        extensionHook.addApiImplementor(activeScanApi);
    }

    @Override
    public List<String> getActiveActions() {
        List<ActiveScan> activeScans = ascanController.getActiveScans();
        if (activeScans.isEmpty()) {
            return null;
        }

        String activeActionPrefix = Constant.messages.getString("ascan.activeActionPrefix");
        List<String> activeActions = new ArrayList<>(activeScans.size());
        for (ActiveScan activeScan : activeScans) {
            if (activeScan instanceof AttackScan && ((AttackScan) activeScan).isDone()) {<commit_msg>Change active scan to only create icons if needed<commit_after>/*
 * Zed Attack Proxy (ZAP) and its related class files.
 * 
 * ZAP is an HTTP/HTTPS proxy for assessing web application security.
 * 
 * Copyright 2010 <EMAIL>
 * 
 * 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.Dimension;
import java.awt.Event;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.InvalidParameterException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control;
import org.parosproxy.paros.control.Control.Mode;
import org.parosproxy.paros.core.scanner.ScannerParam;
import org.parosproxy.paros.extension.CommandLineArgument;
import org.parosproxy.paros.extension.CommandLineListener;
import org.parosproxy.paros.extension.Extension;
import org.parosproxy.paros.extension.ExtensionAdaptor;
import org.parosproxy.paros.extension.ExtensionHook;
import org.parosproxy.paros.extension.SessionChangedListener;
import org.parosproxy.paros.extension.history.ProxyListenerLog;
import org.parosproxy.paros.model.Model;
import org.parosproxy.paros.model.Session;
import org.parosproxy.paros.model.SiteNode;
import org.parosproxy.paros.view.AbstractParamPanel;
import org.parosproxy.paros.view.View;
import org.zaproxy.zap.extension.alert.ExtensionAlert;
import org.zaproxy.zap.extension.help.ExtensionHelp;
import org.zaproxy.zap.extension.script.ExtensionScript;
import org.zaproxy.zap.extension.script.ScriptType;
import org.zaproxy.zap.model.ScanController;
import org.zaproxy.zap.model.StructuralNode;
import org.zaproxy.zap.model.StructuralSiteNode;
import org.zaproxy.zap.model.Target;
import org.zaproxy.zap.users.User;
import org.zaproxy.zap.view.ZapMenuItem;

public class ExtensionActiveScan extends ExtensionAdaptor implements
        SessionChangedListener, CommandLineListener, ScanController<ActiveScan> {

    private static final Logger logger = Logger.getLogger(ExtensionActiveScan.class);
    private static final int ARG_SCAN_IDX = 0;
    
    public static final String NAME = "ExtensionActiveScan";
    
    public static final String SCRIPT_TYPE_ACTIVE = "active";
    public static final String SCRIPT_TYPE_VARIANT = "variant";

    //Could be after the last one that saves the HttpMessage, as this ProxyListener doesn't change the HttpMessage.
    public static final int PROXY_LISTENER_ORDER = ProxyListenerLog.PROXY_LISTENER_ORDER + 1;
    private static final List<Class<? extends Extension>> DEPENDENCIES;
    
    private AttackModeScanner attackModeScanner;
    
    private ActiveScanController ascanController = null;

    static {
        List<Class<? extends Extension>> dep = new ArrayList<>(1);
        dep.add(ExtensionAlert.class);

        DEPENDENCIES = Collections.unmodifiableList(dep);
    }

    private ZapMenuItem menuItemPolicy = null;
    private ZapMenuItem menuItemCustomScan = null;
    private OptionsScannerPanel optionsScannerPanel = null;
    private OptionsVariantPanel optionsVariantPanel = null;
    private ActiveScanPanel activeScanPanel = null;
    private ScannerParam scannerParam = null;
    private final CommandLineArgument[] arguments = new CommandLineArgument[1];
    private final List<AbstractParamPanel> policyPanels = new ArrayList<>();
	private JButton policyButton = null;
	private CustomScanDialog customScanDialog = null;
	private PolicyManagerDialog policyManagerDialog = null;
	private PolicyManager policyManager = null;
    private List<CustomScanPanel> customScanPanels = new ArrayList<CustomScanPanel>();
    
    private List<String> excludeList = Collections.emptyList();

	private ActiveScanAPI activeScanApi;

    public ExtensionActiveScan() {
        super(NAME);
        this.setOrder(28);
        policyManager = new PolicyManager(this);
        ascanController = new ActiveScanController(this);

    }
    
    @Override
    public String getUIName() {
    	return Constant.messages.getString("ascan.name");
    }
    
    @Override
    public void postInit() {
    	policyManager.init();

		if (Control.getSingleton().getMode().equals(Mode.attack)) {
			if (View.isInitialised() && ! this.getScannerParam().isAllowAttackOnStart()) {
				// Disable attack mode for safeties sake (when running with the UI)
	   			View.getSingleton().getMainFrame().getMainToolbarPanel().setMode(Mode.standard);
			} else {
				// Needed to make sure the attackModeScanner starts up
				this.attackModeScanner.sessionModeChanged(Control.getSingleton().getMode());
			}
		}
    }

    @Override
    public void hook(ExtensionHook extensionHook) {
        super.hook(extensionHook);

        attackModeScanner = new AttackModeScanner(this);

        if (getView() != null) {
            extensionHook.getHookMenu().addAnalyseMenuItem(getMenuItemPolicy());
            extensionHook.getHookMenu().addToolsMenuItem(getMenuItemCustomScan());

            extensionHook.getHookView().addStatusPanel(getActiveScanPanel());
            extensionHook.getHookView().addOptionPanel(getOptionsScannerPanel());
            extensionHook.getHookView().addOptionPanel(getOptionsVariantPanel());

	        extensionHook.getHookView().addMainToolBarComponent(this.getPolicyButton());
			View.getSingleton().getMainFrame().getMainFooterPanel().addFooterToolbarRightLabel(
					attackModeScanner.getScanStatus().getCountLabel());

            ExtensionHelp.enableHelpKey(getActiveScanPanel(), "ui.tabs.ascan");
        }
        
        extensionHook.addSessionListener(this);

        extensionHook.addOptionsParamSet(getScannerParam());
        // TODO this isnt currently implemented
        //extensionHook.addCommandLine(getCommandLineArguments());

        ExtensionScript extScript = (ExtensionScript) Control.getSingleton().getExtensionLoader().getExtension(ExtensionScript.NAME);
        if (extScript != null) {
            extScript.registerScriptType(
                    new ScriptType(SCRIPT_TYPE_ACTIVE, "ascan.scripts.type.active", createIcon("script-ascan.png"), true));
            extScript.registerScriptType(
                    new ScriptType(SCRIPT_TYPE_VARIANT, "variant.scripts.type.variant", createIcon("script-variant.png"), true));
        }

        this.ascanController.setExtAlert((ExtensionAlert) Control.getSingleton().getExtensionLoader().getExtension(ExtensionAlert.NAME));
        this.activeScanApi = new ActiveScanAPI(this);
        this.activeScanApi.addApiOptions(getScannerParam());
        extensionHook.addApiImplementor(activeScanApi);
    }

    private ImageIcon createIcon(String iconName) {
        if (getView() == null) {
            return null;
        }
        return new ImageIcon(ExtensionActiveScan.class.getResource("/resource/icon/16/" + iconName));
    }

    @Override
    public List<String> getActiveActions() {
        List<ActiveScan> activeScans = ascanController.getActiveScans();
        if (activeScans.isEmpty()) {
            return null;
        }

        String activeActionPrefix = Constant.messages.getString("ascan.activeActionPrefix");
        List<String> activeActions = new ArrayList<>(activeScans.size());
        for (ActiveScan activeScan : activeScans) {
            if (activeScan instanceof AttackScan && ((AttackScan) activeScan).isDone()) {
{'fraction_non_alphanumeric': 0.09451053807597078, 'fraction_numerical': 0.0021740443263482093, 'mean_word_length': 4.2075471698113205, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5146975', 'n_tokens_mistral': 4719, 'n_tokens_neox': 4552, 'n_words': 991}