/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Copyright 2010 psiinon@gmail.com * * 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.brk; import java.awt.EventQueue; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.log4j.Logger; import org.parosproxy.paros.control.Control.Mode; import org.parosproxy.paros.view.View; import org.zaproxy.zap.extension.httppanel.Message; /** * @deprecated (2.6.0) Use {@link BreakpointMessageHandler2} instead */ @Deprecated public class BreakpointMessageHandler { private static final Logger logger = Logger.getLogger(BreakpointMessageHandler.class); protected static final java.lang.Object semaphore = new java.lang.Object(); protected final BreakPanel breakPanel; protected List<BreakpointMessageInterface> enabledBreakpoints; private List<String> enabledKeyBreakpoints = new ArrayList<>(); public List<String> getEnabledKeyBreakpoints() { return enabledKeyBreakpoints; } public void setEnabledKeyBreakpoints(List<String> enabledKeyBreakpoints) { this.enabledKeyBreakpoints = enabledKeyBreakpoints; } public BreakpointMessageHandler(BreakPanel aBreakPanel) { this.breakPanel = aBreakPanel; } public void setEnabledBreakpoints(List<BreakpointMessageInterface> breakpoints) { this.enabledBreakpoints = breakpoints; } /** * Do not call if in {@link Mode#safe}. * * @param aMessage * @param onlyIfInScope * @return False if message should be dropped. */ public boolean handleMessageReceivedFromClient(Message aMessage, boolean onlyIfInScope) { if ( ! isBreakpoint(aMessage, true, onlyIfInScope)) { return true; } // Do this outside of the semaphore loop so that the 'continue' button can apply to all queued break points // but be reset when the next break point is hit breakPanel.breakpointHit(); synchronized(semaphore) { if (breakPanel.isHoldMessage()) { setBreakDisplay(aMessage, true); waitUntilContinue(true); } } breakPanel.clearAndDisableRequest(); return ! breakPanel.isToBeDropped(); } /** * Do not call if in {@link Mode#safe}. * * @param aMessage * @param onlyIfInScope * @return False if message should be dropped. */ public boolean handleMessageReceivedFromServer(Message aMessage, boolean onlyIfInScope) { if (! isBreakpoint(aMessage, false, onlyIfInScope)) { return true; } // Do this outside of the semaphore loop so that the 'continue' button can apply to all queued break points // but be reset when the next break point is hit breakPanel.breakpointHit(); synchronized(semaphore) { //breakPanel.breakpointHit(); if (breakPanel.isHoldMessage()) { setBreakDisplay(aMessage, false); waitUntilContinue(false); } } breakPanel.clearAndDisableResponse(); return ! breakPanel.isToBeDropped(); } private void setBreakDisplay(final Message msg, boolean isRequest) { breakPanel.setMessage(msg, isRequest); breakPanel.breakpointDisplayed(); try { EventQueue.invokeAndWait(new Runnable() { @Override public void run() { View.getSingleton().getMainFrame().toFront(); } }); } catch (Exception e) { logger.warn(e.getMessage(), e); } } private void waitUntilContinue(final boolean isRequest) { // Note that multiple requests and responses can get built up, so pressing continue only // releases the current break, not all of them. //breakPanel.setContinue(false); while (breakPanel.isHoldMessage()) { try { Thread.sleep(100); } catch (InterruptedException e) { logger.warn(e.getMessage(), e); } } breakPanel.saveMessage(isRequest); } /** * You have to handle {@link Mode#safe} outside. * * @param aMessage * @param isRequest * @param onlyIfInScope * @return True if a breakpoint for given message exists. */ public boolean isBreakpoint(Message aMessage, boolean isRequest, boolean onlyIfInScope) { if (aMessage.isForceIntercept()) { // The browser told us to do it Your Honour return true; } /* Disable pending other changes String secHeader = aMessage.getHeader(HttpHeader.X_SECURITY_PROXY); if (secHeader != null) { for (String val : secHeader.split(",")) { if (val.trim().startsWith(HttpHeader.SEC_PROXY_KEY) && val.indexOf("=") > 0) { String[] keyValue = val.split("="); // Have we been told to intercept messages with this key? for (String k : this.enabledKeyBreakpoints) { if (k.equals(keyValue[1].trim())) { // Yes, we have logger.debug("isBreakpoint match on key " + k); return true; } } } } } */ if (onlyIfInScope && ! aMessage.isInScope()) { return false; } if (isBreakOnAllRequests(aMessage, isRequest)) { // Break on all requests return true; } else if (isBreakOnAllResponses(aMessage, isRequest)) { // Break on all responses return true; } else if (isBreakOnStepping(aMessage, isRequest)) { // Stopping through all requests and responses return true; } return isBreakOnEnabledBreakpoint(aMessage, isRequest, onlyIfInScope); } protected boolean isBreakOnAllRequests(Message aMessage, boolean isRequest) { return isRequest && breakPanel.isBreakRequest(); } protected boolean isBreakOnAllResponses(Message aMessage, boolean isRequest) { return !isRequest && breakPanel.isBreakResponse(); } protected boolean isBreakOnStepping(Message aMessage, boolean isRequest) { return breakPanel.isStepping(); } protected boolean isBreakOnEnabledBreakpoint(Message aMessage, boolean isRequest, boolean onlyIfInScope) { if (enabledBreakpoints.isEmpty()) { // No break points return false; } // match against the break points synchronized (enabledBreakpoints) { Iterator<BreakpointMessageInterface> it = enabledBreakpoints.iterator(); while(it.hasNext()) { BreakpointMessageInterface breakpoint = it.next(); if (breakpoint.match(aMessage, isRequest, onlyIfInScope)) { return true; } } } return false; } }