View Javadoc
1   /*******************************************************************************
2    * Copyhacked (H) 2012-2025.
3    * This program and the accompanying materials
4    * are made available under no term at all, use it like
5    * you want, but share and discuss it
6    * every time possible with every body.
7    *
8    * Contributors:
9    *      ron190 at ymail dot com - initial implementation
10   ******************************************************************************/
11  package com.jsql.view.swing.manager;
12  
13  import com.jsql.util.I18nUtil;
14  import com.jsql.util.LogLevelUtil;
15  import com.jsql.util.bruter.ActionCoder;
16  import com.jsql.view.swing.manager.util.ActionBruteForce;
17  import com.jsql.view.swing.manager.util.JButtonStateful;
18  import com.jsql.view.swing.manager.util.ModelBrute;
19  import com.jsql.view.swing.manager.util.ModelSpinner;
20  import com.jsql.view.swing.panel.preferences.listener.SpinnerMouseWheelListener;
21  import com.jsql.view.swing.text.*;
22  import com.jsql.view.swing.util.I18nViewUtil;
23  import org.apache.commons.lang3.StringUtils;
24  import org.apache.logging.log4j.LogManager;
25  import org.apache.logging.log4j.Logger;
26  
27  import javax.swing.*;
28  import java.awt.*;
29  import java.util.Arrays;
30  import java.util.concurrent.atomic.AtomicReference;
31  
32  /**
33   * Manager to brute force a hash of various types.
34   */
35  public class ManagerBruteForce extends JPanel {
36  
37      private static final Logger LOGGER = LogManager.getRootLogger();
38  
39      public static final String BRUTEFORCE_RUN_BUTTON_TOOLTIP = "BRUTEFORCE_RUN_BUTTON_TOOLTIP";
40      public static final String BRUTEFORCE_HASH_TOOLTIP = "BRUTEFORCE_HASH_TOOLTIP";
41      public static final String BRUTEFORCE_EXCLUDE_TOOLTIP = "BRUTEFORCE_EXCLUDE_TOOLTIP";
42  
43      private JButtonStateful run;
44      private JTextField hash;
45      private JComboBox<String> hashTypes;
46      private final AtomicReference<JCheckBox> lowerCaseCharacters = new AtomicReference<>();
47      private final AtomicReference<JCheckBox> upperCaseCharacters = new AtomicReference<>();
48      private final AtomicReference<JCheckBox> numericCharacters = new AtomicReference<>();
49      private final AtomicReference<JCheckBox> specialCharacters = new AtomicReference<>();
50      private JTextField exclude;
51      private final AtomicReference<JSpinner> minimumLength = new AtomicReference<>();
52      private final AtomicReference<JSpinner> maximumLength = new AtomicReference<>();
53      private final JTextPane result;
54      
55      /**
56       * Animated GIF displayed during attack.
57       */
58      private JProgressBar progressBar;
59      private final Component horizontalGlue = Box.createHorizontalGlue();
60  
61      /**
62       * Create a panel to run brute force attack.
63       */
64      public ManagerBruteForce() {
65          super(new BorderLayout());
66  
67          JPanel panelOptions = this.initOptionsPanel();
68          this.add(panelOptions, BorderLayout.NORTH);
69  
70          var placeholder = new JTextPanePlaceholder(I18nUtil.valueByKey("BRUTEFORCE_RESULT"));
71          this.result = new JPopupTextPane(placeholder).getProxy();
72          I18nViewUtil.addComponentForKey("BRUTEFORCE_RESULT", placeholder);
73          this.result.setName("managerBruterResult");
74          this.result.setEditable(false);
75          this.add(new JScrollPane(this.result), BorderLayout.CENTER);
76  
77          JPanel panelButton = this.initPanelButton();
78          this.add(panelButton, BorderLayout.SOUTH);
79      }
80  
81      private JPanel initPanelButton() {
82          var lastLine = new JPanel();
83          lastLine.setLayout(new BoxLayout(lastLine, BoxLayout.X_AXIS));
84  
85          var tooltip = new AtomicReference<>(new JToolTipI18n(I18nUtil.valueByKey(ManagerBruteForce.BRUTEFORCE_RUN_BUTTON_TOOLTIP)));
86          this.run = new JButtonStateful("BRUTEFORCE_RUN_BUTTON_LABEL") {
87              @Override
88              public JToolTip createToolTip() {
89                  return tooltip.get();
90              }
91          };
92          I18nViewUtil.addComponentForKey("BRUTEFORCE_RUN_BUTTON_LABEL", this.run);
93          I18nViewUtil.addComponentForKey(ManagerBruteForce.BRUTEFORCE_RUN_BUTTON_TOOLTIP, tooltip.get());
94          this.run.setToolTipText(I18nUtil.valueByKey(ManagerBruteForce.BRUTEFORCE_RUN_BUTTON_TOOLTIP));
95  
96          this.run.setName("managerBruterRun");
97          this.run.addActionListener(new ActionBruteForce(this));
98  
99          this.progressBar = new JProgressBar();
100         this.progressBar.setIndeterminate(true);
101         this.progressBar.setVisible(false);
102         this.progressBar.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
103 
104         lastLine.add(this.horizontalGlue);
105         lastLine.add(this.progressBar);
106         lastLine.add(this.run);
107         return lastLine;
108     }
109 
110     public void showLoader(boolean isVisible) {
111         this.progressBar.setVisible(isVisible);
112         this.horizontalGlue.setVisible(!isVisible);
113     }
114 
115     private JPanel initOptionsPanel() {
116         var options = new JPanel(new BorderLayout());
117         JPanel firstLine = this.initFirstLine();
118         final JPanel secondLine = this.initSecondLine();
119         JPanel thirdLine = this.initThirdLine();
120         
121         final var secondAndThirdLine = new JPanel(new BorderLayout());
122         secondAndThirdLine.add(secondLine, BorderLayout.NORTH);
123         secondAndThirdLine.add(thirdLine, BorderLayout.SOUTH);
124 
125         options.add(firstLine, BorderLayout.NORTH);
126         options.add(secondAndThirdLine, BorderLayout.SOUTH);
127         return options;
128     }
129 
130     private JPanel initFirstLine() {
131         var tooltip = new AtomicReference<>(new JToolTipI18n(I18nUtil.valueByKey(ManagerBruteForce.BRUTEFORCE_HASH_TOOLTIP)));
132         var placeholder = new JTextFieldPlaceholder(I18nUtil.valueByKey("BRUTEFORCE_HASH_LABEL")) {
133             @Override
134             public JToolTip createToolTip() {
135                 return tooltip.get();
136             }
137         };
138         this.hash = new JPopupTextField(placeholder).getProxy();
139         I18nViewUtil.addComponentForKey(ManagerBruteForce.BRUTEFORCE_HASH_TOOLTIP, tooltip.get());
140         I18nViewUtil.addComponentForKey("BRUTEFORCE_HASH_LABEL", this.hash);
141         this.hash.setName("managerBruterHash");
142         this.hash.setToolTipText(I18nUtil.valueByKey(ManagerBruteForce.BRUTEFORCE_HASH_TOOLTIP));
143 
144         var firstLine = new JPanel(new BorderLayout());
145         firstLine.add(this.hash, BorderLayout.CENTER);
146         return firstLine;
147     }
148 
149     private JPanel initSecondLine() {
150         final var secondLine = new JPanel();
151         secondLine.setLayout(new BoxLayout(secondLine, BoxLayout.X_AXIS));
152 
153         this.hashTypes = new JComboBox<>(ActionCoder.getHashes().toArray(String[]::new));
154         this.hashTypes.setSelectedIndex(6);
155         this.hashTypes.setToolTipText(I18nUtil.valueByKey("BRUTEFORCE_HASH_TYPE_TOOLTIP"));
156         I18nViewUtil.addComponentForKey("BRUTEFORCE_HASH_TYPE_TOOLTIP", this.hashTypes);
157         secondLine.add(this.hashTypes);
158 
159         Arrays.asList(
160             new ModelBrute(this.lowerCaseCharacters, "a-z", "BRUTEFORCE_LCASE_TOOLTIP"),
161             new ModelBrute(this.upperCaseCharacters, "A-Z", "BRUTEFORCE_UCASE_TOOLTIP"),
162             new ModelBrute(this.numericCharacters, "0-9", "BRUTEFORCE_NUM_TOOLTIP"),
163             new ModelBrute(this.specialCharacters, "Special", "BRUTEFORCE_SPEC_TOOLTIP")
164         ).forEach(modelBrute -> {
165             var tooltip = new AtomicReference<>(new JToolTipI18n(I18nUtil.valueByKey(modelBrute.i18nTooltip)));
166             modelBrute.checkbox.set(new JCheckBox(modelBrute.text, true) {
167                 @Override
168                 public JToolTip createToolTip() {
169                     return tooltip.get();
170                 }
171             });
172             modelBrute.checkbox.get().setToolTipText(I18nUtil.valueByKey(modelBrute.i18nTooltip));
173             I18nViewUtil.addComponentForKey(modelBrute.i18nTooltip, tooltip.get());
174             secondLine.add(Box.createHorizontalStrut(5));
175             secondLine.add(modelBrute.checkbox.get());
176         });
177 
178         return secondLine;
179     }
180 
181     private JPanel initThirdLine() {
182         var thirdLine = new JPanel();
183         thirdLine.setLayout(new BoxLayout(thirdLine, BoxLayout.X_AXIS));
184 
185         final var tooltip = new AtomicReference<>(new JToolTipI18n(I18nUtil.valueByKey(ManagerBruteForce.BRUTEFORCE_EXCLUDE_TOOLTIP)));
186         var placeholderTooltip = new JTextFieldPlaceholder(I18nUtil.valueByKey("BRUTEFORCE_EXCLUDE_LABEL")) {
187             @Override
188             public JToolTip createToolTip() {
189                 return tooltip.get();
190             }
191         };
192         this.exclude = new JPopupTextField(placeholderTooltip).getProxy();
193         this.exclude.setToolTipText(I18nUtil.valueByKey(ManagerBruteForce.BRUTEFORCE_EXCLUDE_TOOLTIP));
194         I18nViewUtil.addComponentForKey("BRUTEFORCE_EXCLUDE_LABEL", this.exclude);
195         I18nViewUtil.addComponentForKey(ManagerBruteForce.BRUTEFORCE_EXCLUDE_TOOLTIP, tooltip.get());
196         thirdLine.add(this.exclude);
197 
198         Arrays.asList(
199             new ModelSpinner(1, this.minimumLength, "BRUTEFORCE_MIN_TOOLTIP"),
200             new ModelSpinner(5, this.maximumLength, "BRUTEFORCE_MAX_TOOLTIP")
201         ).forEach(model -> {
202             final var tooltipMax = new AtomicReference<>(new JToolTipI18n(I18nUtil.valueByKey(model.i18n)));
203             try {  // Fixes #96099: NullPointerException on new JSpinner
204                 model.spinner.set(new JSpinner() {
205                     @Override
206                     public JToolTip createToolTip() {
207                         return tooltipMax.get();
208                     }
209                 });
210             } catch (NullPointerException e) {
211                 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "Spinner creation failed, restart app or check your jre", e);
212                 return;
213             }
214             model.spinner.get().setModel(new SpinnerNumberModel(model.value, 1, 10000, 1));
215             model.spinner.get().addMouseWheelListener(new SpinnerMouseWheelListener());
216             model.spinner.get().setToolTipText(I18nUtil.valueByKey(model.i18n));
217             I18nViewUtil.addComponentForKey(model.i18n, tooltipMax.get());
218             model.spinner.get().setPreferredSize(new Dimension(
219                 (int) (model.spinner.get().getPreferredSize().width/1.8),
220                 model.spinner.get().getPreferredSize().height
221             ));
222         });
223 
224         var labelMin = new JLabel(StringUtils.SPACE + I18nUtil.valueByKey("BRUTEFORCE_MIN_LABEL"), SwingConstants.RIGHT);
225         labelMin.setMaximumSize(new Dimension(labelMin.getPreferredSize().width, labelMin.getPreferredSize().height));
226         thirdLine.add(Box.createHorizontalStrut(5));
227         thirdLine.add(labelMin);
228         I18nViewUtil.addComponentForKey("BRUTEFORCE_MIN_LABEL", labelMin);
229         thirdLine.add(this.minimumLength.get());
230 
231         var labelMax = new JLabel(StringUtils.SPACE + I18nUtil.valueByKey("BRUTEFORCE_MAX_LABEL"), SwingConstants.RIGHT);
232         labelMax.setMaximumSize(new Dimension(labelMax.getPreferredSize().width, labelMax.getPreferredSize().height));
233         thirdLine.add(Box.createHorizontalStrut(5));
234         thirdLine.add(labelMax);
235         I18nViewUtil.addComponentForKey("BRUTEFORCE_MAX_LABEL", labelMax);
236         thirdLine.add(this.maximumLength.get());
237         return thirdLine;
238     }
239 
240     
241     // Getter and setter
242 
243     public JButtonStateful getRun() {
244         return this.run;
245     }
246 
247     public JTextField getHash() {
248         return this.hash;
249     }
250 
251     public JComboBox<String> getHashTypes() {
252         return this.hashTypes;
253     }
254 
255     public JCheckBox getLowerCaseCharacters() {
256         return this.lowerCaseCharacters.get();
257     }
258 
259     public JCheckBox getUpperCaseCharacters() {
260         return this.upperCaseCharacters.get();
261     }
262 
263     public JCheckBox getNumericCharacters() {
264         return this.numericCharacters.get();
265     }
266 
267     public JCheckBox getSpecialCharacters() {
268         return this.specialCharacters.get();
269     }
270 
271     public JTextField getExclude() {
272         return this.exclude;
273     }
274 
275     public JSpinner getMinimumLength() {
276         return this.minimumLength.get();
277     }
278 
279     public JSpinner getMaximumLength() {
280         return this.maximumLength.get();
281     }
282 
283     public JTextPane getResult() {
284         return this.result;
285     }
286 }