Merge pull request #1 from wbrawner/cracker-factory
Implement CrackerFactory
This commit is contained in:
commit
ed4098983a
8 changed files with 63 additions and 63 deletions
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,4 +1,5 @@
|
|||
#Sun Apr 15 14:52:35 CDT 2018
|
||||
# suppress inspection "UnusedProperty" for whole file
|
||||
#Wed Apr 18 08:19:13 CDT 2018
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package com.wbrawner.keecrack.cli;
|
||||
|
||||
import com.wbrawner.keecrack.lib.Code;
|
||||
import com.wbrawner.keecrack.lib.CrackerFactory;
|
||||
import com.wbrawner.keecrack.lib.KeeCrack;
|
||||
import com.wbrawner.keecrack.lib.view.CrackingView;
|
||||
import net.sourceforge.argparse4j.ArgumentParsers;
|
||||
|
@ -71,7 +72,7 @@ public class Main {
|
|||
Namespace res = parser.parseArgs(args);
|
||||
isVerbose = res.getBoolean("verbose");
|
||||
isIncremental = res.getBoolean("incremental");
|
||||
KeeCrack keeCrack = KeeCrack.getInstance();
|
||||
KeeCrack keeCrack = new CrackerFactory().getCracker(true);
|
||||
keeCrack.setCrackingView(new CLICrackingView());
|
||||
|
||||
String databasePath = res.getString("database");
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package com.wbrawner.keecrack.gui;
|
||||
|
||||
import com.wbrawner.keecrack.lib.Code;
|
||||
import com.wbrawner.keecrack.lib.CrackerFactory;
|
||||
import com.wbrawner.keecrack.lib.KeeCrack;
|
||||
import com.wbrawner.keecrack.lib.view.CrackingView;
|
||||
import javafx.application.Platform;
|
||||
|
@ -41,10 +42,11 @@ public class CrackingController implements Initializable, CrackingView {
|
|||
private Label timeElapsed;
|
||||
|
||||
private Stage stage;
|
||||
private KeeCrack keeCrack;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
final KeeCrack keeCrack = KeeCrack.getInstance();
|
||||
keeCrack = new CrackerFactory().getCracker(true);
|
||||
keeCrack.setCrackingView(this);
|
||||
new Thread(keeCrack::attack).start();
|
||||
}
|
||||
|
@ -88,7 +90,6 @@ public class CrackingController implements Initializable, CrackingView {
|
|||
}
|
||||
|
||||
private void onClose() {
|
||||
KeeCrack keeCrack = KeeCrack.getInstance();
|
||||
keeCrack.abort();
|
||||
keeCrack.setCrackingView(null);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package com.wbrawner.keecrack.gui;
|
||||
|
||||
import com.wbrawner.keecrack.lib.Code;
|
||||
import com.wbrawner.keecrack.lib.CrackerFactory;
|
||||
import com.wbrawner.keecrack.lib.KeeCrack;
|
||||
import com.wbrawner.keecrack.lib.view.FormView;
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -48,7 +49,6 @@ public class MainController implements Initializable, FormView {
|
|||
private TextField wordlist;
|
||||
@FXML
|
||||
private Button crackButton;
|
||||
@FXML
|
||||
private ToggleGroup wordlistType;
|
||||
@FXML
|
||||
private RadioButton wordlistFile;
|
||||
|
@ -57,10 +57,10 @@ public class MainController implements Initializable, FormView {
|
|||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
keeCrack = KeeCrack.getInstance();
|
||||
keeCrack = new CrackerFactory().getCracker(true);
|
||||
keeCrack.setFormView(this);
|
||||
database.setOnMouseClicked(event -> {
|
||||
if (KeeCrack.getInstance().isCracking()) {
|
||||
if (keeCrack.isCracking()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ public class MainController implements Initializable, FormView {
|
|||
});
|
||||
|
||||
key.setOnMouseClicked(event -> {
|
||||
if (KeeCrack.getInstance().isCracking()) {
|
||||
if (keeCrack.isCracking()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class MainController implements Initializable, FormView {
|
|||
|
||||
crackButton.setOnMouseClicked(event -> {
|
||||
try {
|
||||
if (KeeCrack.getInstance().isCracking()) {
|
||||
if (keeCrack.isCracking()) {
|
||||
return;
|
||||
}
|
||||
Stage stage = new Stage();
|
||||
|
@ -107,13 +107,16 @@ public class MainController implements Initializable, FormView {
|
|||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
if (wordlistType == null)
|
||||
wordlistType = new ToggleGroup();
|
||||
wordlistFile.setToggleGroup(wordlistType);
|
||||
wordlistPattern.setToggleGroup(wordlistType);
|
||||
wordlistType.selectedToggleProperty().addListener((observableValue, oldToggle, newToggle) ->
|
||||
updateWordListHandler());
|
||||
|
||||
if (keeCrack.getDatabaseFile() != null)
|
||||
onDatabaseFileSet(keeCrack.getDatabaseFile().getName());
|
||||
if (keeCrack.getKeyFile() != null)
|
||||
onKeyFileSet(keeCrack.getKeyFile().getName());
|
||||
if (keeCrack.getWordListName() != null)
|
||||
onWordListSet(keeCrack.getWordListName());
|
||||
}
|
||||
|
@ -127,7 +130,7 @@ public class MainController implements Initializable, FormView {
|
|||
new FileChooser.ExtensionFilter(description, extensions)
|
||||
);
|
||||
Stage stage = new Stage();
|
||||
stage.setOnHidden(e -> KeeCrack.getInstance().setFormView(null));
|
||||
stage.setOnHidden(e -> keeCrack.setFormView(null));
|
||||
return fileChooser.showOpenDialog(stage);
|
||||
}
|
||||
|
||||
|
@ -137,7 +140,7 @@ public class MainController implements Initializable, FormView {
|
|||
wordlist.setEditable(false);
|
||||
wordlist.setCursor(Cursor.HAND);
|
||||
wordlist.setOnMouseClicked(event -> {
|
||||
if (KeeCrack.getInstance().isCracking()) {
|
||||
if (keeCrack.isCracking()) {
|
||||
return;
|
||||
}
|
||||
File wordlistFile = getFile("Text Files", "txt");
|
||||
|
|
|
@ -69,12 +69,8 @@
|
|||
<HBox.margin>
|
||||
<Insets left="20.0"/>
|
||||
</HBox.margin>
|
||||
<toggleGroup>
|
||||
<ToggleGroup fx:id="wordlistType"/>
|
||||
</toggleGroup>
|
||||
</RadioButton>
|
||||
<RadioButton fx:id="wordlistFile" selected="true" text="From File"
|
||||
toggleGroup="wordlistType">
|
||||
<RadioButton fx:id="wordlistFile" selected="true" text="From File">
|
||||
<HBox.margin>
|
||||
<Insets left="20.0"/>
|
||||
</HBox.margin>
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2018 William Brawner
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.wbrawner.keecrack.lib;
|
||||
|
||||
/**
|
||||
* Class responsible for acquiring a {@link KeeCrack} instance
|
||||
*/
|
||||
public class CrackerFactory {
|
||||
private static final Object singletonLock = new Object();
|
||||
private static KeeCrack singleton;
|
||||
|
||||
public KeeCrack getCracker(boolean asSingleton) {
|
||||
if (asSingleton) {
|
||||
synchronized (singletonLock) {
|
||||
if (singleton == null) {
|
||||
singleton = new KeeCrack();
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
}
|
||||
return new KeeCrack();
|
||||
}
|
||||
}
|
|
@ -31,11 +31,11 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
|
||||
/**
|
||||
* The main class responsible for handling the brute forcing of the KeePass database. You do not contruct the
|
||||
* KeeCrack instance directly, but rather call {@link #getInstance()}. To begin, you should set the form view and
|
||||
* cracking view with {@link #setFormView(FormView)} and {@link #setCrackingView(CrackingView)} respectively. These
|
||||
* views will be responsible for displaying information like error messages and status updates. The cracking will
|
||||
* work without these, though it's highly recommended to set them prior to beginning. The database and wordlist must
|
||||
* be set, while the key file is also optional. If either of the required parameters are missing, the
|
||||
* KeeCrack instance directly, but rather call {@link CrackerFactory#getCracker(boolean)}. To begin, you should set the
|
||||
* form view and cracking view with {@link #setFormView(FormView)} and {@link #setCrackingView(CrackingView)}
|
||||
* respectively. These views will be responsible for displaying information like error messages and status updates.
|
||||
* The cracking will work without these, though it's highly recommended to set them prior to beginning. The database
|
||||
* and wordlist must be set, while the key file is also optional. If either of the required parameters are missing, the
|
||||
* {@link #attack()} operation will abort, sending either {@link Code#ERROR_INVALID_DATABASE_FILE} or
|
||||
* {@link Code#ERROR_INVALID_WORD_LIST}, respectively. The word list can either be a pattern, in which case
|
||||
* incremental guessing will take place, or a file, in which case each line of the file will be considered a password
|
||||
|
@ -49,7 +49,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
* first parameter will be null.
|
||||
*/
|
||||
public class KeeCrack {
|
||||
private static final AtomicReference<KeeCrack> singleton = new AtomicReference<>(null);
|
||||
private final Object keyFileLock = new Object();
|
||||
private final AtomicBoolean isCracking = new AtomicBoolean(false);
|
||||
/**
|
||||
|
@ -65,27 +64,10 @@ public class KeeCrack {
|
|||
private WordList wordList;
|
||||
private int guessCount = 0;
|
||||
|
||||
private KeeCrack() {
|
||||
}
|
||||
|
||||
public static KeeCrack getInstance() {
|
||||
if (singleton.get() == null) {
|
||||
singleton.set(new KeeCrack());
|
||||
}
|
||||
|
||||
return singleton.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to reset the state of the KeeCrack instance. Note that you will need to set the views again after
|
||||
* calling this
|
||||
* To get an instance of the class, use the {@link CrackerFactory}
|
||||
*/
|
||||
public void reset() {
|
||||
setDatabaseFile(null);
|
||||
setKeyFile(null);
|
||||
setWordListFile(null);
|
||||
setCrackingView(null);
|
||||
setFormView(null);
|
||||
KeeCrack() {
|
||||
}
|
||||
|
||||
public void abort() {
|
||||
|
|
|
@ -21,13 +21,9 @@ import org.junit.After;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
|
||||
import static junit.framework.TestCase.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
@ -41,30 +37,14 @@ public class KeeCrackTest {
|
|||
public void setUp() {
|
||||
mockCrackingView = mock(CrackingView.class);
|
||||
mockFormView = mock(FormView.class);
|
||||
keeCrack = KeeCrack.getInstance();
|
||||
keeCrack = new CrackerFactory().getCracker(false);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
keeCrack.reset();
|
||||
Utils.rmdir(Utils.getTmpDir());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetTest() {
|
||||
keeCrack.setDatabaseFile(new File("Database"));
|
||||
keeCrack.setKeyFile(new File("Keyfile"));
|
||||
keeCrack.setWordListPattern("Some pattern");
|
||||
assertNotNull(keeCrack.getDatabaseFile());
|
||||
assertNotNull(keeCrack.getKeyFile());
|
||||
assertNotNull(keeCrack.getWordList());
|
||||
keeCrack.reset();
|
||||
assertNull(keeCrack.getDatabaseFile());
|
||||
assertNull(keeCrack.getKeyFile());
|
||||
assertNull(keeCrack.getWordList());
|
||||
assertFalse(keeCrack.isCracking());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void abortTest() throws IOException {
|
||||
keeCrack.setDatabaseFile(Utils.getDatabase("123456.kdbx"));
|
||||
|
|
Loading…
Reference in a new issue