1 /* 2 * 3 * Paros and its related class files. 4 * 5 * Paros is an HTTP/HTTPS proxy for assessing web application security. 6 * Copyright (C) 2003-2004 Chinotec Technologies Company 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the Clarified Artistic License 10 * as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * Clarified Artistic License for more details. 16 * 17 * You should have received a copy of the Clarified Artistic License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 */ 21 22 // ZAP: 2011/08/04 Changed for cleanup 23 // ZAP: 2011/11/20 Set order 24 // ZAP: 2012/03/15 Changed to reset the message of the ManualRequestEditorDialog 25 // when a new session is created. Added the key configuration to the 26 // ManualRequestEditorDialog. 27 // ZAP: 2012/03/17 Issue 282 Added getAuthor() 28 // ZAP: 2012/04/25 Added @Override annotation to all appropriate methods. 29 // ZAP: 2012/07/02 ManualRequestEditorDialog changed to receive Message instead 30 // of HttpMessage. Changed logger to static. 31 // ZAP: 2012/07/29 Issue 43: added sessionScopeChanged event 32 // ZAP: 2012/08/01 Issue 332: added support for Modes 33 // ZAP: 2012/11/21 Heavily refactored extension to support non-HTTP messages. 34 // ZAP: 2013/01/25 Added method removeManualSendEditor(). 35 // ZAP: 2013/02/06 Issue 499: NullPointerException while uninstalling an add-on 36 // with a manual request editor 37 // ZAP: 2014/03/23 Issue 1094: Change ExtensionManualRequestEditor to only add view components if in 38 // GUI mode 39 // ZAP: 2014/08/14 Issue 1292: NullPointerException while attempting to remove an unregistered 40 // ManualRequestEditorDialog 41 // ZAP: 2014/12/12 Issue 1449: Added help button 42 // ZAP: 2015/03/16 Issue 1525: Further database independence changes 43 // ZAP: 2016/06/20 Removed unnecessary/unused constructor 44 // ZAP: 2017/04/07 Added getUIName() 45 // ZAP: 2017/06/06 Clear dialogues in EDT. 46 // ZAP: 2018/02/23 Issue 1161: Fix Session Tracking button sync 47 // ZAP: 2019/06/01 Normalise line endings. 48 // ZAP: 2019/06/05 Normalise format/style. 49 // ZAP: 2019/10/04 Add dialog/menu icon. 50 package org.parosproxy.paros.extension.manualrequest; 51 52 import java.awt.EventQueue; 53 import java.util.HashMap; 54 import java.util.Map; 55 import java.util.Map.Entry; 56 import javax.swing.ImageIcon; 57 import org.parosproxy.paros.Constant; 58 import org.parosproxy.paros.control.Control; 59 import org.parosproxy.paros.control.Control.Mode; 60 import org.parosproxy.paros.extension.ExtensionAdaptor; 61 import org.parosproxy.paros.extension.ExtensionHook; 62 import org.parosproxy.paros.extension.ExtensionLoader; 63 import org.parosproxy.paros.extension.SessionChangedListener; 64 import org.parosproxy.paros.extension.ViewDelegate; 65 import org.parosproxy.paros.extension.manualrequest.http.impl.ManualHttpRequestEditorDialog; 66 import org.parosproxy.paros.model.Session; 67 import org.zaproxy.zap.extension.httppanel.Message; 68 69 public class ExtensionManualRequestEditor extends ExtensionAdaptor 70 implements SessionChangedListener { 71 72 private Map<Class<? extends Message>, ManualRequestEditorDialog> dialogues = new HashMap<>(); 73 private ManualHttpRequestEditorDialog httpSendEditorDialog; 74 75 /** Name of this extension. */ 76 public static final String NAME = "ExtensionManualRequest"; 77 ExtensionManualRequestEditor()78 public ExtensionManualRequestEditor() { 79 super(NAME); 80 this.setOrder(36); 81 } 82 83 @Override getUIName()84 public String getUIName() { 85 return Constant.messages.getString("manReq.name"); 86 } 87 88 @Override initView(ViewDelegate view)89 public void initView(ViewDelegate view) { 90 super.initView(view); 91 92 // add default manual request editor 93 httpSendEditorDialog = 94 new ManualHttpRequestEditorDialog(true, "manual", "ui.dialogs.manreq"); 95 httpSendEditorDialog.setTitle(Constant.messages.getString("manReq.dialog.title")); 96 97 addManualSendEditor(httpSendEditorDialog); 98 } 99 100 /** 101 * Should be called before extension is initialized via its {@link #hook(ExtensionHook)} method. 102 * 103 * @param dialogue 104 */ addManualSendEditor(ManualRequestEditorDialog dialogue)105 public void addManualSendEditor(ManualRequestEditorDialog dialogue) { 106 dialogues.put(dialogue.getMessageType(), dialogue); 107 } 108 removeManualSendEditor(Class<? extends Message> messageType)109 public void removeManualSendEditor(Class<? extends Message> messageType) { 110 // remove from list 111 ManualRequestEditorDialog dialogue = dialogues.remove(messageType); 112 113 if (dialogue != null) { 114 // remove from GUI 115 dialogue.clear(); 116 dialogue.dispose(); 117 118 if (getView() != null) { 119 // unload menu items 120 ExtensionLoader extLoader = Control.getSingleton().getExtensionLoader(); 121 extLoader.removeToolsMenuItem(dialogue.getMenuItem()); 122 } 123 } 124 } 125 126 /** 127 * Get special manual send editor to add listeners, etc. 128 * 129 * @param type 130 * @return 131 */ getManualSendEditor(Class<? extends Message> type)132 public ManualRequestEditorDialog getManualSendEditor(Class<? extends Message> type) { 133 return dialogues.get(type); 134 } 135 136 @Override hook(ExtensionHook extensionHook)137 public void hook(ExtensionHook extensionHook) { 138 super.hook(extensionHook); 139 if (getView() != null) { 140 for (Entry<Class<? extends Message>, ManualRequestEditorDialog> dialogue : 141 dialogues.entrySet()) { 142 extensionHook.getHookMenu().addToolsMenuItem(dialogue.getValue().getMenuItem()); 143 } 144 145 extensionHook.addSessionListener(this); 146 extensionHook.addOptionsChangedListener(httpSendEditorDialog); 147 } 148 } 149 150 @Override getAuthor()151 public String getAuthor() { 152 return Constant.PAROS_TEAM; 153 } 154 155 @Override sessionChanged(Session session)156 public void sessionChanged(Session session) { 157 if (EventQueue.isDispatchThread()) { 158 for (Entry<Class<? extends Message>, ManualRequestEditorDialog> dialogue : 159 dialogues.entrySet()) { 160 dialogue.getValue().clear(); 161 dialogue.getValue().setDefaultMessage(); 162 } 163 return; 164 } 165 166 EventQueue.invokeLater(() -> sessionChanged(session)); 167 } 168 169 @Override sessionAboutToChange(Session session)170 public void sessionAboutToChange(Session session) {} 171 172 @Override sessionScopeChanged(Session session)173 public void sessionScopeChanged(Session session) {} 174 175 @Override sessionModeChanged(Mode mode)176 public void sessionModeChanged(Mode mode) { 177 Boolean isEnabled = null; 178 switch (mode) { 179 case safe: 180 isEnabled = false; 181 break; 182 case protect: 183 case standard: 184 case attack: 185 isEnabled = true; 186 break; 187 } 188 189 if (isEnabled != null) { 190 for (Entry<Class<? extends Message>, ManualRequestEditorDialog> dialog : 191 dialogues.entrySet()) { 192 dialog.getValue().setEnabled(isEnabled); 193 } 194 } 195 } 196 197 /** No database tables used, so all supported */ 198 @Override supportsDb(String type)199 public boolean supportsDb(String type) { 200 return true; 201 } 202 getIcon()203 public static final ImageIcon getIcon() { 204 return new ImageIcon( 205 ExtensionManualRequestEditor.class.getResource("/resource/icon/16/hand.png")); 206 } 207 } 208