/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Copyright 2012 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.extension.pscan; import java.awt.Dialog; import java.util.List; import java.util.regex.Pattern; import javax.swing.GroupLayout; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.parosproxy.paros.Constant; import org.zaproxy.zap.extension.pscan.scanner.RegexAutoTagScanner; import org.zaproxy.zap.utils.ZapTextField; import org.zaproxy.zap.view.AbstractFormDialog; class DialogAddAutoTagScanner extends AbstractFormDialog { private static final long serialVersionUID = -5209887319253495735L; private static final String DIALOG_TITLE = Constant.messages.getString("pscan.options.dialog.scanner.add.title"); private static final String CONFIRM_BUTTON_LABEL = Constant.messages.getString("pscan.options.dialog.scanner.add.button.confirm"); private static final String NAME_FIELD_LABEL = Constant.messages.getString("pscan.options.dialog.scanner.field.label.name"); private static final String TYPE_FIELD_LABEL = Constant.messages.getString("pscan.options.dialog.scanner.field.label.type"); private static final String CONFIGURATION_FIELD_LABEL = Constant.messages.getString("pscan.options.dialog.scanner.field.label.config"); private static final String REQUEST_URL_REGEX_FIELD_LABEL = Constant.messages.getString("pscan.options.dialog.scanner.field.label.editRequestUrlRegex"); private static final String REQUEST_HEADER_REGEX_FIELD_LABEL = Constant.messages.getString("pscan.options.dialog.scanner.field.label.editRequestHeaderRegex"); private static final String RESPONSE_HEADER_REGEX_FIELD_LABEL = Constant.messages.getString("pscan.options.dialog.scanner.field.label.editResponseHeaderRegex"); private static final String RESPONSE_BODY_REGEX_FIELD_LABEL = Constant.messages.getString("pscan.options.dialog.scanner.field.label.editResponseBodyRegex"); private static final String ENABLED_FIELD_LABEL = Constant.messages.getString("pscan.options.dialog.scanner.field.label.enabled"); private static final String TITLE_DISPLAY_NAME_REPEATED_DIALOG = Constant.messages.getString("pscan.options.dialog.scanner.warning.name.repeated.title"); private static final String TEXT_DISPLAY_NAME_REPEATED_DIALOG = Constant.messages.getString("pscan.options.dialog.scanner.warning.name.repeated.text"); private static final String TITLE_WARNING_INVALID_REGEX = Constant.messages.getString("pscan.options.dialog.scanner.warning.invalid.regex.title"); private static final String MESSAGE_INVALID_REQUEST_HEADER_REGEX = Constant.messages.getString("pscan.options.dialog.scanner.warning.invalid.requestHeaderRegex"); private static final String MESSAGE_INVALID_REQUEST_URL_REGEX = Constant.messages.getString("pscan.options.dialog.scanner.warning.invalid.requestUrlRegex"); private static final String MESSAGE_INVALID_RESPONSE_BODY_REGEX = Constant.messages.getString("pscan.options.dialog.scanner.warning.invalid.responseBodyRegex"); private static final String MESSAGE_INVALID_RESPONSE_HEADER_REGEX = Constant.messages.getString("pscan.options.dialog.scanner.warning.invalid.responseHeaderRegex"); private ZapTextField nameTextField; private ZapTextField typeTextField; private ZapTextField configurationTextField; private ZapTextField requestUrlRegexTextField; private ZapTextField requestHeaderRegexTextField; private ZapTextField responseHeaderRegexTextField; private ZapTextField responseBodyRegexTextField; private JCheckBox enabledCheckBox; protected RegexAutoTagScanner scanner; private List<RegexAutoTagScanner> scanners; private ConfirmButtonValidatorDocListener confirmButtonValidatorDocListener; public DialogAddAutoTagScanner(Dialog owner) { super(owner, DIALOG_TITLE); } protected DialogAddAutoTagScanner(Dialog owner, String title) { super(owner, title); } @Override protected JPanel getFieldsPanel() { JPanel fieldsPanel = new JPanel(); GroupLayout layout = new GroupLayout(fieldsPanel); fieldsPanel.setLayout(layout); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); JLabel nameLabel = new JLabel(NAME_FIELD_LABEL); JLabel typeLabel = new JLabel(TYPE_FIELD_LABEL); JLabel configurationLabel = new JLabel(CONFIGURATION_FIELD_LABEL); JLabel requestUrlRegexLabel = new JLabel(REQUEST_URL_REGEX_FIELD_LABEL); JLabel requestHeaderRegexLabel = new JLabel(REQUEST_HEADER_REGEX_FIELD_LABEL); JLabel responseHeaderRegexLabel = new JLabel(RESPONSE_HEADER_REGEX_FIELD_LABEL); JLabel responseBodyRegexLabel = new JLabel(RESPONSE_BODY_REGEX_FIELD_LABEL); JLabel enabledLabel = new JLabel(ENABLED_FIELD_LABEL); layout.setHorizontalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) .addComponent(nameLabel) .addComponent(typeLabel) .addComponent(configurationLabel) .addComponent(requestUrlRegexLabel) .addComponent(requestHeaderRegexLabel) .addComponent(responseHeaderRegexLabel) .addComponent(responseBodyRegexLabel) .addComponent(enabledLabel)) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(getNameTextField()) .addComponent(getTypeTextField()) .addComponent(getConfigurationTextField()) .addComponent(getRequestUrlRegexTextField()) .addComponent(getRequestHeaderRegexTextField()) .addComponent(getResponseHeaderRegexTextField()) .addComponent(getResponseBodyRegexTextField()) .addComponent(getEnabledCheckBox())) ); layout.setVerticalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(nameLabel) .addComponent(getNameTextField())) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(typeLabel) .addComponent(getTypeTextField())) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(configurationLabel) .addComponent(getConfigurationTextField())) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(requestUrlRegexLabel) .addComponent(getRequestUrlRegexTextField())) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(requestHeaderRegexLabel) .addComponent(getRequestHeaderRegexTextField())) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(responseHeaderRegexLabel) .addComponent(getResponseHeaderRegexTextField())) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(responseBodyRegexLabel) .addComponent(getResponseBodyRegexTextField())) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(enabledLabel) .addComponent(getEnabledCheckBox())) ); return fieldsPanel; } @Override protected String getConfirmButtonLabel() { return CONFIRM_BUTTON_LABEL; } @Override protected void init() { getNameTextField().setText(""); getConfigurationTextField().setText(""); getRequestUrlRegexTextField().setText(""); getRequestHeaderRegexTextField().setText(""); getResponseHeaderRegexTextField().setText(""); getResponseBodyRegexTextField().setText(""); getEnabledCheckBox().setSelected(true); scanner = null; } @Override protected boolean validateFields() { if(!validateName(getNameTextField().getText())) { return false; } if (!validateRegex(getRequestHeaderRegexTextField(), MESSAGE_INVALID_REQUEST_HEADER_REGEX)) { return false; } if (!validateRegex(getRequestUrlRegexTextField(), MESSAGE_INVALID_REQUEST_URL_REGEX)) { return false; } if (!validateRegex(getResponseHeaderRegexTextField(), MESSAGE_INVALID_RESPONSE_HEADER_REGEX)) { return false; } if (!validateRegex(getResponseBodyRegexTextField(), MESSAGE_INVALID_RESPONSE_BODY_REGEX)) { return false; } return true; } protected boolean validateName(String name) { for (RegexAutoTagScanner s : scanners) { if (name.equals(s.getName())) { JOptionPane.showMessageDialog(this, TEXT_DISPLAY_NAME_REPEATED_DIALOG, TITLE_DISPLAY_NAME_REPEATED_DIALOG, JOptionPane.INFORMATION_MESSAGE); getNameTextField().requestFocusInWindow(); return false; } } return true; } private boolean validateRegex(ZapTextField regexTextField, String warningMessage) { try { Pattern.compile(regexTextField.getText(), Pattern.CASE_INSENSITIVE); } catch (IllegalArgumentException e) { JOptionPane.showMessageDialog(this, warningMessage, TITLE_WARNING_INVALID_REGEX, JOptionPane.WARNING_MESSAGE); regexTextField.requestFocusInWindow(); return false; } return true; } @Override protected void performAction() { scanner = new RegexAutoTagScanner(getNameTextField().getText(), RegexAutoTagScanner.TYPE.TAG, getConfigurationTextField().getText()); scanner.setRequestHeaderRegex(getRequestHeaderRegexTextField().getText()); scanner.setRequestUrlRegex(getRequestUrlRegexTextField().getText()); scanner.setResponseHeaderRegex(getResponseHeaderRegexTextField().getText()); scanner.setResponseBodyRegex(getResponseBodyRegexTextField().getText()); scanner.setEnabled(getEnabledCheckBox().isSelected()); } @Override protected void clearFields() { getNameTextField().setText(""); getNameTextField().discardAllEdits(); getConfigurationTextField().setText(""); getConfigurationTextField().discardAllEdits(); getRequestUrlRegexTextField().setText(""); getRequestUrlRegexTextField().discardAllEdits(); getRequestHeaderRegexTextField().setText(""); getRequestHeaderRegexTextField().discardAllEdits(); getResponseHeaderRegexTextField().setText(""); getResponseHeaderRegexTextField().discardAllEdits(); getResponseBodyRegexTextField().setText(""); getResponseBodyRegexTextField().discardAllEdits(); } public RegexAutoTagScanner getScanner() { return scanner; } protected ZapTextField getNameTextField() { if (nameTextField == null) { nameTextField = new ZapTextField(25); nameTextField.getDocument().addDocumentListener(getConfirmButtonValidatorDocListener()); } return nameTextField; } protected ZapTextField getTypeTextField() { if (typeTextField == null) { typeTextField = new ZapTextField(); typeTextField.setEditable(false); typeTextField.setText(RegexAutoTagScanner.TYPE.TAG.name()); } return typeTextField; } protected ZapTextField getConfigurationTextField() { if (configurationTextField == null) { configurationTextField = new ZapTextField(); configurationTextField.getDocument().addDocumentListener(getConfirmButtonValidatorDocListener()); } return configurationTextField; } protected ZapTextField getRequestUrlRegexTextField() { if (requestUrlRegexTextField == null) { requestUrlRegexTextField = new ZapTextField(); requestUrlRegexTextField.getDocument().addDocumentListener(getConfirmButtonValidatorDocListener()); } return requestUrlRegexTextField; } protected ZapTextField getRequestHeaderRegexTextField() { if (requestHeaderRegexTextField == null) { requestHeaderRegexTextField = new ZapTextField(); requestHeaderRegexTextField.getDocument().addDocumentListener(getConfirmButtonValidatorDocListener()); } return requestHeaderRegexTextField; } protected ZapTextField getResponseHeaderRegexTextField() { if (responseHeaderRegexTextField == null) { responseHeaderRegexTextField = new ZapTextField(); responseHeaderRegexTextField.getDocument().addDocumentListener(getConfirmButtonValidatorDocListener()); } return responseHeaderRegexTextField; } protected ZapTextField getResponseBodyRegexTextField() { if (responseBodyRegexTextField == null) { responseBodyRegexTextField = new ZapTextField(); responseBodyRegexTextField.getDocument().addDocumentListener(getConfirmButtonValidatorDocListener()); } return responseBodyRegexTextField; } protected JCheckBox getEnabledCheckBox() { if (enabledCheckBox == null) { enabledCheckBox = new JCheckBox(); } return enabledCheckBox; } public void setScanners(List<RegexAutoTagScanner> scanners) { this.scanners = scanners; } public void clear() { this.scanners = null; this.scanner = null; } private ConfirmButtonValidatorDocListener getConfirmButtonValidatorDocListener() { if (confirmButtonValidatorDocListener == null) { confirmButtonValidatorDocListener = new ConfirmButtonValidatorDocListener(); } return confirmButtonValidatorDocListener; } private class ConfirmButtonValidatorDocListener implements DocumentListener { @Override public void insertUpdate(DocumentEvent e) { checkAndEnableConfirmButton(); } @Override public void removeUpdate(DocumentEvent e) { checkAndEnableConfirmButton(); } @Override public void changedUpdate(DocumentEvent e) { checkAndEnableConfirmButton(); } private void checkAndEnableConfirmButton() { boolean enabled = (getNameTextField().getDocument().getLength() > 0) && (getConfigurationTextField().getDocument().getLength() > 0) && (getRequestUrlRegexTextField().getDocument().getLength() > 0 || getRequestUrlRegexTextField().getDocument().getLength() > 0 || getRequestHeaderRegexTextField().getDocument().getLength() > 0 || getResponseHeaderRegexTextField().getDocument().getLength() > 0 || getResponseBodyRegexTextField().getDocument().getLength() > 0); setConfirmButtonEnabled(enabled); } } }