/*
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* 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 net.sf.json.JSONObject;
import org.parosproxy.paros.network.HttpHeader;
import org.parosproxy.paros.network.HttpMalformedHeaderException;
import org.parosproxy.paros.network.HttpMessage;
import org.zaproxy.zap.extension.api.ApiAction;
import org.zaproxy.zap.extension.api.ApiException;
import org.zaproxy.zap.extension.api.ApiImplementor;
import org.zaproxy.zap.extension.api.ApiResponse;
import org.zaproxy.zap.extension.api.ApiResponseElement;
import org.zaproxy.zap.extension.api.ApiView;
import org.zaproxy.zap.extension.httppanel.Message;
public class BreakAPI extends ApiImplementor {
private static final String PREFIX = "break";
private static final String ACTION_BREAK = "break";
private static final String ACTION_BREAK_ON_ID = "breakOnId";
private static final String ACTION_ADD_HTTP_BREAK_POINT = "addHttpBreakpoint";
private static final String ACTION_REM_HTTP_BREAK_POINT = "removeHttpBreakpoint";
private static final String ACTION_CONTINUE = "continue";
private static final String ACTION_STEP = "step";
private static final String ACTION_DROP = "drop";
private static final String ACTION_SET_HTTP_MESSAGE = "setHttpMessage";
private static final String VIEW_IS_BREAK_ALL = "isBreakAll";
private static final String VIEW_IS_BREAK_REQUEST = "isBreakRequest";
private static final String VIEW_IS_BREAK_RESPONSE = "isBreakResponse";
private static final String VIEW_HTTP_MESSAGE = "httpMessage";
private static final String PARAM_STRING = "string";
private static final String PARAM_LOCATION = "location";
private static final String PARAM_MATCH = "match";
private static final String PARAM_INVERSE = "inverse";
private static final String PARAM_IGNORECASE = "ignorecase";
private static final String PARAM_KEY = "key";
private static final String PARAM_SCOPE = "scope";
private static final String PARAM_STATE = "state";
private static final String PARAM_TYPE = "type";
private static final String PARAM_HTTP_HEADER = "httpHeader";
private static final String PARAM_HTTP_BODY = "httpBody";
private static final String VALUE_TYPE_HTTP_ALL = "http-all";
private static final String VALUE_TYPE_HTTP_REQUESTS = "http-requests";
private static final String VALUE_TYPE_HTTP_RESPONSES = "http-responses";
private ExtensionBreak extension = null;
public BreakAPI(ExtensionBreak ext) {
extension = ext;
this.addApiView(new ApiView(VIEW_IS_BREAK_ALL));
this.addApiView(new ApiView(VIEW_IS_BREAK_REQUEST));
this.addApiView(new ApiView(VIEW_IS_BREAK_RESPONSE));
this.addApiView(new ApiView(VIEW_HTTP_MESSAGE));
this.addApiAction(new ApiAction(ACTION_BREAK, new String[] {PARAM_TYPE, PARAM_STATE},
new String[] {PARAM_SCOPE})); // Not currently used but kept for compatibility purposes
this.addApiAction(new ApiAction(ACTION_SET_HTTP_MESSAGE,
new String[] {PARAM_HTTP_HEADER}, new String[] {PARAM_HTTP_BODY}));
this.addApiAction(new ApiAction(ACTION_CONTINUE));
this.addApiAction(new ApiAction(ACTION_STEP));
this.addApiAction(new ApiAction(ACTION_DROP));
this.addApiAction(new ApiAction(ACTION_ADD_HTTP_BREAK_POINT,
new String[] {PARAM_STRING, PARAM_LOCATION, PARAM_MATCH, PARAM_INVERSE, PARAM_IGNORECASE}));
this.addApiAction(new ApiAction(ACTION_REM_HTTP_BREAK_POINT,
new String[] {PARAM_STRING, PARAM_LOCATION, PARAM_MATCH, PARAM_INVERSE, PARAM_IGNORECASE}));
}
@Override
public String getPrefix() {
return PREFIX;
}
@Override
public ApiResponse handleApiAction(String name, JSONObject params) throws ApiException {
if (ACTION_BREAK.equals(name)) {
String type = params.getString(PARAM_TYPE).toLowerCase();
if (type.equals(VALUE_TYPE_HTTP_ALL)) {
extension.setBreakAllRequests(params.getBoolean(PARAM_STATE));
extension.setBreakAllResponses(params.getBoolean(PARAM_STATE));
} else if (type.equals(VALUE_TYPE_HTTP_REQUESTS)) {
extension.setBreakAllRequests(params.getBoolean(PARAM_STATE));
} else if (type.equals(VALUE_TYPE_HTTP_RESPONSES)) {
extension.setBreakAllResponses(params.getBoolean(PARAM_STATE));
} else {
throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, PARAM_TYPE +
" not in [" + VALUE_TYPE_HTTP_ALL +"," + VALUE_TYPE_HTTP_REQUESTS +"," +
VALUE_TYPE_HTTP_RESPONSES +"]");
}
} else if (ACTION_BREAK_ON_ID.equals(name)) {
extension.setBreakOnId(params.getString(PARAM_KEY), params.getString(PARAM_STATE).toLowerCase().equals("on"));
} else if (ACTION_CONTINUE.equals(name)) {
extension.getBreakpointManagementInterface().cont();
} else if (ACTION_STEP.equals(name)) {
extension.getBreakpointManagementInterface().step();
} else if (ACTION_DROP.equals(name)) {
extension.getBreakpointManagementInterface().drop();
} else if (ACTION_SET_HTTP_MESSAGE.equals(name)) {
if (extension.getBreakpointManagementInterface().getMessage() == null) {
// We've not got an intercepted message
throw new ApiException(ApiException.Type.DOES_NOT_EXIST);
}
String header = params.getString(PARAM_HTTP_HEADER);
String body = this.getParam(params, PARAM_HTTP_BODY, "");
if (header.indexOf(HttpHeader.CRLF) < 0) {
if (header.indexOf("\\n") >= 0) {
// Makes it easier to use via API UI
header = header.replace("\\r", "\r").replace("\\n", "\n");
}
}
Message msg = extension.getBreakpointManagementInterface().getMessage();
if (msg instanceof HttpMessage) {
HttpMessage httpMsg = (HttpMessage)msg;
if (extension.getBreakpointManagementInterface().isRequest()) {
try {
httpMsg.setRequestHeader(header);
httpMsg.setRequestBody(body);
extension.getBreakpointManagementInterface().setMessage(httpMsg, true);
} catch (HttpMalformedHeaderException e) {
throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, e.getMessage());
}
} else {
try {
httpMsg.setResponseHeader(header);
httpMsg.setResponseBody(body);
extension.getBreakpointManagementInterface().setMessage(httpMsg, false);
} catch (HttpMalformedHeaderException e) {
throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, e.getMessage());
}
}
}
} else if (ACTION_ADD_HTTP_BREAK_POINT.equals(name)) {
try {
extension.addHttpBreakpoint(
params.getString(PARAM_STRING),
params.getString(PARAM_LOCATION),
params.getString(PARAM_MATCH),
params.getBoolean(PARAM_INVERSE),
params.getBoolean(PARAM_IGNORECASE));
} catch (Exception e) {
throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, e.getMessage());
}
} else if (ACTION_REM_HTTP_BREAK_POINT.equals(name)) {
try {
extension.removeHttpBreakpoint(
params.getString(PARAM_STRING),
params.getString(PARAM_LOCATION),
params.getString(PARAM_MATCH),
params.getBoolean(PARAM_INVERSE),
params.getBoolean(PARAM_IGNORECASE));
} catch (Exception e) {
throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, e.getMessage());
}
} else {
throw new ApiException(ApiException.Type.BAD_ACTION);
}
return ApiResponseElement.OK;
}
@Override
public ApiResponse handleApiView(String name, JSONObject params) throws ApiException {
if (VIEW_IS_BREAK_ALL.equals(name)) {
return new ApiResponseElement(name,
Boolean.toString(extension.getBreakpointManagementInterface().isBreakAll()));
} else if (VIEW_IS_BREAK_REQUEST.equals(name)) {
return new ApiResponseElement(name,
Boolean.toString(extension.getBreakpointManagementInterface().isBreakRequest()));
} else if (VIEW_IS_BREAK_RESPONSE.equals(name)) {
return new ApiResponseElement(name,
Boolean.toString(extension.getBreakpointManagementInterface().isBreakResponse()));
} else if (VIEW_HTTP_MESSAGE.equals(name)) {
Message msg = extension.getBreakpointManagementInterface().getMessage();
if (msg == null ) {
return new ApiResponseElement(name, "");
} else if (msg instanceof HttpMessage) {
HttpMessage httpMsg = (HttpMessage)msg;
StringBuilder sb = new StringBuilder();
if (extension.getBreakpointManagementInterface().isRequest()) {
sb.append(httpMsg.getRequestHeader().toString());
sb.append(httpMsg.getRequestBody().toString());
} else {
sb.append(httpMsg.getResponseHeader().toString());
sb.append(httpMsg.getResponseBody().toString());
}
return new ApiResponseElement(name, sb.toString());
}
throw new ApiException(ApiException.Type.BAD_TYPE);
} else {
throw new ApiException(ApiException.Type.BAD_VIEW);
}
}
}