Skip to content

Commit

Permalink
Merge pull request #27 from DolphFlynn/intruder_mvc
Browse files Browse the repository at this point in the history
Intruder mvc
  • Loading branch information
DolphFlynn authored Feb 25, 2024
2 parents 02518e9 + 816e665 commit 1ca2c7e
Show file tree
Hide file tree
Showing 14 changed files with 1,335 additions and 483 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,11 @@ public void addKey(Key key) {
oldKey = keys.put(key.getID(), key);
}

for (KeysModelListener modelListener: this.modelListeners) {
modelListener.notifyKeyDeleted(oldKey);
for (KeysModelListener modelListener : modelListeners) {
if (oldKey != null) {
modelListener.notifyKeyDeleted(oldKey);
}

modelListener.notifyKeyInserted(key);
}
}
Expand Down Expand Up @@ -165,7 +168,7 @@ public void deleteKey(String keyId) {
}

if (rowIndex >= 0) {
for (KeysModelListener modelListener: this.modelListeners) {
for (KeysModelListener modelListener : this.modelListeners) {
modelListener.notifyKeyDeleted(rowIndex);
}
}
Expand Down
307 changes: 19 additions & 288 deletions src/main/java/com/blackberry/jwteditor/view/config/ConfigView.form

Large diffs are not rendered by default.

179 changes: 13 additions & 166 deletions src/main/java/com/blackberry/jwteditor/view/config/ConfigView.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,185 +20,32 @@

import burp.api.montoya.ui.UserInterface;
import burp.config.BurpConfig;
import burp.intruder.FuzzLocation;
import burp.intruder.IntruderConfig;
import burp.proxy.HighlightColor;
import burp.proxy.ProxyConfig;
import burp.scanner.ScannerConfig;
import com.blackberry.jwteditor.model.keys.Key;
import com.blackberry.jwteditor.model.keys.KeysModel;
import com.blackberry.jwteditor.model.keys.KeysModelListener.SimpleKeysModelListener;
import com.blackberry.jwteditor.view.utils.DocumentAdapter;
import com.nimbusds.jose.JWSAlgorithm;

import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.Optional;

import static java.awt.Font.BOLD;


public class ConfigView {
private final IntruderConfig intruderConfig;
private final BurpConfig burpConfig;
private final UserInterface userInterface;
private final boolean isProVersion;
private final KeysModel keysModel;

private JPanel mainPanel;
private JCheckBox checkBoxHighlightJWT;
private JLabel labelHighlightColor;
private JComboBox comboBoxHighlightColor;
private JLabel labelHighlightJWT;
private JTextField intruderParameterName;
private JComboBox comboBoxPayloadPosition;
private JComboBox comboBoxIntruderSigningKeyId;
private JCheckBox checkBoxHeaderInsertionPoint;
private JTextField scannerParameterName;
private JPanel proxyPanel;
private JLabel proxyLabel;
private JLabel intruderLabel;
private JLabel scannerLabel;
private JPanel intruderPanel;
private JLabel spacerLabel;
private JCheckBox resignIntruderJWS;
private JComboBox comboBoxIntruderSigningAlg;
private ProxyConfigView proxyConfigView;
private ScannerConfigView scannerConfigView;
private IntruderConfigView intruderConfigView;

public ConfigView(BurpConfig burpConfig, UserInterface userInterface, boolean isProVersion, KeysModel keysModel) {
this.burpConfig = burpConfig;
this.userInterface = userInterface;
this.isProVersion = isProVersion;
this.keysModel = keysModel;
this.intruderConfig = burpConfig.intruderConfig();

ProxyConfig proxyConfig = burpConfig.proxyConfig();

checkBoxHighlightJWT.setSelected(proxyConfig.highlightJWT());
checkBoxHighlightJWT.addActionListener(e -> {
comboBoxHighlightColor.setEnabled(checkBoxHighlightJWT.isSelected());
proxyConfig.setHighlightJWT(checkBoxHighlightJWT.isSelected());
});

comboBoxHighlightColor.setModel(new DefaultComboBoxModel<>(HighlightColor.values()));
comboBoxHighlightColor.setSelectedItem(proxyConfig.highlightColor());
comboBoxHighlightColor.setEnabled(proxyConfig.highlightJWT());
comboBoxHighlightColor.addActionListener(e -> proxyConfig.setHighlightColor((HighlightColor) comboBoxHighlightColor.getSelectedItem()));

intruderParameterName.setText(intruderConfig.fuzzParameter());
intruderParameterName.getDocument().addDocumentListener(
new DocumentAdapter(e -> intruderConfig.setFuzzParameter(intruderParameterName.getText()))
);

comboBoxPayloadPosition.setModel(new DefaultComboBoxModel<>(FuzzLocation.values()));
comboBoxPayloadPosition.setSelectedItem(intruderConfig.fuzzLocation());
comboBoxPayloadPosition.addActionListener(e -> intruderConfig.setFuzzLocation((FuzzLocation) comboBoxPayloadPosition.getSelectedItem()));

updateSigningKeyList();
comboBoxIntruderSigningKeyId.addActionListener(e -> {
String newSigningKeyId = (String) comboBoxIntruderSigningKeyId.getSelectedItem();

if (!intruderConfig.signingKeyId().equals(newSigningKeyId)) {
intruderConfig.setSigningKeyId(newSigningKeyId);
updateSigningAlgorithmList();
}
});
comboBoxIntruderSigningAlg.addActionListener(e -> intruderConfig.setSigningAlgorithm((JWSAlgorithm) comboBoxIntruderSigningAlg.getSelectedItem()));
resignIntruderJWS.addActionListener(e -> intruderConfig.setResign(resignIntruderJWS.isSelected()));
keysModel.addKeyModelListener(new SimpleKeysModelListener(this::updateSigningKeyList));

ScannerConfig scannerConfig = burpConfig.scannerConfig();

checkBoxHeaderInsertionPoint.setEnabled(isProVersion);
checkBoxHeaderInsertionPoint.setSelected(scannerConfig.enableHeaderJWSInsertionPointLocation());
checkBoxHeaderInsertionPoint.addActionListener(e -> {
scannerConfig.setEnableHeaderJWSInsertionPointLocation(checkBoxHeaderInsertionPoint.isSelected());
scannerParameterName.setEnabled(checkBoxHeaderInsertionPoint.isSelected());
});

scannerParameterName.setEnabled(scannerConfig.enableHeaderJWSInsertionPointLocation());
scannerParameterName.setText(scannerConfig.insertionPointLocationParameterName());
scannerParameterName.getDocument().addDocumentListener(
new DocumentAdapter(e -> scannerConfig.setInsertionPointLocationParameterName(scannerParameterName.getText()))
);

proxyLabel.setFont(proxyLabel.getFont().deriveFont(BOLD));
intruderLabel.setFont(intruderLabel.getFont().deriveFont(BOLD));
scannerLabel.setFont(scannerLabel.getFont().deriveFont(BOLD));
userInterface.applyThemeToComponent(mainPanel);

comboBoxHighlightColor.setRenderer(new HighlightComboRenderer());
}

private void updateSigningKeyList() {
List<Key> signingKeys = keysModel.getSigningKeys();
String[] signingKeyIds = signingKeys.stream().map(Key::getID).toArray(String[]::new);
String modelSelectedSigningId = intruderConfig.signingKeyId();

String viewSelectedKeyId = (String) comboBoxIntruderSigningKeyId.getSelectedItem();
comboBoxIntruderSigningKeyId.setModel(new DefaultComboBoxModel<>(signingKeyIds));

if (signingKeys.isEmpty()) {
resignIntruderJWS.setSelected(false);
resignIntruderJWS.setEnabled(false);
comboBoxIntruderSigningKeyId.setEnabled(false);
comboBoxIntruderSigningAlg.setEnabled(false);
intruderConfig.setResign(false);
intruderConfig.setSigningKeyId(null);
} else {
resignIntruderJWS.setEnabled(true);
comboBoxIntruderSigningKeyId.setEnabled(true);
comboBoxIntruderSigningAlg.setEnabled(true);

Optional<Key> selectedKey = signingKeys.stream()
.filter(k -> k.getID().equals(modelSelectedSigningId))
.findFirst();


if (selectedKey.isPresent()) {
Key key = selectedKey.get();

resignIntruderJWS.setSelected(intruderConfig.resign());
comboBoxIntruderSigningKeyId.setSelectedItem(key.getID());

if (!modelSelectedSigningId.equals(viewSelectedKeyId)) {
comboBoxIntruderSigningAlg.setModel(new DefaultComboBoxModel(key.getSigningAlgorithms()));
comboBoxIntruderSigningAlg.setSelectedIndex(0);
}
} else {
resignIntruderJWS.setSelected(false);
comboBoxIntruderSigningKeyId.setSelectedIndex(0);

Key key = signingKeys.get(0);
comboBoxIntruderSigningAlg.setModel(new DefaultComboBoxModel(key.getSigningAlgorithms()));
}
}
}

private void updateSigningAlgorithmList() {
Key key = keysModel.getSigningKeys().stream()
.filter(k -> k.getID().equals(intruderConfig.signingKeyId()))
.findFirst()
.orElseThrow();

JWSAlgorithm[] signingAlgorithms = key.getSigningAlgorithms();
comboBoxIntruderSigningAlg.setModel(new DefaultComboBoxModel(signingAlgorithms));

if (signingAlgorithms.length > 0) {
JWSAlgorithm algorithm = signingAlgorithms[0];
comboBoxIntruderSigningAlg.setSelectedItem(algorithm);
intruderConfig.setSigningAlgorithm(algorithm);
}
}

/**
* Custom list cell renderer to color rows of combo box drop down list.
*/
private static class HighlightComboRenderer implements ListCellRenderer<HighlightColor> {
private final ListCellRenderer renderer = new DefaultListCellRenderer();

@Override
public Component getListCellRendererComponent(JList<? extends HighlightColor> list, HighlightColor value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

Color background = isSelected ? list.getSelectionBackground() : value.color;
label.setBackground(background);

return label;
}
private void createUIComponents() {
proxyConfigView = new ProxyConfigView(userInterface, burpConfig.proxyConfig());
intruderConfigView = new IntruderConfigView(userInterface, new IntruderConfigModel(keysModel, burpConfig.intruderConfig()));
scannerConfigView = new ScannerConfigView(userInterface, burpConfig.scannerConfig(), isProVersion);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package com.blackberry.jwteditor.view.config;

import burp.intruder.FuzzLocation;
import burp.intruder.IntruderConfig;
import com.blackberry.jwteditor.model.keys.Key;
import com.blackberry.jwteditor.model.keys.KeysModel;
import com.blackberry.jwteditor.model.keys.KeysModelListener.SimpleKeysModelListener;
import com.nimbusds.jose.JWSAlgorithm;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;

import static java.util.Arrays.stream;

class IntruderConfigModel {
static final String SIGNING_KEYS_UPDATED = "signingKeysUpdated";
static final String SELECTED_KEY_UPDATED = "selectedKeyUpdated";
static final String SIGNING_ALGORITHMS_UPDATED = "signingAlgorithmsUpdated";
static final String SELECTED_ALGORITHM_UPDATED = "selectedAlgorithmUpdated";
static final String RESIGN_UPDATED = "resignUpdated";

private static final JWSAlgorithm[] NO_ALGORITHMS = new JWSAlgorithm[0];

private final PropertyChangeSupport propertyChangeSupport;
private final KeysModel keysModel;
private final IntruderConfig intruderConfig;
private final List<PropertyChangeListener> listeners;

private String[] signingKeyIds;
private JWSAlgorithm[] selectedKeySigningAlgorithms;

IntruderConfigModel(KeysModel keysModel, IntruderConfig intruderConfig) {
this.keysModel = keysModel;
this.intruderConfig = intruderConfig;
this.signingKeyIds = signingKeyIds();
this.selectedKeySigningAlgorithms = signingAlgorithms();
this.listeners = new ArrayList<>();
this.propertyChangeSupport = new PropertyChangeSupport(this);

keysModel.addKeyModelListener(new SimpleKeysModelListener(this::updateSigningKeyList));
}

String fuzzParameter() {
return intruderConfig.fuzzParameter();
}

void setFuzzParameter(String fuzzParameter) {
intruderConfig.setFuzzParameter(fuzzParameter);
}

FuzzLocation fuzzLocation() {
return intruderConfig.fuzzLocation();
}

void setFuzzLocation(FuzzLocation fuzzLocation) {
intruderConfig.setFuzzLocation(fuzzLocation);
}

FuzzLocation[] fuzzLocations() {
return FuzzLocation.values();
}

boolean hasSigningKeys() {
return !keysModel.getSigningKeys().isEmpty();
}

String[] signingKeyIds() {
return keysModel.getSigningKeys().stream().map(Key::getID).toArray(String[]::new);
}

String signingKeyId() {
return intruderConfig.signingKeyId();
}

public void setSigningKeyId(String signingKeyId) {
String oldSigningKeyId = intruderConfig.signingKeyId();
JWSAlgorithm[] oldAlgorithms = selectedKeySigningAlgorithms;
intruderConfig.setSigningKeyId(signingKeyId);

boolean selectedKeyUnchanged = (oldSigningKeyId == null && signingKeyId==null) || (oldSigningKeyId != null && oldSigningKeyId.equals(signingKeyId));

if (!selectedKeyUnchanged) {
selectedKeySigningAlgorithms = signingAlgorithms();
propertyChangeSupport.firePropertyChange(SIGNING_ALGORITHMS_UPDATED, oldAlgorithms, selectedKeySigningAlgorithms);
}
}

JWSAlgorithm[] signingAlgorithms() {
if (intruderConfig.signingKeyId() == null) {
return NO_ALGORITHMS;
}

return keysModel.getSigningKeys().stream()
.filter(k -> k.getID().equals(intruderConfig.signingKeyId()))
.findFirst()
.orElseThrow()
.getSigningAlgorithms();
}

JWSAlgorithm signingAlgorithm() {
return intruderConfig.signingAlgorithm();
}

void setSigningAlgorithm(JWSAlgorithm signingAlgorithm) {
intruderConfig.setSigningAlgorithm(signingAlgorithm);
}

boolean resign() {
return intruderConfig.resign() && hasSigningKeys();
}

void setResign(boolean resign) {
intruderConfig.setResign(resign);
}

void addPropertyChangeListener(PropertyChangeListener listener) {
listeners.add(listener);
propertyChangeSupport.addPropertyChangeListener(listener);
}

void clearListeners() {
listeners.forEach(propertyChangeSupport::removePropertyChangeListener);
}

private void updateSigningKeyList() {
String[] oldSigningKeyIds = signingKeyIds;
JWSAlgorithm[] oldSigningAlgorithms = selectedKeySigningAlgorithms;
JWSAlgorithm oldSigningAlgorithm = intruderConfig.signingAlgorithm();
signingKeyIds = signingKeyIds();
propertyChangeSupport.firePropertyChange(SIGNING_KEYS_UPDATED, oldSigningKeyIds, signingKeyIds);

String selectedKeyId = intruderConfig.signingKeyId();
boolean modelIsEmpty = signingKeyIds.length == 0;
boolean modelWasEmpty = oldSigningKeyIds.length == 0 && signingKeyIds.length > 0;
boolean selectedKeyDeleted = selectedKeyId != null && (signingKeyIds.length == 0 || stream(signingKeyIds).noneMatch(selectedKeyId::equals));
boolean wasResigning = intruderConfig.resign();

if (modelIsEmpty) {
selectedKeySigningAlgorithms = NO_ALGORITHMS;
propertyChangeSupport.firePropertyChange(SIGNING_ALGORITHMS_UPDATED, oldSigningAlgorithms, NO_ALGORITHMS);

String oldSigningKeyId = intruderConfig.signingKeyId();
intruderConfig.setSigningKeyId(null);
propertyChangeSupport.firePropertyChange(SELECTED_KEY_UPDATED, oldSigningKeyId, null);

intruderConfig.setSigningAlgorithm(null);
propertyChangeSupport.firePropertyChange(SELECTED_ALGORITHM_UPDATED, oldSigningAlgorithm, null);

intruderConfig.setResign(false);
propertyChangeSupport.firePropertyChange(RESIGN_UPDATED, wasResigning, false);
}
else if (modelWasEmpty || selectedKeyDeleted) {
String firstKeyId = signingKeyIds[0];
intruderConfig.setSigningKeyId(firstKeyId);
selectedKeySigningAlgorithms = signingAlgorithms();
JWSAlgorithm firstSigningAlgorithm = selectedKeySigningAlgorithms[0];
intruderConfig.setSigningAlgorithm(firstSigningAlgorithm);
intruderConfig.setResign(false);

propertyChangeSupport.firePropertyChange(SELECTED_KEY_UPDATED, null, firstKeyId);
propertyChangeSupport.firePropertyChange(SIGNING_ALGORITHMS_UPDATED, oldSigningAlgorithms, selectedKeySigningAlgorithms);
propertyChangeSupport.firePropertyChange(SELECTED_ALGORITHM_UPDATED, oldSigningAlgorithm, firstSigningAlgorithm);
propertyChangeSupport.firePropertyChange(RESIGN_UPDATED, wasResigning, false);
}
}
}
Loading

0 comments on commit 1ca2c7e

Please sign in to comment.