Skip to content

Commit

Permalink
Support BurpSuite 2 dark theme, reflections bugfix
Browse files Browse the repository at this point in the history
  • Loading branch information
hvqzao committed May 20, 2019
1 parent 7c3f627 commit 8830384
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 80 deletions.
144 changes: 106 additions & 38 deletions src/hvqzao/flow/FlowExtension.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Flow Burp Extension, (c) 2015-2017 Marcin Woloszyn (@hvqzao), Released under MIT license
// Flow Burp Extension, (c) 2015-2019 Marcin Woloszyn (@hvqzao), Released under MIT license
package hvqzao.flow;

import hvqzao.flow.ui.DialogWrapper;
Expand Down Expand Up @@ -61,7 +61,7 @@
import burp.IScopeChangeListener;
import burp.ITab;
import hvqzao.flow.ui.BooleanTableCellRenderer;
import static hvqzao.flow.ui.Helper.cellBackground;
import hvqzao.flow.ui.ThemeHelper;
import java.awt.Dialog;
import java.io.PrintWriter;
import java.util.List;
Expand All @@ -77,7 +77,11 @@

public class FlowExtension implements IBurpExtender, ITab, IHttpListener, IScopeChangeListener, IExtensionStateListener {

private final String version = "Flow v1.23 (2018-04-16) (unreleased)";
private final String version = "Flow v1.24 (2019-05-20)";
// Changes in v1.24:
// - rows coloring is now disabled on dark theme
// - reflections count display limit introduced
//
// Changes in v1.23:
// - Center "Add new sitemap issue" dialog, resize according to preferred size
// - Filter by search term does not break window anymore when search is too long
Expand Down Expand Up @@ -176,9 +180,15 @@ public class FlowExtension implements IBurpExtender, ITab, IHttpListener, IScope
private boolean autoDelete = false;
private int autoDeleteKeep = 1000;
private boolean autoPopulate = false;
private boolean showReflections = true;
private int showReflectionsCount;
private final int showReflectionsCountMax = 50;
private final int showReflectionsCountDefault = 10;
private boolean modalAutoPopulate;
private boolean modalAutoDelete;
private int modalAutoDeleteKeep;
private boolean modalShowReflections;
private int modalShowReflectionsCount;
private static PrintWriter stderr;
private FilterWorker flowFilterWorker;
private static int sortOrder;
Expand Down Expand Up @@ -206,7 +216,7 @@ public void run() {
ImageIcon iconNewWindow = new ImageIcon(new ImageIcon(getClass().getResource("/hvqzao/flow/resources/newwindow.png")).getImage().getScaledInstance(13, 13, java.awt.Image.SCALE_SMOOTH));
ImageIcon iconCheckbox = new ImageIcon(new ImageIcon(getClass().getResource("/hvqzao/flow/resources/checkbox.png")).getImage().getScaledInstance(13, 13, java.awt.Image.SCALE_SMOOTH));
Dimension iconDimension = new Dimension(24, 24);

// flow tab prolog: vertical split
flowTab = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
callbacks.customizeUiComponent(flowTab);
Expand Down Expand Up @@ -723,6 +733,14 @@ public void actionPerformed(ActionEvent e) {
flowTableSorter.sort();
}
}
if (showReflections != modalShowReflections) {
showReflections = modalShowReflections;
callbacks.saveExtensionSetting("showReflections", showReflections ? "1" : "0");
}
if (showReflectionsCount != modalShowReflectionsCount) {
showReflectionsCount = modalShowReflectionsCount;
callbacks.saveExtensionSetting("showReflectionsCount", String.valueOf(showReflectionsCount));
}
}
}
});
Expand All @@ -742,6 +760,8 @@ public void actionPerformed(ActionEvent e) {
autoPopulate = "1".equals(callbacks.loadExtensionSetting("autoPopulateProxy"));
autoDeleteKeep = validateAutoDeleteKeep(callbacks.loadExtensionSetting("autoDeleteKeep"));
autoDelete = "1".equals(callbacks.loadExtensionSetting("autoDelete"));
showReflections = "0".equals(callbacks.loadExtensionSetting("showReflections")) == false;
showReflectionsCount = parseReflectionsCount(callbacks.loadExtensionSetting("showReflectionsCount"));
//

//
Expand All @@ -751,6 +771,14 @@ public void actionPerformed(ActionEvent e) {
//callbacks.printOutput("Initializing extension with contents of Burp Proxy...");
(new PopulateWorker(callbacks.getProxyHistory())).execute();
}

//Set<Map.Entry<Object, Object>> entries = UIManager.getLookAndFeelDefaults().entrySet();
//for (Map.Entry<Object, Object> entry : entries) {
// if (entry.getValue() instanceof Color) {
// stderr.println(String.valueOf(entry.getKey()) + "\t" + String.valueOf(UIManager.getColor(entry.getKey())) + "\t" + String.valueOf(entry.getValue()));
// }
//}

//callbacks.printOutput("Loaded.");
// TODO end main
}
Expand Down Expand Up @@ -1033,7 +1061,7 @@ private boolean showOptionsDialog() {
//
// wrap optionsPane
wrapper.getScrollPane().getViewport().add(optionsPane);
dialog.setBounds(100, 100, 526, 420);
dialog.setBounds(100, 100, 526, 500);
dialog.setContentPane(wrapper);
//
modalResult = false;
Expand All @@ -1043,6 +1071,8 @@ private boolean showOptionsDialog() {
optionsPane.getAutoPopulate().setSelected(autoPopulate);
optionsPane.getAutoDelete().setSelected(autoDelete);
optionsPane.getAutoDeleteKeep().setText(String.valueOf(autoDeleteKeep));
optionsPane.getShowReflections().setSelected(showReflections);
optionsPane.getShowReflectionsCount().setText(String.valueOf(showReflectionsCount));
//
JButton ok = wrapper.getOkButton();
callbacks.customizeUiComponent(ok);
Expand All @@ -1054,6 +1084,8 @@ public void actionPerformed(ActionEvent e) {
modalAutoPopulate = optionsPane.getAutoPopulate().isSelected();
modalAutoDelete = optionsPane.getAutoDelete().isSelected();
modalAutoDeleteKeep = validateAutoDeleteKeep(optionsPane.getAutoDeleteKeep().getText());
modalShowReflections = optionsPane.getShowReflections().isSelected();
modalShowReflectionsCount = parseReflectionsCount(optionsPane.getShowReflectionsCount().getText());
dialog.dispose();
}
});
Expand Down Expand Up @@ -2399,44 +2431,62 @@ protected void setValue(Object value) {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
final Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
// c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE);
//if (!isSelected && tempy != null && flowTable.convertRowIndexToModel(row) == flow.indexOf(tempy)) {
// c.setForeground(Color.blue);
//} else {
// c.setForeground(Color.black);
//}
int modelRow = table.convertRowIndexToModel(row);
FlowEntry entry = flow.get(modelRow);
int r = 0, g = 0, b = 0;
if (entry.status == 404 || entry.status == 403) {
r += 196;
g += 128;
b += 128;
}
if (entry.status == 500) {
g += 196;
}
if (entry.toolFlag != IBurpExtenderCallbacks.TOOL_PROXY) {
b += 196;
}
if (r > 255) {
r = 255;
}
if (g > 255) {
g = 255;
}
if (b > 255) {
b = 255;
}
c.setForeground(new Color(r, g, b));
if (ThemeHelper.isDarkTheme() == false) {
// c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE);
//if (!isSelected && tempy != null && flowTable.convertRowIndexToModel(row) == flow.indexOf(tempy)) {
// c.setForeground(Color.blue);
//} else {
// c.setForeground(Color.black);
//}
int r = 0, g = 0, b = 0;
if (entry.status == 404 || entry.status == 403) {
r += 196;
g += 128;
b += 128;
}
if (entry.status == 500) {
g += 196;
}
if (entry.toolFlag != IBurpExtenderCallbacks.TOOL_PROXY) {
b += 196;
}
if (r > 255) {
r = 255;
}
if (g > 255) {
g = 255;
}
if (b > 255) {
b = 255;
}
c.setForeground(new Color(r, g, b));

c.setBackground(cellBackground(table.getRowCount(), row, isSelected));
c.setBackground(ThemeHelper.cellBackground(table.getRowCount(), row, isSelected));
}

final ArrayList<String> reflections = new ArrayList<>();
for (IParameter reflection : entry.getReflections()) {
reflections.add(new StringBuilder(" &nbsp; &nbsp; (").append(paramType(reflection.getType())).append(") ").append(reflection.getName()).append("=").append(reflection.getValue()).toString());
}
if (reflections.size() > 0) {
final ArrayList<IParameter> allReflections = entry.getReflections();
int reflectionsAmount = allReflections.size();
if (reflectionsAmount > showReflectionsCount) {
reflectionsAmount = showReflectionsCount;
}
if (allReflections.size() > 0) {
for (IParameter reflection : allReflections.subList(0, reflectionsAmount)) {
String param = reflection.getName();
if (param.length() > 50) {
param = param.substring(0, 50 - 3) + "...";
}
String val = reflection.getValue();
if (val.length() > 50) {
val = val.substring(0, 50 - 3) + "...";
}
reflections.add(new StringBuilder(" &nbsp; &nbsp; (").append(paramType(reflection.getType())).append(") ").append(param).append("=").append(val).toString());
}
if (allReflections.size() > showReflectionsCount) {
reflections.add("...");
}
((JLabel) c).setToolTipText(new StringBuilder("<html>Reflections:<br/>").append(String.join("<br/>", reflections)).append("</html>").toString());
} else {
((JLabel) c).setToolTipText(null);
Expand Down Expand Up @@ -2501,4 +2551,22 @@ public static FlowExtension getInstance() {
public static PrintWriter getStderr() {
return stderr;
}

private int parseReflectionsCount(String text) {
int result = showReflectionsCountDefault;
if (text != null) {
try {
showReflectionsCount = Integer.parseInt(text);
if (showReflectionsCount > showReflectionsCountMax) {
showReflectionsCount = showReflectionsCountMax;
}
if (showReflectionsCount < 0) {
showReflectionsCount = 0;
}
} catch (NumberFormatException ex) {
// do nothing
}
}
return result;
}
}
2 changes: 1 addition & 1 deletion src/hvqzao/flow/FlowFilterPopup.form
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<CompoundBorder>
<Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
<LineBorder thickness="2">
<Color PropertyName="color" blue="ff" green="ff" id="white" palette="1" red="ff" type="palette"/>
<Color PropertyName="color" blue="ff" green="ff" id="Table.background" palette="3" red="ff" type="palette"/>
</LineBorder>
</Border>
<Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo">
Expand Down
2 changes: 1 addition & 1 deletion src/hvqzao/flow/FlowFilterPopup.java
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ private void initComponents() {
FlowFilterCaptureSourceProxyOnly = new javax.swing.JCheckBox();
FlowFilterBottom = new javax.swing.JPanel();

setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.white, 2), javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.darkGray), javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5))));
setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Table.background"), 2), javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.darkGray), javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5))));

flowFilterHelp.setMargin(new java.awt.Insets(0, 0, 0, 0));
flowFilterHelp.setMaximumSize(new java.awt.Dimension(24, 24));
Expand Down
30 changes: 25 additions & 5 deletions src/hvqzao/flow/FlowOptionsPane.form
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
<Group type="102" attributes="0">
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel2" pref="0" max="32767" attributes="0"/>
<Component id="jLabel3" pref="308" max="32767" attributes="0"/>
<Component id="jLabel2" pref="341" max="32767" attributes="0"/>
<Component id="jLabel3" pref="341" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
Expand All @@ -56,13 +56,18 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="autoDelete" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="autoDeleteKeep" min="-2" pref="40" max="-2" attributes="0"/>
</Group>
<Component id="autoPopulate" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="showReflections" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="showReflectionsCount" min="-2" pref="32" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<EmptySpace min="0" pref="81" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
Expand Down Expand Up @@ -94,13 +99,18 @@
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="showReflections" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="showReflectionsCount" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="autoPopulate" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="autoDelete" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="autoDeleteKeep" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="12" max="32767" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
Expand Down Expand Up @@ -194,5 +204,15 @@
<Property name="text" type="java.lang.String" value="Populate with requests from Proxy history"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="showReflections">
<Properties>
<Property name="text" type="java.lang.String" value="Show parameter reflections. Count:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="showReflectionsCount">
<Properties>
<Property name="text" type="java.lang.String" value="10"/>
</Properties>
</Component>
</SubComponents>
</Form>
Loading

0 comments on commit 8830384

Please sign in to comment.