org.parosproxy.paros.extension.manualrequest.ManualRequestEditorDialog Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zap Show documentation
Show all versions of zap Show documentation
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.
/*
*
* Paros and its related class files.
*
* Paros is an HTTP/HTTPS proxy for assessing web application security.
* Copyright (C) 2003-2004 Chinotec Technologies Company
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Clarified Artistic License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Clarified Artistic License for more details.
*
* You should have received a copy of the Clarified Artistic License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// ZAP: 2011/08/04 Changed to support new Features
// ZAP: 2011/08/04 Changed to support new interface
// ZAP: 2012/03/15 Changed so the display options can be modified dynamically.
// ZAP: 2012/07/02 Wraps no HttpMessage object, but more generalized Message.
// new map of supported message types; removed history list; removed unused
// methods.
// ZAP: 2012/07/16 Issue 326: Add response time and total length to manual request dialog
// ZAP: 2012/07/31 Removed the instance variables followRedirect,
// useTrackingSessionState and httpSender. Removed the methods getHttpSender,
// getButtonFollowRedirect and getButtonUseTrackingSessionState and changed the
// methods windowClosing and setVisible.
// ZAP: 2012/08/01 Issue 332: added support for Modes
// ZAP: 2012/11/21 Heavily refactored extension to support non-HTTP messages.
// ZAP: 2013/05/02 Re-arranged all modifiers into Java coding standard order
// ZAP: 2014/01/28 Issue 207: Support keyboard shortcuts
// ZAP: 2017/02/20 Issue 2699: Make SSLException handling more user friendly
package org.parosproxy.paros.extension.manualrequest;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.net.ssl.SSLException;
import javax.swing.JButton;
import javax.swing.JPanel;
import org.apache.commons.lang.exception.ExceptionUtils;
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.extension.option.OptionsParamView;
import org.parosproxy.paros.network.HttpMessage;
import org.parosproxy.paros.view.AbstractFrame;
import org.parosproxy.paros.view.View;
import org.zaproxy.zap.extension.httppanel.HttpPanelRequest;
import org.zaproxy.zap.extension.httppanel.Message;
import org.zaproxy.zap.extension.tab.Tab;
import org.zaproxy.zap.view.ZapMenuItem;
/**
* Send custom crafted messages via HTTP or other TCP based protocols.
*/
public abstract class ManualRequestEditorDialog extends AbstractFrame implements Tab {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(ManualRequestEditorDialog.class);
private boolean isSendEnabled = true;
protected String configurationKey;
private JPanel panelWindow = null;
private JButton btnSend = null;
/**
* Non-abstract classes should call {@link #initialize()} in their constructor.
*
* @param isSendEnabled
* @param configurationKey
* @throws HeadlessException
*/
public ManualRequestEditorDialog(boolean isSendEnabled, String configurationKey) throws HeadlessException {
super();
this.isSendEnabled = isSendEnabled;
this.configurationKey = OptionsParamView.BASE_VIEW_KEY + "." + configurationKey + ".";
this.setPreferredSize(new Dimension(700, 800));
}
protected void initialize() {
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
getMessageSender().cleanup();
saveConfig();
}
});
setContentPane(getWindowPanel());
}
/**
* Returns type of message it handles.
*
* @return
*/
public abstract Class extends Message> getMessageType();
/**
* Message sender for the given {@link #getMessageType()}.
*
* @return
*/
protected abstract MessageSender getMessageSender();
/**
* Menu item that calls this editor.
*
* @return
*/
public abstract ZapMenuItem getMenuItem();
protected JPanel getWindowPanel() {
if (panelWindow == null) {
panelWindow = new JPanel();
panelWindow.setLayout(new BorderLayout());
panelWindow.add(getManualSendPanel());
}
return panelWindow;
}
protected abstract Component getManualSendPanel();
@Override
public void setVisible(boolean show) {
if (!show && getMessageSender() != null) {
getMessageSender().cleanup();
}
super.setVisible(show);
}
public abstract void setDefaultMessage();
public abstract void setMessage(Message aMessage);
public abstract Message getMessage();
public void clear() {
getRequestPanel().clearView();
}
protected JButton getBtnSend() {
if (btnSend == null) {
btnSend = new JButton();
btnSend.setText(Constant.messages.getString("manReq.button.send"));
btnSend.setEnabled(isSendEnabled);
btnSend.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
btnSend.setEnabled(false);
// save current message (i.e. set payload/body)
getRequestPanel().saveData();
Mode mode = Control.getSingleton().getMode();
if (mode.equals(Mode.safe)) {
// Can happen if the user turns on safe mode with the dialog open
View.getSingleton().showWarningDialog(Constant.messages.getString("manReq.safe.warning"));
btnSend.setEnabled(true);
return;
} else if (mode.equals(Mode.protect)) {
if (!getMessage().isInScope()) {
// In protected mode and not in scope, so fail
View.getSingleton().showWarningDialog(Constant.messages.getString("manReq.outofscope.warning"));
btnSend.setEnabled(true);
return;
}
}
btnSendAction();
}
});
}
return btnSend;
}
/**
* Do not forget to enable the send button again i
*/
protected abstract void btnSendAction();
protected void send(final Message aMessage) {
final Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
getMessageSender().handleSendMessage(aMessage);
postSend();
} catch (SSLException sslEx) {
StringBuilder strBuilder = new StringBuilder();
strBuilder.append(Constant.messages.getString("network.ssl.error.connect"));
strBuilder.append(((HttpMessage) aMessage).getRequestHeader().getURI().toString()).append('\n');
strBuilder.append(Constant.messages.getString("network.ssl.error.exception")).append(sslEx.getMessage())
.append('\n');
strBuilder.append(Constant.messages.getString("network.ssl.error.exception.rootcause"))
.append(ExceptionUtils.getRootCauseMessage(sslEx)).append('\n');
strBuilder.append(Constant.messages.getString("network.ssl.error.help",
Constant.messages.getString("network.ssl.error.help.url")));
logger.warn(strBuilder.toString());
if (logger.isDebugEnabled()) {
logger.debug(sslEx, sslEx);
}
View.getSingleton().showWarningDialog(strBuilder.toString());
} catch (Exception e) {
logger.warn(e.getMessage(), e);
View.getSingleton().showWarningDialog(e.getMessage());
} finally {
btnSend.setEnabled(true);
}
}
});
t.setPriority(Thread.NORM_PRIORITY);
t.start();
}
protected void postSend() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// redraw, as message may have changed after sending
getRequestPanel().updateContent();
}
});
}
protected abstract void saveConfig();
protected abstract HttpPanelRequest getRequestPanel();
}