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