Initial commit...

This commit is contained in:
2021-02-18 17:45:52 -06:00
parent dc3906fa9b
commit 1180e3171f
2159 changed files with 45470 additions and 2 deletions

View File

@@ -0,0 +1 @@
java -jar DarkCrypt.jar

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#!/bin/bash
function main() {
java -jar DarkCrypt.jar
}
main;

Binary file not shown.

View File

@@ -0,0 +1,13 @@
#!/bin/bash
function main() {
jar cvfm DarkCrypt.jar manifest.txt com/itdominator/darkcrypt/DarkCrypt.class \
com/itdominator/darkcrypt/*.class \
com/itdominator/darkcrypt/resources \
com/itdominator/darkcrypt/handlers \
com/itdominator/darkcrypt/utils/*.class
chmod +x DarkCrypt.jar
mv DarkCrypt.jar bin/
}
main;

View File

@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.String?>
<?import javafx.collections.FXCollections?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToggleButton?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?scenebuilder-background-color 0x444444ff?>
<AnchorPane minHeight="700.0" minWidth="800.0" onKeyReleased="#ctrlLockScrn" onMouseDragged="#updatePosition" onMousePressed="#setOffset" prefHeight="700.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<AnchorPane fx:id="basePane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<TabPane layoutX="382.0" layoutY="45.0" prefHeight="600.0" prefWidth="420.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab styleClass="tabHeader" text="Manager">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="446.0">
<children>
<TextField fx:id="userField" layoutX="110.0" layoutY="193.0" prefHeight="26.0" prefWidth="380.0" promptText="Username:" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="150.0">
<tooltip>
<Tooltip text="Username:" />
</tooltip>
</TextField>
<TextField fx:id="titleField" layoutX="-22.0" layoutY="6.0" prefHeight="26.0" prefWidth="380.0" promptText="Title:" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="30.0">
<tooltip>
<Tooltip text="Title:" />
</tooltip>
</TextField>
<TextArea fx:id="descriptionField" layoutX="82.0" layoutY="86.0" prefHeight="60.0" prefWidth="380.0" promptText="Description..." AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="75.0">
<tooltip>
<Tooltip text="Description:" />
</tooltip>
</TextArea>
<TextField fx:id="tagsField" layoutX="107.0" layoutY="320.0" prefHeight="26.0" prefWidth="380.0" promptText="Split Multiple Tags With Commas" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="345.0">
<tooltip>
<Tooltip text="Tags" />
</tooltip></TextField>
<PasswordField fx:id="passwdField" layoutX="107.0" layoutY="205.0" prefHeight="26.0" prefWidth="380.0" promptText="Password:" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="195.0">
<tooltip>
<Tooltip text="Password:" />
</tooltip>
</PasswordField>
<TextField fx:id="unhiddenPassword" layoutX="107.0" layoutY="245.0" prefHeight="26.0" prefWidth="330.0" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="245.0">
<tooltip>
<Tooltip text="Unhidden Password" />
</tooltip></TextField>
<Button fx:id="createBttn" layoutX="240.0" layoutY="359.0" mnemonicParsing="false" onAction="#createEntry" text="Save" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="400.0" />
<Button fx:id="deleteBttn" layoutX="9.0" layoutY="400.0" mnemonicParsing="false" onAction="#deleteEntry" AnchorPane.rightAnchor="380.0" AnchorPane.topAnchor="400.0">
<tooltip>
<Tooltip text="Delete Password Entry" />
</tooltip></Button>
<Button fx:id="clearBttn" layoutX="107.0" layoutY="359.0" mnemonicParsing="false" onAction="#clearFields" text="Clear" AnchorPane.rightAnchor="200.0" AnchorPane.topAnchor="400.0" />
<Button fx:id="updateBttn" layoutX="266.0" layoutY="359.0" mnemonicParsing="false" onAction="#updateEntry" text="Update" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="400.0" />
<ToggleButton fx:id="toggleShowHideBttn" layoutX="55.0" layoutY="285.0" mnemonicParsing="false" onAction="#togglePasswardView" prefHeight="26.0" prefWidth="26.0" AnchorPane.rightAnchor="375.0" AnchorPane.topAnchor="245.0">
<tooltip>
<Tooltip text="Show / Hide Password" />
</tooltip>
</ToggleButton>
<Button fx:id="lockBttn" layoutX="223.0" layoutY="497.0" mnemonicParsing="false" onAction="#lockScreen" AnchorPane.bottomAnchor="45.0" AnchorPane.rightAnchor="170.0">
<tooltip>
<Tooltip text="Lock Manager" />
</tooltip>
</Button>
<Hyperlink fx:id="hyperLink" layoutX="231.0" layoutY="381.0" onAction="#openLink" prefHeight="26.0" prefWidth="330.0" textFill="#00e8ff" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="295.0" />
<TextField fx:id="urlField" layoutX="107.0" layoutY="279.0" prefHeight="26.0" prefWidth="330.0" promptText="URL:" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="295.0">
<tooltip>
<Tooltip text="Url:" />
</tooltip>
</TextField>
<Button fx:id="toggleEditLinkBttn" layoutX="20.0" layoutY="295.0" mnemonicParsing="false" onAction="#editHyperLinkToggle" prefHeight="26.0" prefWidth="26.0" AnchorPane.rightAnchor="375.0" AnchorPane.topAnchor="295.0">
<tooltip>
<Tooltip text="Show / Hide Url:" />
</tooltip></Button>
</children>
</AnchorPane>
</content>
</Tab>
<Tab styleClass="tabHeader" text="Password Generator">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TextField fx:id="genPasswdFld" layoutX="25.0" layoutY="67.0" prefHeight="26.0" prefWidth="370.0" promptText="Generated Password..." AnchorPane.rightAnchor="35.0" AnchorPane.topAnchor="67.0">
<tooltip>
<Tooltip text="Generated Password..." />
</tooltip>
</TextField>
<TextField fx:id="genLength" layoutX="64.0" layoutY="25.0" prefHeight="26.0" prefWidth="45.0" promptText="Generator Password Length" text="16" AnchorPane.rightAnchor="311.0" AnchorPane.topAnchor="25.0">
<tooltip>
<Tooltip text="Generated Password Length" />
</tooltip></TextField>
<ComboBox fx:id="genType" layoutX="222.0" layoutY="25.0" prefHeight="26.0" prefWidth="200.0" AnchorPane.rightAnchor="35.0" AnchorPane.topAnchor="25.0">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="Alphabets" />
<String fx:value="Numbers" />
<String fx:value="Alphabets | Numbers" />
<String fx:value="Alphabets | Numbers | Symbols" />
</FXCollections>
</items>
<tooltip>
<Tooltip text="Generated Password Type" />
</tooltip>
</ComboBox>
<Label layoutX="14.0" layoutY="30.0" text="Length:" AnchorPane.rightAnchor="356.0" AnchorPane.topAnchor="30.0" />
<Button fx:id="generatePasswdBttn" layoutX="18.0" layoutY="106.0" mnemonicParsing="false" onAction="#generatePassword" prefHeight="26.0" prefWidth="370.0" text="Generate" AnchorPane.rightAnchor="35.0" AnchorPane.topAnchor="106.0">
<tooltip>
<Tooltip text="Generate Password" />
</tooltip></Button>
<Label layoutX="148.0" layoutY="30.0" text="Type:" AnchorPane.rightAnchor="235.0" AnchorPane.topAnchor="30.0" />
</children>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
<TextField fx:id="searchField" layoutX="85.0" layoutY="45.0" onKeyReleased="#searchForEntry" onMouseClicked="#cleanSearchField" prefWidth="171.0" promptText="Search...">
<tooltip>
<Tooltip text="Search..." />
</tooltip>
</TextField>
<Button fx:id="refreshBttn" layoutX="352.0" layoutY="623.0" mnemonicParsing="false" onAction="#refreshPassTree">
<tooltip>
<Tooltip text="Refresh Tree View..." />
</tooltip>
</Button>
<TreeView fx:id="groupsTree" layoutX="71.0" layoutY="85.0" onMouseClicked="#searchOrExpand" prefHeight="585.0" prefWidth="200.0" />
<HBox prefHeight="45.0" prefWidth="800.0">
<children>
<Label id="dragBar" fx:id="headerLabel" alignment="CENTER" contentDisplay="CENTER" minHeight="42.0" onMouseDragged="#updatePosition" onMousePressed="#setOffset" prefHeight="42.0" prefWidth="755.0" text="[------------------------- DarkCrypt -------------------------]" textAlignment="RIGHT" textFill="#00e8ff" />
<Button id="closeButton" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" onAction="#closeProgram" prefHeight="42.0" prefWidth="45.0" text="X" textFill="#00e8ff" />
</children>
</HBox>
</children>
</AnchorPane>
<AnchorPane fx:id="passwdDialog" layoutX="10.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseDragged="#updatePosition" onMousePressed="#setOffset" prefHeight="300.0" prefWidth="500.0" visible="false" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="150.0">
<children>
<ImageView fx:id="dialogImgView" fitHeight="150.0" fitWidth="200.0" layoutX="14.0" layoutY="75.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="75.0" AnchorPane.leftAnchor="15.0" AnchorPane.topAnchor="75.0" />
<PasswordField fx:id="passwdDialogField" layoutX="283.0" layoutY="137.0" onKeyReleased="#checkPass1" AnchorPane.rightAnchor="146.0" AnchorPane.topAnchor="137.0" />
<Label fx:id="messageLabel" alignment="CENTER" contentDisplay="CENTER" layoutX="283.0" layoutY="75.0" prefHeight="16.0" prefWidth="171.0" text="Enter Your Password" textAlignment="JUSTIFY" />
<Button layoutX="283.0" layoutY="199.0" mnemonicParsing="false" onAction="#checkPass2" prefHeight="26.0" prefWidth="72.0" text="OK" AnchorPane.rightAnchor="245.0" />
<Button layoutX="391.0" layoutY="199.0" mnemonicParsing="false" onAction="#closeProgramDialog" prefHeight="26.0" prefWidth="72.0" text="Close" AnchorPane.rightAnchor="146.0" />
</children>
</AnchorPane>
</children>
</AnchorPane>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,41 @@
.root {
//-fx-background: rgba(68, 68, 68, 0.8); // == #444444;
-fx-background: rgba(0, 0, 0, 0.8);
-fx-border-style: solid;
-fx-border-color: rgba(0, 232, 255, 1);
}
#dragBar {
-fx-border-color: rgba(0, 232, 255, 1);
-fx-cursor: MOVE;
}
#closeButton {
-fx-background-color: rgba(0, 0, 0, 0);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#closeButton:hover {
-fx-background-color: rgba(255, 8, 0, 1);
-fx-cursor: HAND;
}
#closeButton,
.toggle-button,
.button {
-fx-cursor: HAND;
}
.hyperlink {
-fx-text-fill: rgba(0, 232, 255, 1);
}
.hyperlink:hover {
-fx-text-fill: rgba(255, 255, 255, 1);
-fx-underline: true;
}
.tabHeader {
-fx-background-color: rgba(0, 0, 0, 0.74);
-fx-text-base-color: rgba(255, 255, 255, 1);;
}

View File

@@ -0,0 +1,3 @@
Class-Path: resources/lib/sqlite-jdbc-3.27.2.1.jar
SplashScreen-Image: com/itdominator/darkcrypt/resources/DarkCryptSplash.jpg
Main-Class: com.itdominator.darkcrypt.DarkCrypt

View File

@@ -0,0 +1,373 @@
package com.itdominator.darkcrypt;
import com.itdominator.darkcrypt.handlers.DBConnect;
import com.itdominator.darkcrypt.utils.PasswordGenerator;
import javafx.fxml.FXML;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TreeView;
import javafx.scene.control.TreeItem;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Hyperlink;
import javafx.scene.paint.Paint;
import javafx.event.ActionEvent;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.MouseButton;
import java.io.IOException;
import java.lang.ProcessBuilder;
import java.util.List;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class Controller {
// Classes
private final DBConnect dbConn = DBConnect.getInstance();
// FXML Stuff
@FXML private AnchorPane basePane;
@FXML private TreeView<String> groupsTree;
@FXML private ComboBox<String> genType;
@FXML private TextArea descriptionField;
@FXML private TextField searchField, titleField, userField, passwdField,
unhiddenPassword, urlField, tagsField, genPasswdFld,
genLength;
@FXML private ToggleButton toggleShowHideBttn;
@FXML private Button createBttn, updateBttn, deleteBttn, clearBttn, lockBttn,
toggleEditLinkBttn, generatePasswdBttn, refreshBttn;
@FXML private Label headerLabel;
@FXML private Hyperlink hyperLink;
// Lock FXML Parts
@FXML private AnchorPane passwdDialog;
@FXML private ImageView dialogImgView;
@FXML private PasswordField passwdDialogField;
@FXML private Label messageLabel;
// General stuff
private static final String partialPath = "/com/itdominator/darkcrypt/resources/imgs/",
headerLabelTxt = "[------------------------- DarkCrypt -------------------------]";
private static final ImageView lockImg = new ImageView(new Image(partialPath + "lock.png")),
trashImg = new ImageView(new Image(partialPath + "delete.png")),
eyeOpenImg = new ImageView(new Image(partialPath + "eyeOpen.png")),
eyeClosedImg = new ImageView(new Image(partialPath + "eyeClosed.png")),
refreshImg = new ImageView(new Image(partialPath + "refresh.png")),
editLnkImg = new ImageView(new Image(partialPath + "edit.png"));
private static final Image keysImg = new Image(partialPath + "keys.png");
private static Paint defaultColor = Paint.valueOf("#00e8ff"),
neutral = Paint.valueOf("#ffffff"),
success = Paint.valueOf("#88cc27"),
warning = Paint.valueOf("#ffa800"),
error = Paint.valueOf("#ff0000");
private static String currentEntryID = "-1";
private static double xOffset = 0,
yOffset = 0;
private static boolean passwdPresent = true;
private Stage mainStage;
private Scene mainScene;
private TreeItem<String> trunk = new TreeItem<String> (":: Tags ::"),
branch = new TreeItem<String> (),
leaf = new TreeItem<String> ();
@FXML void initialize() {
genType.getSelectionModel().selectLast();
refreshImg.setFitWidth(32);
refreshImg.setFitHeight(32);
lockImg.setFitWidth(32);
lockImg.setFitHeight(32);
refreshBttn.setGraphic(refreshImg);
lockBttn.setGraphic(lockImg);
deleteBttn.setGraphic(trashImg);
toggleShowHideBttn.setGraphic(eyeOpenImg);
toggleEditLinkBttn.setGraphic(editLnkImg);
dialogImgView.setImage(keysImg);
enableSave();
trunk.setExpanded(true);
groupsTree.setRoot(trunk);
resetTreeGroup();
passwdPresent = dbConn.checkPassword("", true, false);
if (!passwdPresent) {
// setup new password and change text
messageLabel.setTextFill(warning);
messageLabel.setText("Enter a new password...");
}
lockScrn();
}
@FXML void searchForEntry(KeyEvent event) {
if (!searchField.getText().isEmpty()) {
clearTree();
List<String> data = dbConn.searchForEntry(searchField.getText());
for (int i=0; i<data.size(); i++) {
addBranch(data.get(i));
}
} else { // Reset view
clearTree();
}
}
@FXML void searchOrExpand(MouseEvent event) {
if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) {
TreeItem<String> selectedItem = (TreeItem<String>) groupsTree.getSelectionModel().getSelectedItem();
if (selectedItem.getChildren().size() == 0) {
String branch = "" + selectedItem.getParent().getValue();
String leaf = "" + selectedItem.getValue();
retrieveEntry(branch, leaf);
} else {
updateTagsField(selectedItem.getValue());
}
}
}
// Pull entry info from DB
private void retrieveEntry(String branch, String leaf) {
String[] data = dbConn.retrieveEntry(branch, leaf);
titleField.setText(data[0]); descriptionField.setText(data[1]);
userField.setText(data[2]); passwdField.setText(data[3]);
unhiddenPassword.setText(""); urlField.setText(data[4]);
hyperLink.setText(data[4]); tagsField.setText(data[5]);
currentEntryID = data[6];
urlField.setVisible(false);
toggleShowHideBttn.setGraphic(eyeOpenImg);
disableSave();
}
@FXML void createEntry(ActionEvent event) throws Exception {
if (titleField.getText().isEmpty()) {
headerLabel.setTextFill(error);
headerLabel.setText("You need to give a Title at the least...");
return;
}
String[] data = {titleField.getText(), descriptionField.getText(),
userField.getText(), passwdField.getText(),
urlField.getText(), tagsField.getText()};
dbConn.createEntry(data);
hyperLink.setText(data[4]);
urlField.setVisible(false);
headerLabel.setTextFill(success);
headerLabel.setText("Saved entry...");
// disableSave();
clearAllFields(); // NOTE: Need to find a way to get id instead of forcing a reload on my part
resetTreeGroup();
}
@FXML void updateEntry(ActionEvent event) throws Exception {
if (titleField.getText().isEmpty()) {
headerLabel.setTextFill(error);
headerLabel.setText("You need to give a Title at the least...");
return;
}
String[] data = {titleField.getText(), descriptionField.getText(),
userField.getText(), passwdField.getText(),
urlField.getText(), tagsField.getText()};
dbConn.updateEntry(data);
hyperLink.setText(data[4]);
urlField.setVisible(false);
headerLabel.setTextFill(success);
headerLabel.setText("Updated entry...");
resetTreeGroup();
}
@FXML void deleteEntry(ActionEvent event) {
enableSave();
String[] data = {currentEntryID};
dbConn.deleteEntry(data);
headerLabel.setTextFill(success);
headerLabel.setText("Deleted entry...");
}
@FXML void refreshPassTree(ActionEvent event) {
resetTreeGroup();
}
@FXML void generatePassword(ActionEvent event) {
int length;
try {
length = Integer.parseInt(genLength.getText());
} catch (Exception ex) {
genLength.selectAll();
genLength.requestFocus();
return;
}
String passwd = new PasswordGenerator(length, genType.getSelectionModel().
getSelectedIndex() + 1).generatePassword();
genPasswdFld.setText(passwd);
}
@FXML void openLink(ActionEvent event) throws IOException {
new ProcessBuilder("x-www-browser", hyperLink.getText()).start();
}
private void resetTreeGroup() {
clearTree();
for(Object branch : dbConn.getBranches()) {
String tag = (String) branch;
addBranch(tag);
List<String> leaves = dbConn.getLeaves(tag);
for (int i=0; i<leaves.size(); i++) {
addLeaf(leaves.get(i));
}
}
}
// General interface manipulations
/* Tree actions */
public void addBranch(String in) {
branch = new TreeItem<String> (in);
trunk.getChildren().add(branch);
}
public void addLeaf(String in) {
leaf = new TreeItem<String> (in);
branch.getChildren().add(leaf);
}
public void clearTree() {
trunk.getChildren().clear();
}
@FXML void togglePasswardView(ActionEvent event) {
if (unhiddenPassword.getText().isEmpty()) {
toggleShowHideBttn.setGraphic(eyeClosedImg);
unhiddenPassword.setText(passwdField.getText());
} else {
toggleShowHideBttn.setGraphic(eyeOpenImg);
unhiddenPassword.setText("");
}
}
private void updateTagsField(String tag) {
if (tagsField.getText() != null && !tagsField.getText().trim().isEmpty()) {
tagsField.setText(tagsField.getText() + "," + tag);
} else {
tagsField.setText(tag);
}
}
@FXML void editHyperLinkToggle(ActionEvent event) {
if (urlField.isVisible())
urlField.setVisible(false);
else
urlField.setVisible(true);
}
@FXML void cleanSearchField(MouseEvent event) {
searchField.setText("");
resetTreeGroup();
}
@FXML void clearFields(ActionEvent event) {
clearAllFields();
}
private void clearAllFields() {
enableSave();
urlField.setVisible(true);
toggleShowHideBttn.setGraphic(eyeOpenImg);
titleField.setText(""); descriptionField.setText(""); userField.setText("");
passwdField.setText(""); urlField.setText(""); tagsField.setText("");
hyperLink.setText(""); unhiddenPassword.setText(""); headerLabel.setText(headerLabelTxt);
headerLabel.setTextFill(defaultColor);
}
/* Cleaver way to keep duplicate data out.... =] */
private void enableSave() {
createBttn.setDisable(false);
updateBttn.setDisable(true);
deleteBttn.setDisable(true);
}
private void disableSave() {
createBttn.setDisable(true);
updateBttn.setDisable(false);
deleteBttn.setDisable(false);
}
/* Used for movement with dragbar */
@FXML void setOffset(MouseEvent event) {
xOffset = mainStage.getX() - event.getScreenX();
yOffset = mainStage.getY() - event.getScreenY();
}
@FXML void updatePosition(MouseEvent event) {
mainStage.setX(event.getScreenX() + xOffset);
mainStage.setY(event.getScreenY() + yOffset);
}
/* End used for movement with dragbar */
/* Lock screen and close program actions */
@FXML void ctrlLockScrn(KeyEvent event) {
if (event.isControlDown() && event.getCode() == KeyCode.L)
lockScrn();
}
@FXML void lockScreen(ActionEvent event) {
lockScrn();
}
private void lockScrn() {
basePane.setVisible(false);
passwdDialogField.requestFocus();
passwdDialog.setVisible(true);
}
private void checkPassword() {
if (dbConn.checkPassword(passwdDialogField.getText(), passwdPresent, true)) {
basePane.setVisible(true);
passwdDialog.setVisible(false);
passwdDialogField.setText("");
messageLabel.setTextFill(neutral);
messageLabel.setText("Enter Your Password");
passwdPresent = true;
} else {
passwdDialogField.setText("");
messageLabel.setTextFill(error);
messageLabel.setText("Incorrect password...");
}
}
@FXML void checkPass1(KeyEvent event) { if (event.getCode() == KeyCode.ENTER) checkPassword(); }
@FXML void checkPass2(ActionEvent event) { checkPassword(); }
@FXML void closeProgram(ActionEvent event) { close(); }
@FXML void closeProgramDialog(ActionEvent event) { close(); }
private void close() { mainStage.close(); }
// End general interface manipulations
// Used to lock window and close program
public void setStageNScene(Stage mainStage, Scene mainScene) {
this.mainStage = mainStage;
this.mainScene = mainScene;
}
}

View File

@@ -0,0 +1,44 @@
package com.itdominator.darkcrypt;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import java.awt.SplashScreen;
import java.util.logging.Level;
import java.io.IOException;
public class DarkCrypt extends Application {
// Classes
private Controller controler = new Controller();
// Generics
private SplashScreen splash = SplashScreen.getSplashScreen();
@Override public void start(Stage stage) throws Exception, IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("resources/DarkCrypt.fxml"));
loader.setController(controler);
loader.load();
Scene scene = new Scene(loader.getRoot());
scene.getStylesheets().add("/com/itdominator/darkcrypt/resources/stylesheet.css");
scene.setFill(null);
stage.setTitle("DarkCrypt");
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.getIcons().add(new Image(DarkCrypt.class.getResourceAsStream("resources/DarkCrypt.png")));
stage.setResizable(false);
controler.setStageNScene(stage, scene); // pass stage n scene for locking and closing program
splash.close();
stage.show();
}
public static void main(String[] args) { launch(args); }
}

View File

@@ -0,0 +1,256 @@
package com.itdominator.darkcrypt.handlers;
import com.itdominator.darkcrypt.utils.DarkCryptLogger;
import com.itdominator.darkcrypt.handlers.DBConnect;
import com.itdominator.darkcrypt.utils.Utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.logging.Level;
import java.util.Properties;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
public class DBConnect {
// Classes
private static DBConnect dbConnect = new DBConnect();
private DarkCryptLogger cryptLogger = DarkCryptLogger.getInstance();
private Connection connector; // SQL connector to DriverManager connection.
private Set<String> noDupTagsSet = new HashSet<String>();
private static final String JDBC_URL = "jdbc:sqlite:resources/DarkCrypt.db";
// Instance passer
public static DBConnect getInstance() { return dbConnect; }
// Init DBConnect
private DBConnect() {
try {
this.connector = DriverManager.getConnection(JDBC_URL);
if (this.connector != null)
System.out.println("Connected to db driver....");
} catch (SQLException sqlException) {
String message = "\nDarkCrypt Failed to connect to the database.... See logs.\n";
System.out.println(message);
cryptLogger.insertToLog(Level.SEVERE, message, sqlException);
}
}
public List<String> searchForEntry(String searchTerm) {
List<String> data = new ArrayList<String>();
try {
String sql = "SELECT Title FROM DarkCrypt WHERE Title LIKE ?";
PreparedStatement pstmt = connector.prepareStatement(sql);
pstmt.setString(1, "%" + searchTerm + "%");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
data.add(rs.getString("Title"));
}
} catch (SQLException sqlException) { }
return data;
}
public void createEntry(String[] data) throws Exception {
String unencryptedPassword = data[3];
data[5] = (data[5].isEmpty()) ? "[no tag]": data[5].replace("\\s","");
if (!unencryptedPassword.isEmpty())
data[3] = Utils.encryptGeneral(unencryptedPassword);
String preStmt = "INSERT INTO DarkCrypt (Title, Description, Username, Password, Url, Tags)" +
" Values(?,?,?,?,?,?)";
String errorMsg = "DarkCrypt Failed to insert to the database... See logs.\n";
dbHandler(preStmt, data, errorMsg);
System.out.println("Created entry...");
}
public void updateEntry(String[] data) throws Exception {
String unencryptedPassword = data[3];
data[5] = (data[5].equals("")) ? "[no tag]": data[5].replace("\\s","");
data[3] = Utils.encryptGeneral(unencryptedPassword);
String preStmt = "UPDATE DarkCrypt SET Title = ? , Description = ? , Username = ? ," +
" Password = ? , Url = ? , Tags = ? WHERE id = ? ";
String errorMsg = "\nDarkCrypt Failed to update row in database... See logs.\n";
dbHandler(preStmt, data, errorMsg);
System.out.print("Updated entry...");
}
public void deleteEntry(String[] data) {
String preStmt = "DELETE FROM DarkCrypt WHERE id = ? ";
String errorMsg = "DarkCrypt Failed to delete from database... See logs.\n";
dbHandler(preStmt, data, errorMsg);
System.out.print("Deleted entry...");
}
public String[] retrieveEntry(String branch, String leaf) {
String[] data = new String[7];
String preStmt = "";
PreparedStatement stmt;
try {
// This has issues if there is a duplicate entry of title but branch is root.
// The design is supposed look at tags to root out duplicates.
if (!branch.equals(":: Tags ::")) {
preStmt = "SELECT * FROM DarkCrypt WHERE Tags LIKE ? AND Title = ?";
stmt = connector.prepareStatement(preStmt);
stmt.setString(1, "%" + branch + "%");
stmt.setString(2, leaf);
} else {
preStmt = "SELECT * FROM DarkCrypt WHERE Title = ?";
stmt = connector.prepareStatement(preStmt);
stmt.setString(1, leaf);
}
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
data[0] = rs.getString("Title");
data[1] = rs.getString("Description");
data[2] = rs.getString("Username");
// passwords are encrypted and therefore need to be decrypted to view
if (!rs.getString("Password").isEmpty())
data[3] = Utils.decryptGeneral(rs.getString("Password"));
else
data[3] = rs.getString("Password");
data[4] = rs.getString("Url");
data[5] = rs.getString("Tags").replace("[no tag]", "");
data[6] = rs.getString("id");
}
} catch (SQLException sqlException) {
String message = "DarkCrypt Failed to get from database query data... See logs.\n";
System.out.println(message + sqlException);
cryptLogger.insertToLog(Level.SEVERE, message, sqlException);
} catch (Exception e) {}
return data;
}
private void dbHandler(String preStmt, String[] arguments, String message) {
try {
PreparedStatement stmt = connector.prepareStatement(preStmt);
int count = arguments.length;
if (count > 1) {
for (int i = 1; i <= count; i++) { // B/c of sql prep statement it starts at 1
if (i != 7) {
stmt.setString(i, arguments[i-1]);
} else { // Need to convert 'id' to int
System.out.println(i);
stmt.setInt(i, Integer.parseInt(arguments[i-1]));
}
}
} else if (count == 1) { // Assuming deletion since only 'id' passesd
stmt.setInt(1, Integer.parseInt(arguments[0]));
} else {
return;
}
stmt.executeUpdate();
} catch (SQLException sqlException) {
System.out.println(message);
cryptLogger.insertToLog(Level.SEVERE, message, sqlException);
}
}
public Set<String> getBranches() {
try {
String sql = "SELECT Tags FROM DarkCrypt";
PreparedStatement stmt = connector.prepareStatement(sql);;
ResultSet rs = stmt.executeQuery();
// Get a de-duplicated set of tags that are coma split
while (rs.next()) {
String[] commaSplitTags = rs.getString("Tags").split("\\"+",");
for (int i=0; i<commaSplitTags.length; i++) {
if (!noDupTagsSet.contains(commaSplitTags[i]))
noDupTagsSet.add(commaSplitTags[i]);
}
}
} catch (SQLException ex) {}
return noDupTagsSet;
}
public List<String> getLeaves(String branch) {
List<String> data = new ArrayList<String>();
String sql = "SELECT * FROM DarkCrypt WHERE ',' || Tags || ',' LIKE ?";
try {
PreparedStatement pstmt = connector.prepareStatement(sql);
pstmt.setString(1, "%"+ branch +",%");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
data.add(rs.getString("Title"));
}
} catch (SQLException ex) {}
return data;
}
// See if a passwd exists or compare NOTE: the first run in controller
// sees if a password exists and all other runs compare...
public boolean checkPassword(String pass, boolean passwdPresent, boolean compare) {
if (passwdPresent) {
try {
Statement st = this.connector.createStatement();
String sql = String.format("SELECT * FROM Login");
ResultSet rs = st.executeQuery(sql);
if (rs.next()) {
if (compare) {
if (pass.equals(Utils.decryptGeneral(rs.getString("Pass")))) {
pass = "";
return true;
}
} else {
return true;
}
}
} catch (SQLException sqlException) {
String message = "\nDarkCrypt Failed to access database... See logs.\n";
System.out.println(message);
cryptLogger.insertToLog(Level.SEVERE, message, sqlException);
} catch (Exception decException) {
String message = "\nDarkCrypt Failed to encode password properly... See logs.\n";
System.out.println(message);
cryptLogger.insertToLog(Level.WARNING, message, decException);
}
return false;
} else {
setLogin(pass);
return true;
}
}
public void setLogin(String key) {
try {
key = Utils.encryptGeneral(key);
String sql = "INSERT INTO Login Values (?)";
PreparedStatement pstmt = connector.prepareStatement(sql);
pstmt.setString(1, key);
pstmt.execute();
} catch (SQLException sqlException) {
String message = "\nDarkCrypt Failed to access Login database...\n";
System.out.println(message + sqlException);
cryptLogger.insertToLog(Level.SEVERE, message, sqlException);
} catch (Exception e) { }
}
}

View File

@@ -0,0 +1,17 @@
#!/bin/bash
# -Xlint:unchecked
function main() {
javac -cp .:../bin/resources/lib/* \
utils/*.java \
handlers/*.java \
*.java
rm ../com/itdominator/darkcrypt/*.class
rm ../com/itdominator/darkcrypt/handlers/*.class
rm ../com/itdominator/darkcrypt/utils/*.class
mv *.class ../com/itdominator/darkcrypt/
mv handlers/*.class ../com/itdominator/darkcrypt/handlers/
mv utils/*.class ../com/itdominator/darkcrypt/utils/
}
main;

View File

@@ -0,0 +1,162 @@
// Copyright 2003-2009 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
// www.source-code.biz, www.inventec.ch/chdh
//
// This module is multi-licensed and may be used under the terms
// of any of the following licenses:
//
// EPL, Eclipse Public License, http://www.eclipse.org/legal
// LGPL, GNU Lesser General Public License, http://www.gnu.org/licenses/lgpl.html
// AL, Apache License, http://www.apache.org/licenses
// BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php
//
// Please contact the author if you need another license.
// This module is provided "as is", without warranties of any kind.
package com.itdominator.darkcrypt.utils;
/**
* A Base64 Encoder/Decoder.
*
* <p>
* This class is used to encode and decode data in Base64 format as described in RFC 1521.
*
* <p>
* Home page: <a href="http://www.source-code.biz">www.source-code.biz</a><br>
* Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br>
* Multi-licensed: EPL/LGPL/AL/BSD.
*
* <p>
* Version history:<br>
* 2003-07-22 Christian d'Heureuse (chdh): Module created.<br>
* 2005-08-11 chdh: Lincense changed from GPL to LGPL.<br>
* 2006-11-21 chdh:<br>
* &nbsp; Method encode(String) renamed to encodeString(String).<br>
* &nbsp; Method decode(String) renamed to decodeString(String).<br>
* &nbsp; New method encode(byte[],int) added.<br>
* &nbsp; New method decode(String) added.<br>
* 2009-07-16: Additional licenses (EPL/AL) added.<br>
* 2009-09-16: Additional license (BSD) added.<br>
* 2009-09-16: Additional license (BSD) added.<br>
* 2010-01-27: Package name added.<br>
*/
public class Base64Coder {
// Mapping table from 6-bit nibbles to Base64 characters.
private static char[] map1 = new char[64];
static {
int i=0;
for (char c='A'; c<='Z'; c++) map1[i++] = c;
for (char c='a'; c<='z'; c++) map1[i++] = c;
for (char c='0'; c<='9'; c++) map1[i++] = c;
map1[i++] = '+'; map1[i++] = '/'; }
// Mapping table from Base64 characters to 6-bit nibbles.
private static byte[] map2 = new byte[128];
static {
for (int i=0; i<map2.length; i++) map2[i] = -1;
for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
/**
* Encodes a string into Base64 format.
* No blanks or line breaks are inserted.
* @param s a String to be encoded.
* @return A String with the Base64 encoded data.
*/
public static String encodeString (String s) {
return new String(encode(s.getBytes())); }
/**
* Encodes a byte array into Base64 format.
* No blanks or line breaks are inserted.
* @param in an array containing the data bytes to be encoded.
* @return A character array with the Base64 encoded data.
*/
public static char[] encode (byte[] in) {
return encode(in,in.length); }
/**
* Encodes a byte array into Base64 format.
* No blanks or line breaks are inserted.
* @param in an array containing the data bytes to be encoded.
* @param iLen number of bytes to process in <code>in</code>.
* @return A character array with the Base64 encoded data.
*/
public static char[] encode (byte[] in, int iLen) {
int oDataLen = (iLen*4+2)/3; // output length without padding
int oLen = ((iLen+2)/3)*4; // output length including padding
char[] out = new char[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++] & 0xff;
int i1 = ip < iLen ? in[ip++] & 0xff : 0;
int i2 = ip < iLen ? in[ip++] & 0xff : 0;
int o0 = i0 >>> 2;
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
int o3 = i2 & 0x3F;
out[op++] = map1[o0];
out[op++] = map1[o1];
out[op] = op < oDataLen ? map1[o2] : '='; op++;
out[op] = op < oDataLen ? map1[o3] : '='; op++; }
return out; }
/**
* Decodes a string from Base64 format.
* @param s a Base64 String to be decoded.
* @return A String containing the decoded data.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static String decodeString (String s) {
return new String(decode(s)); }
/**
* Decodes a byte array from Base64 format.
* @param s a Base64 String to be decoded.
* @return An array containing the decoded data bytes.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static byte[] decode (String s) {
return decode(s.toCharArray()); }
/**
* Decodes a byte array from Base64 format.
* No blanks or line breaks are allowed within the Base64 encoded data.
* @param in a character array containing the Base64 encoded data.
* @return An array containing the decoded data bytes.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static byte[] decode (char[] in) {
int iLen = in.length;
if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
while (iLen > 0 && in[iLen-1] == '=') iLen--;
int oLen = (iLen*3) / 4;
byte[] out = new byte[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++];
int i1 = in[ip++];
int i2 = ip < iLen ? in[ip++] : 'A';
int i3 = ip < iLen ? in[ip++] : 'A';
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
int b0 = map2[i0];
int b1 = map2[i1];
int b2 = map2[i2];
int b3 = map2[i3];
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
int o0 = ( b0 <<2) | (b1>>>4);
int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
int o2 = ((b2 & 3)<<6) | b3;
out[op++] = (byte)o0;
if (op<oLen) out[op++] = (byte)o1;
if (op<oLen) out[op++] = (byte)o2; }
return out; }
// Dummy constructor.
private Base64Coder() {}
} // end class Base64Coder

View File

@@ -0,0 +1,31 @@
package com.itdominator.darkcrypt.utils;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.logging.FileHandler;
import java.io.IOException;
public class DarkCryptLogger {
private static DarkCryptLogger darkcryptLogger = new DarkCryptLogger();
private Logger logger = Logger.getLogger(DarkCryptLogger.class.getName());
private boolean append = false;
// Instance passer
public static DarkCryptLogger getInstance() { return darkcryptLogger; }
// Init DarkCryptLogger
private DarkCryptLogger() {
try {
FileHandler logFile = new FileHandler("darkcrypt_error.log", append);
logger.addHandler(logFile);
} catch (IOException e) {
insertToLog(Level.SEVERE, "Can not access error log file...", e);
e.printStackTrace();
}
}
public void insertToLog(Level severity, String message, Exception stackTrace) {
logger.log(severity, message, stackTrace);
}
}

View File

@@ -0,0 +1,54 @@
package com.itdominator.darkcrypt.utils;
import java.util.Random;
public class PasswordGenerator {
public static final int ALPHABETIC = 1;
public static final int NUMERIC = 2;
public static final int ALPHABETIC_NUMERIC = 3;
public static final int ALPHABETIC_NUMERIC_SYMBOLS = 4;
public static final String ALPHABETS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String NUMBERS = "1234567890";
public static final String SYMBOLS = "-=_+)(*&^%$#@!<>/\\}{[]?.,";
private Random random;
private final int length;
private final int type;
public PasswordGenerator(int length, int type) {
this.length = length;
this.type = type;
this.random = new Random(System.currentTimeMillis());
}
public String generatePassword() {
String validChars;
switch (this.type) {
case PasswordGenerator.ALPHABETIC:
validChars = PasswordGenerator.ALPHABETS;
break;
case PasswordGenerator.ALPHABETIC_NUMERIC:
validChars = PasswordGenerator.ALPHABETS + PasswordGenerator.NUMBERS;
break;
case PasswordGenerator.NUMERIC:
validChars = PasswordGenerator.NUMBERS;
break;
case PasswordGenerator.ALPHABETIC_NUMERIC_SYMBOLS:
validChars = PasswordGenerator.ALPHABETS + PasswordGenerator.NUMBERS + PasswordGenerator.SYMBOLS;
break;
default:
validChars = "";
}
char[] password = new char[this.length];
for (int i = 0; i < password.length; i++) {
int charPosition = randomInt(validChars.length());
password[i] = new Character(validChars.charAt(charPosition));
}
return new String(password);
}
private int randomInt(int max) { return this.random.nextInt(max); }
}

View File

@@ -0,0 +1,79 @@
package com.itdominator.darkcrypt.utils;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class Utils {
public static String encryptGeneral(String value) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
String ekey = getGeneralKey();
value = encrypt(ekey, value);
value = String.format("%s%s%s", value.substring(0, 5), ekey, value.substring(5));
return value;
}
public static String getGeneralKey() {
String result = "";
String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < 16; i++) {
result += letters.charAt(random.nextInt(letters.length()));
}
return result;
}
public static String decryptGeneral(String value) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
String ekey = value.substring(5, 21);
value = String.format("%s%s", value.substring(0, 5), value.substring(21));
value = decrypt(ekey, value);
return value;
}
public static String encrypt(String key, String text) throws UnsupportedEncodingException,
NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
byte[] byteKey = key.getBytes("UTF8");
byte[] byteText = text.getBytes("UTF8");
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k = new SecretKeySpec(byteKey, "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] byteEncrypted = c.doFinal(byteText);
String encrypted = new String(Base64Coder.encode(byteEncrypted));
return encrypted;
}
public static String decrypt(String key, String encrypted) throws UnsupportedEncodingException,
NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, IOException {
byte[] byteKey = key.getBytes("UTF8");
byte[] byteEncrypted = Base64Coder.decode(encrypted);
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k = new SecretKeySpec(byteKey, "AES");
c.init(Cipher.DECRYPT_MODE, k);
byte[] byteText = c.doFinal(byteEncrypted);
String text = new String(byteText);
return text;
}
}

View File

@@ -0,0 +1,14 @@
#!/bin/bash
function main() {
find . -type f | entr ./unix_compile.sh
runBuildJar;
}
function runBuildJar() {
cd ../
./buildJar.sh
mv ./DarkCrypt.jar ./bin/
}
main;