diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java index f74b829..06bfd88 100644 --- a/src/main/java/burp/BurpExtender.java +++ b/src/main/java/burp/BurpExtender.java @@ -24,6 +24,8 @@ public void initialize(MontoyaApi api) { api.extension().setName(extensionName); api.userInterface().registerContextMenuItemsProvider(new CstcContextMenuItemsProvider(api, view)); api.http().registerHttpHandler(new CstcHttpHandler(view)); + api.proxy().registerRequestHandler(new CstcProxyRequestHandler(view)); + api.proxy().registerResponseHandler(new CstcProxyResponseHandler(view)); api.userInterface().registerSuiteTab(extensionName, view); api.userInterface().registerHttpRequestEditorProvider(new MyHttpRequestEditorProvider(view)); api.userInterface().registerHttpRequestEditorProvider(new MyHttpRequestEditorProviderFormatting(view)); @@ -41,8 +43,10 @@ public void initialize(MontoyaApi api) { private void restoreInput(PersistedObject persistence) { try { this.view.getFormatRecipePanel().restoreInput(persistence.getString(BurpOperation.FORMAT + "Input")); - this.view.getIncomingRecipePanel().restoreInput(persistence.getString(BurpOperation.INCOMING + "Input")); - this.view.getOutgoingRecipePanel().restoreInput(persistence.getString(BurpOperation.OUTGOING + "Input")); + this.view.getIncomingProxyRequestRecipePanel().restoreInput(persistence.getString(BurpOperation.INCOMING_PROXY_REQUEST + "Input")); + this.view.getOutgoingHttpRequestRecipePanel().restoreInput(persistence.getString(BurpOperation.OUTGOING_HTTP_REQUEST + "Input")); + this.view.getIncomingHttpResponseRecipePanel().restoreInput(persistence.getString(BurpOperation.INCOMING_HTTP_RESPONSE + "Input")); + this.view.getOutgoingProxyResponseRecipePanel().restoreInput(persistence.getString(BurpOperation.OUTGOING_PROXY_RESPONSE + "Input")); } catch (Exception e) { Logger.getInstance().log( "Could not restore the input for one or multiple panels. If this is the first time using CSTC in a project, you can ignore this message."); @@ -52,8 +56,10 @@ private void restoreInput(PersistedObject persistence) { private void restoreRecipe(PersistedObject persistence) { try { this.view.getFormatRecipePanel().restoreState(persistence.getString(BurpOperation.FORMAT + "Recipe")); - this.view.getIncomingRecipePanel().restoreState(persistence.getString(BurpOperation.INCOMING + "Recipe")); - this.view.getOutgoingRecipePanel().restoreState(persistence.getString(BurpOperation.OUTGOING + "Recipe")); + this.view.getIncomingHttpResponseRecipePanel().restoreState(persistence.getString(BurpOperation.INCOMING_HTTP_RESPONSE + "Recipe")); + this.view.getIncomingProxyRequestRecipePanel().restoreState(persistence.getString(BurpOperation.INCOMING_PROXY_REQUEST + "Recipe")); + this.view.getOutgoingHttpRequestRecipePanel().restoreState(persistence.getString(BurpOperation.OUTGOING_HTTP_REQUEST + "Recipe")); + this.view.getOutgoingProxyResponseRecipePanel().restoreState(persistence.getString(BurpOperation.OUTGOING_PROXY_RESPONSE + "Recipe")); } catch (Exception e) { Logger.getInstance().log( "Could not restore the recipe for one or multiple panels. If this is the first time using CSTC in a project, you can ignore this message."); diff --git a/src/main/java/burp/CstcContextMenuItemsProvider.java b/src/main/java/burp/CstcContextMenuItemsProvider.java index 5965093..a6dc79a 100644 --- a/src/main/java/burp/CstcContextMenuItemsProvider.java +++ b/src/main/java/burp/CstcContextMenuItemsProvider.java @@ -30,27 +30,45 @@ public CstcContextMenuItemsProvider(MontoyaApi api, View view) public List provideMenuItems(ContextMenuEvent event) { List menuItems = new ArrayList<>(); - JMenuItem incomingMenu = new JMenuItem("Send to CSTC (Incoming)"); - JMenuItem outgoingMenu = new JMenuItem("Send to CSTC (Outgoing)"); - JMenuItem incomingReqFormatMenu = new JMenuItem("Send request to CSTC (Formatting)"); - JMenuItem incomingResFormatMenu = new JMenuItem("Send response to CSTC (Formatting)"); + JMenuItem incomingHttpResponseMenu = new JMenuItem("Send to Incoming HTTP Responses"); + JMenuItem incomingProxyRequestMenu = new JMenuItem("Send to Incoming Proxy Requests"); + JMenuItem outgoingHttpRequestMenu = new JMenuItem("Send to Outgoing HTTP Requests"); + JMenuItem outgoingProxyResponseMenu = new JMenuItem("Send to Outgoing Proxy Responses"); + JMenuItem incomingReqFormatMenu = new JMenuItem("Send request to Formatting"); + JMenuItem incomingResFormatMenu = new JMenuItem("Send response to Formatting"); - menuItems.add(outgoingMenu); - menuItems.add(incomingMenu); + menuItems.add(outgoingHttpRequestMenu); + menuItems.add(outgoingProxyResponseMenu); + menuItems.add(incomingHttpResponseMenu); + menuItems.add(incomingProxyRequestMenu); menuItems.add(incomingReqFormatMenu); menuItems.add(incomingResFormatMenu); - incomingMenu.addActionListener(new ActionListener() { + incomingHttpResponseMenu.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - view.getIncomingRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0)); + view.getIncomingHttpResponseRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0)); + } + }); + + incomingProxyRequestMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + view.getIncomingProxyRequestRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0)); } }); - outgoingMenu.addActionListener(new ActionListener() { + outgoingHttpRequestMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + view.getOutgoingHttpRequestRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0)); + } + }); + + outgoingProxyResponseMenu.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - view.getOutgoingRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0)); + view.getOutgoingProxyResponseRecipePanel().setInput(event.messageEditorRequestResponse().isPresent() ? event.messageEditorRequestResponse().get().requestResponse() : event.selectedRequestResponses().get(0)); } }); diff --git a/src/main/java/burp/CstcHttpHandler.java b/src/main/java/burp/CstcHttpHandler.java index a6224a0..acc3990 100644 --- a/src/main/java/burp/CstcHttpHandler.java +++ b/src/main/java/burp/CstcHttpHandler.java @@ -32,10 +32,10 @@ public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent reque return continueWith(request, Annotations.annotations("CSTC")); } - if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.OUTGOING, requestToBeSent.toolSource().toolType())) { + if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.OUTGOING_HTTP_REQUEST, requestToBeSent.toolSource().toolType())) { ByteArray request = requestToBeSent.toByteArray(); - ByteArray modifiedRequest = view.getOutgoingRecipePanel().bake(request, null); + ByteArray modifiedRequest = view.getOutgoingHttpRequestRecipePanel().bake(request, null); return continueWith(HttpRequest.httpRequest(modifiedRequest).withService(requestToBeSent.httpService())); } else{ @@ -45,12 +45,12 @@ public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent reque @Override public ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived responseReceived) { - if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.INCOMING, responseReceived.toolSource().toolType())) { + if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.INCOMING_HTTP_RESPONSE, responseReceived.toolSource().toolType())) { if(responseReceived.annotations().hasNotes() && responseReceived.annotations().notes().equals("CSTC")) { return continueWith(responseReceived); } ByteArray response = responseReceived.toByteArray(); - ByteArray modifiedResponse = view.getIncomingRecipePanel().bake(response, responseReceived.initiatingRequest().toByteArray()); + ByteArray modifiedResponse = view.getIncomingHttpResponseRecipePanel().bake(response, responseReceived.initiatingRequest().toByteArray()); return continueWith(HttpResponse.httpResponse(modifiedResponse)); } else{ diff --git a/src/main/java/burp/CstcProxyRequestHandler.java b/src/main/java/burp/CstcProxyRequestHandler.java new file mode 100644 index 0000000..e7fb525 --- /dev/null +++ b/src/main/java/burp/CstcProxyRequestHandler.java @@ -0,0 +1,39 @@ +package burp; + +import burp.api.montoya.core.ByteArray; +import burp.api.montoya.core.ToolType; +import burp.api.montoya.http.message.requests.HttpRequest; +import burp.api.montoya.proxy.http.InterceptedRequest; +import burp.api.montoya.proxy.http.ProxyRequestHandler; +import burp.api.montoya.proxy.http.ProxyRequestReceivedAction; +import burp.api.montoya.proxy.http.ProxyRequestToBeSentAction; +import de.usd.cstchef.view.View; +import de.usd.cstchef.view.filter.FilterState; + +import static burp.api.montoya.proxy.http.ProxyRequestReceivedAction.continueWith; + +public class CstcProxyRequestHandler implements ProxyRequestHandler { + + private View view; + + public CstcProxyRequestHandler(View view) { + this.view = view; + } + + @Override + public ProxyRequestReceivedAction handleRequestReceived(InterceptedRequest interceptedRequest) { + if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.INCOMING_PROXY_REQUEST, ToolType.PROXY)) { + ByteArray request = interceptedRequest.toByteArray(); + ByteArray modifiedRequest = view.getIncomingProxyRequestRecipePanel().bake(request, null); + return continueWith(HttpRequest.httpRequest(modifiedRequest).withService(interceptedRequest.httpService())); + } + else{ + return continueWith(interceptedRequest); + } + } + + @Override + public ProxyRequestToBeSentAction handleRequestToBeSent(InterceptedRequest interceptedRequest) { + return ProxyRequestToBeSentAction.continueWith(interceptedRequest); + } +} \ No newline at end of file diff --git a/src/main/java/burp/CstcProxyResponseHandler.java b/src/main/java/burp/CstcProxyResponseHandler.java new file mode 100644 index 0000000..e51f4b5 --- /dev/null +++ b/src/main/java/burp/CstcProxyResponseHandler.java @@ -0,0 +1,39 @@ +package burp; + +import burp.api.montoya.core.ByteArray; +import burp.api.montoya.core.ToolType; +import burp.api.montoya.http.message.responses.HttpResponse; +import burp.api.montoya.proxy.http.InterceptedResponse; +import burp.api.montoya.proxy.http.ProxyResponseHandler; +import burp.api.montoya.proxy.http.ProxyResponseReceivedAction; +import burp.api.montoya.proxy.http.ProxyResponseToBeSentAction; +import de.usd.cstchef.view.View; +import de.usd.cstchef.view.filter.FilterState; + +import static burp.api.montoya.proxy.http.ProxyResponseToBeSentAction.continueWith; + +public class CstcProxyResponseHandler implements ProxyResponseHandler { + + private View view; + + public CstcProxyResponseHandler(View view) { + this.view = view; + } + + @Override + public ProxyResponseReceivedAction handleResponseReceived(InterceptedResponse interceptedResponse) { + return ProxyResponseReceivedAction.continueWith(interceptedResponse); + } + + @Override + public ProxyResponseToBeSentAction handleResponseToBeSent(InterceptedResponse interceptedResponse) { + if (BurpUtils.getInstance().getFilterState().shouldProcess(FilterState.BurpOperation.OUTGOING_PROXY_RESPONSE, ToolType.PROXY)) { + ByteArray response = interceptedResponse.toByteArray(); + ByteArray modifiedResponse = view.getOutgoingProxyResponseRecipePanel().bake(response, interceptedResponse.request().toByteArray()); + return continueWith(HttpResponse.httpResponse(modifiedResponse)); + } + else{ + return continueWith(interceptedResponse); + } + } +} \ No newline at end of file diff --git a/src/main/java/burp/MyExtensionProvidedHttpRequestEditor.java b/src/main/java/burp/MyExtensionProvidedHttpRequestEditor.java index 2de4421..978d526 100644 --- a/src/main/java/burp/MyExtensionProvidedHttpRequestEditor.java +++ b/src/main/java/burp/MyExtensionProvidedHttpRequestEditor.java @@ -36,7 +36,7 @@ public HttpRequest getRequest() @Override public void setRequestResponse(HttpRequestResponse requestResponse) { - ByteArray result = view.getOutgoingRecipePanel().bake(requestResponse.request().toByteArray(), requestResponse.request().toByteArray()); + ByteArray result = view.getOutgoingHttpRequestRecipePanel().bake(requestResponse.request().toByteArray(), requestResponse.request().toByteArray()); this.requestEditor.setContents(result); } @@ -69,4 +69,4 @@ public boolean isModified() { return requestEditor.isModified(); } -} \ No newline at end of file +} diff --git a/src/main/java/de/usd/cstchef/operations/dataformat/FromDecimal.java b/src/main/java/de/usd/cstchef/operations/dataformat/FromDecimal.java old mode 100755 new mode 100644 index b8f103a..90caef4 --- a/src/main/java/de/usd/cstchef/operations/dataformat/FromDecimal.java +++ b/src/main/java/de/usd/cstchef/operations/dataformat/FromDecimal.java @@ -1,78 +1,78 @@ -package de.usd.cstchef.operations.dataformat; - -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Set; - -import javax.swing.JComboBox; - -import burp.api.montoya.core.ByteArray; -import de.usd.cstchef.operations.Operation; -import de.usd.cstchef.operations.Operation.OperationInfos; -import de.usd.cstchef.operations.OperationCategory; -import de.usd.cstchef.operations.dataformat.ToHex.Delimiter; - -@OperationInfos(name = "From Decimal", category = OperationCategory.DATAFORMAT, description = "Converts an integer array back into its raw form.") -public class FromDecimal extends Operation { - - static HashMap delimiters = new HashMap() { - { - put("Space", new Delimiter(" ")); - put("Comma", new Delimiter(",")); - put("Semi-colon", new Delimiter(";")); - put("Colon", new Delimiter(":")); - put("Line feed", new Delimiter("\n")); - put("CRLF", new Delimiter("\r\n")); - } - }; - - private JComboBox delimiterBox; - - @Override - protected ByteArray perform(ByteArray input) throws Exception { - - if(input.length() == 0) { - return input; - } - - String selectedKey = (String) this.delimiterBox.getSelectedItem(); - Delimiter delimiter = ToHex.delimiters.get(selectedKey); - String delimString = new String(delimiter.value, StandardCharsets.UTF_8); - - String[] parts = input.toString().trim().split(delimString); - - byte[] decodedBytes = new byte[parts.length]; - - for (int i = 0; i < parts.length; i++) { - try { - decodedBytes[i] = (byte) Integer.parseInt(parts[i]); - } - catch(NumberFormatException e) { - if(e.getMessage().split("\\s+")[0].equals("For")) { - if(parts[i].length() < 100) { - throw new IllegalArgumentException("Cannot parse string \"" + parts[i] + "\" to an integer."); - } - else { - throw new IllegalArgumentException("Cannot parse parts of the string to an integer."); - } - } - else { - throw new IllegalArgumentException("Please ensure that the input only contains parsable integers and delimiters."); - } - } - } - - String output = new String(decodedBytes, StandardCharsets.UTF_8); - - return factory.createByteArray(output); - } - - @Override - public void createUI() { - Set choices = FromDecimal.delimiters.keySet(); - delimiterBox = new JComboBox(choices.toArray(new String[choices.size()])); - delimiterBox.setSelectedIndex(0); - - this.addUIElement("Delimiter", delimiterBox); - } -} +package de.usd.cstchef.operations.dataformat; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Set; + +import javax.swing.JComboBox; + +import burp.api.montoya.core.ByteArray; +import de.usd.cstchef.operations.Operation; +import de.usd.cstchef.operations.Operation.OperationInfos; +import de.usd.cstchef.operations.OperationCategory; +import de.usd.cstchef.operations.dataformat.ToHex.Delimiter; + +@OperationInfos(name = "From Decimal", category = OperationCategory.DATAFORMAT, description = "Converts an integer array back into its raw form.") +public class FromDecimal extends Operation { + + static HashMap delimiters = new HashMap() { + { + put("Space", new Delimiter(" ")); + put("Comma", new Delimiter(",")); + put("Semi-colon", new Delimiter(";")); + put("Colon", new Delimiter(":")); + put("Line feed", new Delimiter("\n")); + put("CRLF", new Delimiter("\r\n")); + } + }; + + private JComboBox delimiterBox; + + @Override + protected ByteArray perform(ByteArray input) throws Exception { + + if(input.length() == 0) { + return input; + } + + String selectedKey = (String) this.delimiterBox.getSelectedItem(); + Delimiter delimiter = ToHex.delimiters.get(selectedKey); + String delimString = new String(delimiter.value, StandardCharsets.UTF_8); + + String[] parts = input.toString().trim().split(delimString); + + byte[] decodedBytes = new byte[parts.length]; + + for (int i = 0; i < parts.length; i++) { + try { + decodedBytes[i] = (byte) Integer.parseInt(parts[i]); + } + catch(NumberFormatException e) { + if(e.getMessage().split("\\s+")[0].equals("For")) { + if(parts[i].length() < 100) { + throw new IllegalArgumentException("Cannot parse string \"" + parts[i] + "\" to an integer."); + } + else { + throw new IllegalArgumentException("Cannot parse parts of the string to an integer."); + } + } + else { + throw new IllegalArgumentException("Please ensure that the input only contains parsable integers and delimiters."); + } + } + } + + String output = new String(decodedBytes, StandardCharsets.UTF_8); + + return factory.createByteArray(output); + } + + @Override + public void createUI() { + Set choices = FromDecimal.delimiters.keySet(); + delimiterBox = new JComboBox(choices.toArray(new String[choices.size()])); + delimiterBox.setSelectedIndex(0); + + this.addUIElement("Delimiter", delimiterBox); + } +} diff --git a/src/main/java/de/usd/cstchef/operations/dataformat/ToDecimal.java b/src/main/java/de/usd/cstchef/operations/dataformat/ToDecimal.java old mode 100755 new mode 100644 index b5bb8fb..05eb96f --- a/src/main/java/de/usd/cstchef/operations/dataformat/ToDecimal.java +++ b/src/main/java/de/usd/cstchef/operations/dataformat/ToDecimal.java @@ -1,68 +1,68 @@ -package de.usd.cstchef.operations.dataformat; - -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Set; - -import javax.swing.JComboBox; -import burp.api.montoya.core.ByteArray; -import de.usd.cstchef.operations.Operation; -import de.usd.cstchef.operations.Operation.OperationInfos; -import de.usd.cstchef.operations.OperationCategory; -import de.usd.cstchef.operations.dataformat.ToHex.Delimiter; - -@OperationInfos(name = "To Decimal", category = OperationCategory.DATAFORMAT, description = "Converts the input to an integer array.") -public class ToDecimal extends Operation { - - static HashMap delimiters = new HashMap() { - { - put("Space", new Delimiter(" ")); - put("Comma", new Delimiter(",")); - put("Semi-colon", new Delimiter(";")); - put("Colon", new Delimiter(":")); - put("Line feed", new Delimiter("\n")); - put("CRLF", new Delimiter("\r\n")); - } - }; - - private JComboBox delimiterBox; - - @Override - protected ByteArray perform(ByteArray input) throws Exception { - - String selectedKey = (String) this.delimiterBox.getSelectedItem(); - Delimiter delimiter = ToHex.delimiters.get(selectedKey); - String delimString = new String(delimiter.value, StandardCharsets.UTF_8); - - byte[] inputBytes = input.getBytes(); - StringBuilder output = new StringBuilder(); - - if (input.length() > 0 && delimiter.writeAtStart) { - output.append(delimString); - } - - for (int i = 0; i < inputBytes.length - 1; i++) { - output.append(inputBytes[i] & 0xFF); - output.append(delimString); - } - - if (input.length() > 0) { - output.append(inputBytes[inputBytes.length - 1] & 0xFF); - if (delimiter.writeAtEnd) { - output.append(delimString); - } - } - - return factory.createByteArray(output.toString()); - } - - @Override - public void createUI() { - Set choices = ToDecimal.delimiters.keySet(); - delimiterBox = new JComboBox(choices.toArray(new String[choices.size()])); - delimiterBox.setSelectedIndex(0); - - this.addUIElement("Delimiter", delimiterBox); - } -} - +package de.usd.cstchef.operations.dataformat; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Set; + +import javax.swing.JComboBox; +import burp.api.montoya.core.ByteArray; +import de.usd.cstchef.operations.Operation; +import de.usd.cstchef.operations.Operation.OperationInfos; +import de.usd.cstchef.operations.OperationCategory; +import de.usd.cstchef.operations.dataformat.ToHex.Delimiter; + +@OperationInfos(name = "To Decimal", category = OperationCategory.DATAFORMAT, description = "Converts the input to an integer array.") +public class ToDecimal extends Operation { + + static HashMap delimiters = new HashMap() { + { + put("Space", new Delimiter(" ")); + put("Comma", new Delimiter(",")); + put("Semi-colon", new Delimiter(";")); + put("Colon", new Delimiter(":")); + put("Line feed", new Delimiter("\n")); + put("CRLF", new Delimiter("\r\n")); + } + }; + + private JComboBox delimiterBox; + + @Override + protected ByteArray perform(ByteArray input) throws Exception { + + String selectedKey = (String) this.delimiterBox.getSelectedItem(); + Delimiter delimiter = ToHex.delimiters.get(selectedKey); + String delimString = new String(delimiter.value, StandardCharsets.UTF_8); + + byte[] inputBytes = input.getBytes(); + StringBuilder output = new StringBuilder(); + + if (input.length() > 0 && delimiter.writeAtStart) { + output.append(delimString); + } + + for (int i = 0; i < inputBytes.length - 1; i++) { + output.append(inputBytes[i] & 0xFF); + output.append(delimString); + } + + if (input.length() > 0) { + output.append(inputBytes[inputBytes.length - 1] & 0xFF); + if (delimiter.writeAtEnd) { + output.append(delimString); + } + } + + return factory.createByteArray(output.toString()); + } + + @Override + public void createUI() { + Set choices = ToDecimal.delimiters.keySet(); + delimiterBox = new JComboBox(choices.toArray(new String[choices.size()])); + delimiterBox.setSelectedIndex(0); + + this.addUIElement("Delimiter", delimiterBox); + } +} + diff --git a/src/main/java/de/usd/cstchef/view/BurpEditorWrapper.java b/src/main/java/de/usd/cstchef/view/BurpEditorWrapper.java index 6cd3103..e79a329 100644 --- a/src/main/java/de/usd/cstchef/view/BurpEditorWrapper.java +++ b/src/main/java/de/usd/cstchef/view/BurpEditorWrapper.java @@ -41,8 +41,10 @@ public BurpEditorWrapper(CstcMessageEditorController controller, BurpOperation o this.lastContent = ByteArray.byteArray(""); if (BurpUtils.inBurp()) { switch(operation){ - case OUTGOING: burpEditor = api.userInterface().createHttpRequestEditor(); break; - case INCOMING: burpEditor = api.userInterface().createHttpResponseEditor(); break; + case INCOMING_PROXY_REQUEST: + case OUTGOING_HTTP_REQUEST: burpEditor = api.userInterface().createHttpRequestEditor(); break; + case OUTGOING_PROXY_RESPONSE: + case INCOMING_HTTP_RESPONSE: burpEditor = api.userInterface().createHttpResponseEditor(); break; case FORMAT: burpEditor = api.userInterface().createRawEditor(); break; default: break; } @@ -101,9 +103,9 @@ public void setRequestToResponse(ByteArray requestToResponse) { public ByteArray getContents() { if(operation == BurpOperation.FORMAT) return ((RawEditor)burpEditor).getContents(); - else if(operation == BurpOperation.OUTGOING) + else if(operation == BurpOperation.INCOMING_PROXY_REQUEST || operation == BurpOperation.OUTGOING_HTTP_REQUEST) return ((HttpRequestEditor)burpEditor).getRequest().toByteArray(); - else if(operation == BurpOperation.INCOMING) + else if(operation == BurpOperation.INCOMING_HTTP_RESPONSE || operation == BurpOperation.OUTGOING_PROXY_RESPONSE) return ((HttpResponseEditor)burpEditor).getResponse().toByteArray(); else return ByteArray.byteArray(); @@ -113,9 +115,9 @@ else if(operation == BurpOperation.INCOMING) public void setContents(ByteArray contents) { isChangedViaContextMenu = true; this.lastContent = contents; - if(operation == BurpOperation.OUTGOING) + if(operation == BurpOperation.INCOMING_PROXY_REQUEST || operation == BurpOperation.OUTGOING_HTTP_REQUEST) ((HttpRequestEditor)burpEditor).setRequest(HttpRequest.httpRequest(contents)); - else if(operation == BurpOperation.INCOMING) + else if(operation == BurpOperation.INCOMING_HTTP_RESPONSE || operation == BurpOperation.OUTGOING_PROXY_RESPONSE) ((HttpResponseEditor)burpEditor).setResponse(HttpResponse.httpResponse(contents)); else ((RawEditor)burpEditor).setContents(contents); @@ -124,7 +126,7 @@ else if(operation == BurpOperation.INCOMING) @Override public HttpResponse getResponse() { - if(operation != BurpOperation.INCOMING){ + if(operation != BurpOperation.INCOMING_HTTP_RESPONSE && operation != BurpOperation.OUTGOING_PROXY_RESPONSE){ return null; } HttpResponse result; @@ -146,7 +148,7 @@ public void setResponse(HttpResponse response) { @Override public HttpRequest getRequest() { - if(operation != BurpOperation.OUTGOING){ + if(operation != BurpOperation.INCOMING_PROXY_REQUEST && operation != BurpOperation.OUTGOING_HTTP_REQUEST){ return null; } HttpRequest result; diff --git a/src/main/java/de/usd/cstchef/view/RecipePanel.java b/src/main/java/de/usd/cstchef/view/RecipePanel.java index fc58c11..249ece0 100644 --- a/src/main/java/de/usd/cstchef/view/RecipePanel.java +++ b/src/main/java/de/usd/cstchef/view/RecipePanel.java @@ -425,7 +425,24 @@ public void actionPerformed(ActionEvent e) { } public void disableAutobakeIfFilterActive() { - for(Boolean b : BurpUtils.getInstance().getFilterState().getIncomingFilterSettings().values()) { + for(Boolean b : BurpUtils.getInstance().getFilterState().getIncomingHttpResponseFilterSettings().values()) { + if(b) { + this.autoBake = false; + this.bakeCheckBox.setSelected(false); + this.bakeButton.setEnabled(true); + this.bakeCheckBox.setEnabled(false); + this.bakeCheckBox.setToolTipText("Auto bake is disabled if Filter is active."); + this.autoBakeInterval.setEnabled(false); + return; + } + else if(!this.bakeCheckBox.isEnabled() && !b) { + this.bakeCheckBox.setEnabled(true); + this.bakeCheckBox.setToolTipText(""); + this.autoBakeInterval.setEnabled(true); + } + } + + for(Boolean b : BurpUtils.getInstance().getFilterState().getIncomingProxyRequestFilterSettings().values()) { if(b) { this.autoBake = false; this.bakeCheckBox.setSelected(false); @@ -442,7 +459,24 @@ else if(!this.bakeCheckBox.isEnabled() && !b) { } } - for(Boolean b : BurpUtils.getInstance().getFilterState().getOutgoingFilterSettings().values()) { + for(Boolean b : BurpUtils.getInstance().getFilterState().getOutgoingHttpRequestFilterSettings().values()) { + if(b) { + this.autoBake = false; + this.bakeCheckBox.setSelected(false); + this.bakeButton.setEnabled(true); + this.bakeCheckBox.setEnabled(false); + this.bakeCheckBox.setToolTipText("Auto bake is disabled if Filter is active."); + this.autoBakeInterval.setEnabled(false); + return; + } + else if(!this.bakeCheckBox.isEnabled() && !b) { + this.bakeCheckBox.setEnabled(true); + this.bakeCheckBox.setToolTipText(""); + this.autoBakeInterval.setEnabled(true); + } + } + + for(Boolean b : BurpUtils.getInstance().getFilterState().getOutgoingProxyResponseFilterSettings().values()) { if(b) { this.autoBake = false; this.bakeCheckBox.setSelected(false); @@ -500,13 +534,13 @@ public void showInactiveWarning(){ } public void setInput(HttpRequestResponse requestResponse) { - if(operation == BurpOperation.OUTGOING){ + if(operation == BurpOperation.INCOMING_PROXY_REQUEST || operation == BurpOperation.OUTGOING_HTTP_REQUEST){ HttpRequest request = requestResponse.request(); if(request == null) request = HttpRequest.httpRequest(ByteArray.byteArray("The message you have sent via the context menu is not a valid HTML request. Try using the formatting tab.")); this.inputText.setRequest(request); } - else if(operation == BurpOperation.INCOMING) { + else if(operation == BurpOperation.OUTGOING_PROXY_RESPONSE || operation == BurpOperation.INCOMING_HTTP_RESPONSE) { HttpResponse response = requestResponse.response(); if(response == null) { response = HttpResponse.httpResponse(ByteArray.byteArray("The message you have sent via the context menu does not have a valid HTML response. Try including a response to a request or use the formatting tab.")); @@ -750,10 +784,10 @@ public void run() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - if( operation == BurpOperation.OUTGOING) { + if( operation == BurpOperation.INCOMING_PROXY_REQUEST || operation == BurpOperation.OUTGOING_HTTP_REQUEST) { outputText.setRequest(HttpRequest.httpRequest(result)); controllerMod.setRequest(HttpRequest.httpRequest(result)); - } else if (operation == BurpOperation.INCOMING){ + } else if (operation == BurpOperation.OUTGOING_PROXY_RESPONSE || operation == BurpOperation.INCOMING_HTTP_RESPONSE){ outputText.setResponse(HttpResponse.httpResponse(result)); controllerMod.setResponse(HttpResponse.httpResponse(result)); } diff --git a/src/main/java/de/usd/cstchef/view/RequestFilterDialog.java b/src/main/java/de/usd/cstchef/view/RequestFilterDialog.java index 7e82e9b..e92b2b5 100644 --- a/src/main/java/de/usd/cstchef/view/RequestFilterDialog.java +++ b/src/main/java/de/usd/cstchef/view/RequestFilterDialog.java @@ -30,8 +30,10 @@ public static RequestFilterDialog getInstance() { private RequestFilterDialog() { this.setLayout(new GridLayout(0, 3)); - JPanel incomingPanel = createPanel(BurpOperation.INCOMING); - JPanel outgoingPanel = createPanel(BurpOperation.OUTGOING); + JPanel incomingHttpResponsePanel = createHttpPanel(BurpOperation.INCOMING_HTTP_RESPONSE); + JPanel incomingProxyRequestPanel = createProxyPanel(BurpOperation.INCOMING_PROXY_REQUEST); + JPanel outgoingHttpRequestPanel = createHttpPanel(BurpOperation.OUTGOING_HTTP_REQUEST); + JPanel outgoingProxyResponsePanel = createProxyPanel(BurpOperation.OUTGOING_PROXY_RESPONSE); JPanel labelPanel = new JPanel(); labelPanel.setLayout(new GridLayout(7, 0)); @@ -43,12 +45,14 @@ private RequestFilterDialog() { this.removeAll(); this.add(labelPanel); - this.add("Outgoing", outgoingPanel); - this.add("Incoming", incomingPanel); + this.add("Outgoing HTTP Request", outgoingHttpRequestPanel); + this.add("Incoming HTTP Response", incomingHttpResponsePanel); + this.add("Incoming Proxy Request", incomingProxyRequestPanel); + this.add("Outgoing Proxy Response", outgoingProxyResponsePanel); } - private JPanel createPanel(BurpOperation operation) { + private JPanel createHttpPanel(BurpOperation operation) { if (BurpUtils.getInstance().getFilterState().getFilterMask(operation).isEmpty()) { BurpUtils.getInstance().getFilterState().getFilterMask(operation).put(new Filter(ToolType.PROXY, ToolType.PROXY.ordinal()), false); BurpUtils.getInstance().getFilterState().getFilterMask(operation).put(new Filter(ToolType.REPEATER, ToolType.REPEATER.ordinal()), false); @@ -60,7 +64,7 @@ private JPanel createPanel(BurpOperation operation) { JPanel panel = new JPanel(); panel.add(new JLabel(operation.toString())); - for (Map.Entry entry : BurpUtils.getInstance().getFilterState().getFilterMask(operation).entrySet()) { + for (Map.Entry entry : BurpUtils.getInstance().getFilterState().getFilterMask(operation).entrySet()) { Filter filter = entry.getKey(); boolean selected = entry.getValue(); @@ -85,6 +89,36 @@ public void actionPerformed(ActionEvent e) { panel.setLayout(new GridLayout(7, 0)); return panel; } + + private JPanel createProxyPanel(BurpOperation operation) { + if (BurpUtils.getInstance().getFilterState().getFilterMask(operation).isEmpty()) { + BurpUtils.getInstance().getFilterState().getFilterMask(operation).put(new Filter(ToolType.PROXY, ToolType.PROXY.ordinal()), false); + } + JPanel panel = new JPanel(); + for (Map.Entry entry : BurpUtils.getInstance().getFilterState().getFilterMask(operation).entrySet()) { + Filter filter = entry.getKey(); + boolean selected = entry.getValue(); + + JCheckBox box = new JCheckBox(); + box.setSelected(selected); + box.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // set Filter + BurpUtils.getInstance().getFilterState().getFilterMask(operation).put(filter, box.isSelected()); + + // disable autobake + BurpUtils.getInstance().getView().preventRaceConditionOnVariables(); + + // remove inactivity warning + BurpUtils.getInstance().getView().updateInactiveWarnings(); + } + }); + panel.add(box); + } + panel.add(new JLabel(operation.toString())); + return panel; + } public void updateFilterSettings(){ RequestFilterDialog.instance = new RequestFilterDialog(); diff --git a/src/main/java/de/usd/cstchef/view/View.java b/src/main/java/de/usd/cstchef/view/View.java index eea0a81..ddd9785 100644 --- a/src/main/java/de/usd/cstchef/view/View.java +++ b/src/main/java/de/usd/cstchef/view/View.java @@ -16,8 +16,10 @@ public class View extends JPanel { - private RecipePanel incomingRecipePanel; - private RecipePanel outgoingRecipePanel; + private RecipePanel incomingHttpResponseRecipePanel; + private RecipePanel incomingProxyRequestRecipePanel; + private RecipePanel outgoingHttpRequestRecipePanel; + private RecipePanel outgoingProxyResponseRecipePanel; private RecipePanel formatRecipePanel; public View(){ @@ -30,22 +32,34 @@ public View(FilterState state) { this.setLayout(new BorderLayout()); JTabbedPane tabbedPane = new JTabbedPane(); - incomingRecipePanel = new RecipePanel(BurpOperation.INCOMING); - outgoingRecipePanel = new RecipePanel(BurpOperation.OUTGOING); + incomingHttpResponseRecipePanel = new RecipePanel(BurpOperation.INCOMING_HTTP_RESPONSE); + incomingProxyRequestRecipePanel = new RecipePanel(BurpOperation.INCOMING_PROXY_REQUEST); + outgoingHttpRequestRecipePanel = new RecipePanel(BurpOperation.OUTGOING_HTTP_REQUEST); + outgoingProxyResponseRecipePanel = new RecipePanel(BurpOperation.OUTGOING_PROXY_RESPONSE); formatRecipePanel = new RecipePanel(BurpOperation.FORMAT); - tabbedPane.addTab("Outgoing Requests", null, outgoingRecipePanel, "Outgoing requests from the browser, the repeater or another tool."); - tabbedPane.addTab("Incoming Responses", null, incomingRecipePanel, "Responses from the server."); + tabbedPane.addTab("Incoming Proxy Requests", null, incomingProxyRequestRecipePanel, "Incoming requests from the client application."); + tabbedPane.addTab("Outgoing HTTP Requests", null, outgoingHttpRequestRecipePanel, "Outgoing requests from any tool of Burp."); + tabbedPane.addTab("Incoming HTTP Responses", null, incomingHttpResponseRecipePanel, "Responses from the server."); + tabbedPane.addTab("Outgoing Proxy Responses", null, outgoingProxyResponseRecipePanel, "Outgoing responses from Burp."); tabbedPane.addTab("Formatting", null, formatRecipePanel, "Formatting for messages."); this.add(tabbedPane); } - public RecipePanel getIncomingRecipePanel() { - return this.incomingRecipePanel; + public RecipePanel getIncomingHttpResponseRecipePanel() { + return this.incomingHttpResponseRecipePanel; + } + + public RecipePanel getIncomingProxyRequestRecipePanel() { + return this.incomingProxyRequestRecipePanel; } - public RecipePanel getOutgoingRecipePanel() { - return this.outgoingRecipePanel; + public RecipePanel getOutgoingHttpRequestRecipePanel() { + return this.outgoingHttpRequestRecipePanel; + } + + public RecipePanel getOutgoingProxyResponseRecipePanel() { + return this.outgoingProxyResponseRecipePanel; } public RecipePanel getFormatRecipePanel() { @@ -64,22 +78,36 @@ public static void main(String[] args) { } public void updateInactiveWarnings() { - incomingRecipePanel.showInactiveWarning(); - for(Boolean b : BurpUtils.getInstance().getFilterState().getIncomingFilterSettings().values()){ + incomingHttpResponseRecipePanel.showInactiveWarning(); + for(Boolean b : BurpUtils.getInstance().getFilterState().getIncomingHttpResponseFilterSettings().values()){ + if(b == true) + incomingHttpResponseRecipePanel.hideInactiveWarning(); + } + + incomingProxyRequestRecipePanel.showInactiveWarning(); + for(Boolean b : BurpUtils.getInstance().getFilterState().getIncomingProxyRequestFilterSettings().values()){ if(b == true) - incomingRecipePanel.hideInactiveWarning(); + incomingProxyRequestRecipePanel.hideInactiveWarning(); } - outgoingRecipePanel.showInactiveWarning(); - for(Boolean b : BurpUtils.getInstance().getFilterState().getOutgoingFilterSettings().values()){ + outgoingHttpRequestRecipePanel.showInactiveWarning(); + for(Boolean b : BurpUtils.getInstance().getFilterState().getOutgoingHttpRequestFilterSettings().values()){ + if(b == true) + outgoingHttpRequestRecipePanel.hideInactiveWarning(); + } + + outgoingProxyResponseRecipePanel.showInactiveWarning(); + for(Boolean b : BurpUtils.getInstance().getFilterState().getOutgoingProxyResponseFilterSettings().values()){ if(b == true) - outgoingRecipePanel.hideInactiveWarning(); + outgoingProxyResponseRecipePanel.hideInactiveWarning(); } } public void preventRaceConditionOnVariables() { - incomingRecipePanel.disableAutobakeIfFilterActive(); - outgoingRecipePanel.disableAutobakeIfFilterActive(); + incomingHttpResponseRecipePanel.disableAutobakeIfFilterActive(); + incomingProxyRequestRecipePanel.disableAutobakeIfFilterActive(); + outgoingHttpRequestRecipePanel.disableAutobakeIfFilterActive(); + outgoingProxyResponseRecipePanel.disableAutobakeIfFilterActive(); formatRecipePanel.disableAutobakeIfFilterActive(); } } diff --git a/src/main/java/de/usd/cstchef/view/filter/FilterState.java b/src/main/java/de/usd/cstchef/view/filter/FilterState.java index 681871f..1268e02 100644 --- a/src/main/java/de/usd/cstchef/view/filter/FilterState.java +++ b/src/main/java/de/usd/cstchef/view/filter/FilterState.java @@ -10,27 +10,42 @@ public class FilterState implements Serializable{ @JsonDeserialize(keyUsing = FilterStateDeserializer.class) - private LinkedHashMap incomingFilterSettings; + private LinkedHashMap incomingHttpResponseFilterSettings; @JsonDeserialize(keyUsing = FilterStateDeserializer.class) - private LinkedHashMap outgoingFilterSettings; - - public FilterState(LinkedHashMap incomingFilterSettings, - LinkedHashMap outgoingFilterSettings) { - this.incomingFilterSettings = incomingFilterSettings; - this.outgoingFilterSettings = outgoingFilterSettings; + private LinkedHashMap incomingProxyRequestFilterSettings; + @JsonDeserialize(keyUsing = FilterStateDeserializer.class) + private LinkedHashMap outgoingHttpRequestFilterSettings; + @JsonDeserialize(keyUsing = FilterStateDeserializer.class) + private LinkedHashMap outgoingProxyResponseFilterSettings; + + public FilterState(LinkedHashMap incomingHttpResponseFilterSettings, + LinkedHashMap incomingProxyRequestFilterSettings, + LinkedHashMap outgoingHttpRequestFilterSettings, + LinkedHashMap outgoingProxyResponseFilterSettings) { + this.incomingHttpResponseFilterSettings = incomingHttpResponseFilterSettings; + this.incomingProxyRequestFilterSettings = incomingProxyRequestFilterSettings; + this.outgoingHttpRequestFilterSettings = outgoingHttpRequestFilterSettings; + this.outgoingProxyResponseFilterSettings = outgoingProxyResponseFilterSettings; } public FilterState() { - this(new LinkedHashMap(), new LinkedHashMap()); + this(new LinkedHashMap(), new LinkedHashMap(), + new LinkedHashMap(), new LinkedHashMap()); } public void setFilterMask(LinkedHashMap filterMask, BurpOperation operation) { switch (operation) { - case INCOMING: - incomingFilterSettings = filterMask; + case INCOMING_HTTP_RESPONSE: + incomingHttpResponseFilterSettings = filterMask; + break; + case INCOMING_PROXY_REQUEST: + incomingProxyRequestFilterSettings = filterMask; break; - case OUTGOING: - outgoingFilterSettings = filterMask; + case OUTGOING_HTTP_REQUEST: + outgoingHttpRequestFilterSettings = filterMask; + break; + case OUTGOING_PROXY_RESPONSE: + outgoingProxyResponseFilterSettings = filterMask; break; default: break; @@ -39,29 +54,43 @@ public void setFilterMask(LinkedHashMap filterMask, BurpOperati public LinkedHashMap getFilterMask(BurpOperation operation) { switch (operation) { - case INCOMING: - return incomingFilterSettings; - case OUTGOING: - return outgoingFilterSettings; + case INCOMING_HTTP_RESPONSE: + return incomingHttpResponseFilterSettings; + case INCOMING_PROXY_REQUEST: + return incomingProxyRequestFilterSettings; + case OUTGOING_HTTP_REQUEST: + return outgoingHttpRequestFilterSettings; + case OUTGOING_PROXY_RESPONSE: + return outgoingProxyResponseFilterSettings; default: return new LinkedHashMap(); } } - public void setFilterMask(LinkedHashMap incomingFilterMask, - LinkedHashMap outgoingFilterMask) { - this.incomingFilterSettings = incomingFilterMask; - this.outgoingFilterSettings = outgoingFilterMask; + public void setFilterMask(LinkedHashMap incomingHttpResponseFilterMask, + LinkedHashMap incomingProxyRequestFilterMask, + LinkedHashMap outgoingHttpRequestFilterMask, + LinkedHashMap outgoingProxyResponseFilterMask) { + this.incomingHttpResponseFilterSettings = incomingHttpResponseFilterMask; + this.incomingProxyRequestFilterSettings = incomingProxyRequestFilterMask; + this.outgoingHttpRequestFilterSettings = outgoingHttpRequestFilterMask; + this.outgoingProxyResponseFilterSettings = outgoingProxyResponseFilterMask; } public boolean shouldProcess(BurpOperation operation, ToolType toolType) { LinkedHashMap filterSettings; switch (operation) { - case INCOMING: - filterSettings = incomingFilterSettings; + case INCOMING_HTTP_RESPONSE: + filterSettings = incomingHttpResponseFilterSettings; + break; + case INCOMING_PROXY_REQUEST: + filterSettings = incomingProxyRequestFilterSettings; + break; + case OUTGOING_HTTP_REQUEST: + filterSettings = outgoingHttpRequestFilterSettings; break; - case OUTGOING: - filterSettings = outgoingFilterSettings; + case OUTGOING_PROXY_RESPONSE: + filterSettings = outgoingProxyResponseFilterSettings; break; default: filterSettings = new LinkedHashMap<>(); @@ -77,35 +106,58 @@ public boolean shouldProcess(BurpOperation operation, ToolType toolType) { return false; } - public LinkedHashMap getIncomingFilterSettings() { - return this.incomingFilterSettings; + public LinkedHashMap getIncomingHttpResponseFilterSettings() { + return this.incomingHttpResponseFilterSettings; } - public void setIncomingFilterSettings(LinkedHashMap incomingFilterSettings) { - this.incomingFilterSettings = incomingFilterSettings; + public void setIncomingHttpResponseFilterSettings(LinkedHashMap incomingHttpResponseFilterSettings) { + this.incomingHttpResponseFilterSettings = incomingHttpResponseFilterSettings; + } + + public LinkedHashMap getIncomingProxyRequestFilterSettings() { + return this.incomingProxyRequestFilterSettings; + } + + public void setIncomingProxyRequestFilterSettings(LinkedHashMap incomingProxyRequestFilterSettings) { + this.incomingProxyRequestFilterSettings = incomingProxyRequestFilterSettings; } - public LinkedHashMap getOutgoingFilterSettings() { - return this.outgoingFilterSettings; + public LinkedHashMap getOutgoingHttpRequestFilterSettings() { + return this.outgoingHttpRequestFilterSettings; + } + + public void setOutgoingHttpRequestFilterSettings(LinkedHashMap outgoingHttpRequestFilterSettings) { + this.outgoingHttpRequestFilterSettings = outgoingHttpRequestFilterSettings; + } + + public LinkedHashMap getOutgoingProxyResponseFilterSettings() { + return this.outgoingProxyResponseFilterSettings; } - public void setOutgoingFilterSettings(LinkedHashMap outgoingFilterSettings) { - this.outgoingFilterSettings = outgoingFilterSettings; + public void setOutgoingProxyResponseFilterSettings(LinkedHashMap outgoingProxyResponseFilterSettings) { + this.outgoingProxyResponseFilterSettings = outgoingProxyResponseFilterSettings; } public String toString(){ - return "Incoming: " + this.incomingFilterSettings.toString() + "\nOutgoing: " + this.outgoingFilterSettings.toString(); + return "Incoming HTTP Response: " + this.incomingHttpResponseFilterSettings.toString() + + "\nIncoming Proxy Request: " + this.incomingProxyRequestFilterSettings.toString() + + "\nOutgoing HTTP Request: " + this.outgoingHttpRequestFilterSettings.toString() + + "\nOutgoing Proxy Response: " + this.outgoingProxyResponseFilterSettings.toString(); } public enum BurpOperation { - INCOMING, - OUTGOING, + INCOMING_HTTP_RESPONSE, + INCOMING_PROXY_REQUEST, + OUTGOING_HTTP_REQUEST, + OUTGOING_PROXY_RESPONSE, FORMAT; public String toString(){ switch(this){ - case INCOMING: return "Incoming"; - case OUTGOING: return "Outgoing"; + case INCOMING_HTTP_RESPONSE: return "Incoming_HTTP_Response"; + case INCOMING_PROXY_REQUEST: return "Incoming_Proxy_Request"; + case OUTGOING_HTTP_REQUEST: return "Outgoing_HTTP_Request"; + case OUTGOING_PROXY_RESPONSE: return "Outgoing_Proxy_Response"; case FORMAT: return "Formatting"; default: return ""; }