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