diff --git a/AdminTools/build/built-jar.properties b/AdminTools/build/built-jar.properties index 6dc72fd..2b8e8b6 100644 --- a/AdminTools/build/built-jar.properties +++ b/AdminTools/build/built-jar.properties @@ -1,4 +1,4 @@ -#Sun, 19 Jul 2020 17:51:38 +0200 +#Fri, 24 Jul 2020 15:15:01 +0200 C\:\\Users\\lukak\\Documents\\NetBeansProjects\\AdminTools= diff --git a/AdminTools/build/classes/rconclient/RconClient.class b/AdminTools/build/classes/rconclient/RconClient.class index 85b3838..c58a068 100644 Binary files a/AdminTools/build/classes/rconclient/RconClient.class and b/AdminTools/build/classes/rconclient/RconClient.class differ diff --git a/AdminTools/build/classes/rconclient/gui/LoginWindow.fxml b/AdminTools/build/classes/rconclient/gui/LoginWindow.fxml new file mode 100644 index 0000000..dd7751d --- /dev/null +++ b/AdminTools/build/classes/rconclient/gui/LoginWindow.fxml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AdminTools/build/classes/rconclient/gui/LoginWindowController.class b/AdminTools/build/classes/rconclient/gui/LoginWindowController.class new file mode 100644 index 0000000..996f4fd Binary files /dev/null and b/AdminTools/build/classes/rconclient/gui/LoginWindowController.class differ diff --git a/AdminTools/build/classes/rconclient/gui/RconWindowController.class b/AdminTools/build/classes/rconclient/gui/RconWindowController.class index dc28c17..0718ddf 100644 Binary files a/AdminTools/build/classes/rconclient/gui/RconWindowController.class and b/AdminTools/build/classes/rconclient/gui/RconWindowController.class differ diff --git a/AdminTools/build/classes/rconclient/gui/SettingsWindowController.class b/AdminTools/build/classes/rconclient/gui/SettingsWindowController.class index 1220650..eca9519 100644 Binary files a/AdminTools/build/classes/rconclient/gui/SettingsWindowController.class and b/AdminTools/build/classes/rconclient/gui/SettingsWindowController.class differ diff --git a/AdminTools/build/classes/rconclient/gui/StatusWindowController.class b/AdminTools/build/classes/rconclient/gui/StatusWindowController.class index ccea6e0..4aa7647 100644 Binary files a/AdminTools/build/classes/rconclient/gui/StatusWindowController.class and b/AdminTools/build/classes/rconclient/gui/StatusWindowController.class differ diff --git a/AdminTools/build/classes/rconclient/gui/Style.css b/AdminTools/build/classes/rconclient/gui/Style.css index b59e21f..37b4e64 100644 --- a/AdminTools/build/classes/rconclient/gui/Style.css +++ b/AdminTools/build/classes/rconclient/gui/Style.css @@ -292,4 +292,23 @@ .list-cell:even{ -fx-background-color : #575757; -fx-text-fill: white; +} + +.leftSidePane{ + -fx-background-color: #3d3d3d; + -fx-border-color: #5c5c5c; + -fx-border-width: 0px 1px 0px 0px; +} + +.imageBackground{ + -fx-background-image: url(/rconclient/image/background.png); + -fx-background-size: cover; +} + +.loginCenter{ + -fx-background-color: #3d3d3d; + -fx-border-color: #5c5c5c; + -fx-border-width: 1px; + -fx-border-radius: 10px; + -fx-background-radius: 10px; } \ No newline at end of file diff --git a/AdminTools/build/classes/rconclient/image/background.png b/AdminTools/build/classes/rconclient/image/background.png new file mode 100644 index 0000000..25ee40c Binary files /dev/null and b/AdminTools/build/classes/rconclient/image/background.png differ diff --git a/AdminTools/build/classes/rconclient/security/Mozaic.class b/AdminTools/build/classes/rconclient/security/Mozaic.class new file mode 100644 index 0000000..ba25399 Binary files /dev/null and b/AdminTools/build/classes/rconclient/security/Mozaic.class differ diff --git a/AdminTools/build/classes/rconclient/security/SecureIO.class b/AdminTools/build/classes/rconclient/security/SecureIO.class new file mode 100644 index 0000000..64d1a76 Binary files /dev/null and b/AdminTools/build/classes/rconclient/security/SecureIO.class differ diff --git a/AdminTools/build/classes/rconclient/util/CustomRcon.class b/AdminTools/build/classes/rconclient/util/CustomRcon.class index 258e02f..e856895 100644 Binary files a/AdminTools/build/classes/rconclient/util/CustomRcon.class and b/AdminTools/build/classes/rconclient/util/CustomRcon.class differ diff --git a/AdminTools/build/classes/rconclient/util/Data.class b/AdminTools/build/classes/rconclient/util/Data.class index 7365f0a..5f4c066 100644 Binary files a/AdminTools/build/classes/rconclient/util/Data.class and b/AdminTools/build/classes/rconclient/util/Data.class differ diff --git a/AdminTools/build/classes/rconclient/util/Utill.class b/AdminTools/build/classes/rconclient/util/Utill.class index 38230e7..814b455 100644 Binary files a/AdminTools/build/classes/rconclient/util/Utill.class and b/AdminTools/build/classes/rconclient/util/Utill.class differ diff --git a/AdminTools/build/classes/rconclient/util/WindowLoader.class b/AdminTools/build/classes/rconclient/util/WindowLoader.class index 21536b7..dfb9e3d 100644 Binary files a/AdminTools/build/classes/rconclient/util/WindowLoader.class and b/AdminTools/build/classes/rconclient/util/WindowLoader.class differ diff --git a/AdminTools/nbproject/private/private.xml b/AdminTools/nbproject/private/private.xml index 63d0282..ff158a3 100644 --- a/AdminTools/nbproject/private/private.xml +++ b/AdminTools/nbproject/private/private.xml @@ -6,9 +6,11 @@ file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/util/Data.java file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/RconClient.java file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/gui/RconWindowController.java - file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/textprocessing/Markup.java + file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/util/WindowLoader.java + file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/gui/LoginWindowController.java + file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/gui/SettingsWindowController.java file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/gui/StatusWindowController.java - file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/util/Utill.java + file:/C:/Users/lukak/Documents/NetBeansProjects/AdminTools/src/rconclient/util/CustomRcon.java diff --git a/AdminTools/src/rconclient/RconClient.java b/AdminTools/src/rconclient/RconClient.java index 0006c6d..a34cee9 100644 --- a/AdminTools/src/rconclient/RconClient.java +++ b/AdminTools/src/rconclient/RconClient.java @@ -1,5 +1,6 @@ package rconclient; +import java.io.File; import java.io.IOException; import java.net.SocketException; import javafx.application.Application; @@ -28,7 +29,12 @@ public class RconClient extends Application { @Override public void start(Stage stage) throws Exception { - Parent root = FXMLLoader.load(getClass().getResource("/rconclient/gui/RconWindow.fxml")); + Parent root; + if(new File("rconclient.properties").exists()){ + root = FXMLLoader.load(getClass().getResource("/rconclient/gui/RconWindow.fxml")); + }else{ + root = FXMLLoader.load(getClass().getResource("/rconclient/gui/LoginWindow.fxml")); + } Scene scene = new Scene(root); diff --git a/AdminTools/src/rconclient/gui/LoginWindow.fxml b/AdminTools/src/rconclient/gui/LoginWindow.fxml new file mode 100644 index 0000000..dd7751d --- /dev/null +++ b/AdminTools/src/rconclient/gui/LoginWindow.fxml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AdminTools/src/rconclient/gui/LoginWindowController.java b/AdminTools/src/rconclient/gui/LoginWindowController.java new file mode 100644 index 0000000..60020cc --- /dev/null +++ b/AdminTools/src/rconclient/gui/LoginWindowController.java @@ -0,0 +1,144 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package rconclient.gui; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Random; +import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.Logger; +import javafx.application.Platform; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Label; +import javafx.scene.control.PasswordField; +import javafx.scene.control.ProgressBar; +import javafx.scene.control.TextField; +import javafx.scene.layout.AnchorPane; +import net.kronos.rkon.core.ex.AuthenticationException; +import rconclient.util.CustomRcon; +import rconclient.util.Data; +import rconclient.util.WindowLoader; +import simplefxdialog.Dialog; +import simplefxdialog.img.DialogImage; + +/** + * FXML Controller class + * + * @author lukak + */ +public class LoginWindowController implements Initializable { + + @FXML + private AnchorPane rootPane; + @FXML + private TextField ip; + @FXML + private TextField port; + @FXML + private PasswordField password; + @FXML + private Label loginButton; + @FXML + private ProgressBar loginProgress; + @FXML + private Label loginInfo; + @FXML + private AnchorPane loginPane; + + /** + * Initializes the controller class. + */ + @Override + public void initialize(URL url, ResourceBundle rb) { + // TODO + } + + @FXML + private void login() { + Thread loginThread = new Thread(() -> { + Platform.runLater(() -> { + loginPane.setDisable(true); + loginProgress.setProgress(ProgressBar.INDETERMINATE_PROGRESS); + loginInfo.setText("Starting up"); + }); + + try { + Thread.sleep(new Random().nextInt(200)); + } catch (InterruptedException ex) { + + } + + Platform.runLater(() -> { + loginInfo.setText("Connecting and autentificating"); + }); + + boolean connected = true; + try { + CustomRcon rcon = CustomRcon.getInstance(ip.getText(), Integer.valueOf(port.getText()), password.getText().getBytes()); + } catch (IOException ex) { + connected = false; + Platform.runLater(() -> { + loginProgress.setProgress(0); + loginInfo.setText(""); + Dialog.okDialog(DialogImage.error, "Connnection Error", "Couldnt connect to server.\n Probably an incorect IP."); + ip.setText(""); + }); + } catch (AuthenticationException ex) { + connected = false; + Platform.runLater(() -> { + loginProgress.setProgress(0); + loginInfo.setText(""); + Dialog.okDialog(DialogImage.error, "Connnection Error", "Couldnt authenticate with server. \nIncorrect password."); + password.setText(""); + }); + } catch (NumberFormatException ex) { + connected = false; + Platform.runLater(() -> { + loginProgress.setProgress(0); + loginInfo.setText(""); + Dialog.okDialog(DialogImage.error, "Conversion error", "Port you specified is not a valid integer"); + port.setText(""); + }); + } catch (Exception ex) { + connected = false; + Platform.runLater(() -> { + loginProgress.setProgress(0); + loginInfo.setText(""); + Dialog.okDialog(DialogImage.error, "Error", "General exception\n" + ex.getMessage()); + }); + } + + loginPane.setDisable(false); + + if (connected) { + Data.rconTextData = null; + + //Write to credentials + ArrayList props = Data.credentialsDefaults; + + props.set(0, ip.getText()); //set ip + props.set(1, port.getText()); //set port + props.set(2, password.getText()); //set password + try { + Data.writeCredentials(props); + } catch (IOException ex) { + + } + Data.refresh(); + + Platform.runLater(() -> { + loginInfo.setText("Login successful"); + loginProgress.setProgress(0); + WindowLoader.loadRcon(rootPane); + }); + } + }); + loginThread.start(); + } +} diff --git a/AdminTools/src/rconclient/gui/RconWindowController.java b/AdminTools/src/rconclient/gui/RconWindowController.java index 4ae6605..d69d02a 100644 --- a/AdminTools/src/rconclient/gui/RconWindowController.java +++ b/AdminTools/src/rconclient/gui/RconWindowController.java @@ -7,26 +7,22 @@ import java.awt.Desktop; import java.io.IOException; -import java.net.SocketException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.ResourceBundle; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Platform; -import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.Initializable; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Hyperlink; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextField; -import javafx.scene.image.Image; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; @@ -35,9 +31,11 @@ import javafx.scene.text.FontPosture; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; -import javafx.stage.Stage; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import net.kronos.rkon.core.ex.AuthenticationException; -import rconclient.RconClient; +import rconclient.security.Mozaic; import rconclient.util.CustomRcon; import rconclient.textprocessing.Markup; import rconclient.util.Data; @@ -76,7 +74,7 @@ public class RconWindowController implements Initializable { @Override public void initialize(URL url, ResourceBundle rb) { - + //Get if barebones argument was given and transition to barebones mode if it was given if (Data.arguments.length > 0) { if (Data.arguments[0].equals("barebones")) { @@ -168,24 +166,24 @@ public void initialize(URL url, ResourceBundle rb) { Data d = Data.getInstance(); writeRconInternal("Connecting to " + d.getHost() + " : " + d.getPort()); try { - CustomRcon cr = CustomRcon.getInstance(d.getHost(), d.getPort(), d.getPassword()); + CustomRcon cr = CustomRcon.getInstance(); } catch (IOException ex) { connected = false; Platform.runLater(() -> { - Dialog.okDialog(DialogImage.error, "Connnection Error", "Couldnt connect to server.\n Probably a incorect IP, edit properties"); - System.exit(0); + Dialog.okDialog(DialogImage.error, "Connnection Error", "Couldnt connect to server.\n Probably an incorect IP."); + WindowLoader.loadLogin(rootPane); }); } catch (AuthenticationException ex) { connected = false; Platform.runLater(() -> { - Dialog.okDialog(DialogImage.error, "Connnection Error", "Couldnt authenticate with server. \nIncorect IP or password, edit properties."); - System.exit(0); + Dialog.okDialog(DialogImage.error, "Connnection Error", "Couldnt authenticate with server. \nIncorrect password."); + WindowLoader.loadLogin(rootPane); }); } catch (Exception ex) { connected = false; Platform.runLater(() -> { - Dialog.okDialog(DialogImage.error, "Connnection Error", "General exception\n" + ex.getMessage()); - System.exit(0); + Dialog.okDialog(DialogImage.error, "Error", "General exception\n" + ex.getMessage()); + WindowLoader.loadLogin(rootPane); }); } //Write succsesfull connection @@ -205,6 +203,7 @@ public void initialize(URL url, ResourceBundle rb) { connect.start(); Data.startingUp = false; } + } public void writeRcon(String message) { @@ -274,6 +273,12 @@ private void send() { rcon.getChildren().clear(); writeRconInternal("Cleared console"); break; + //Clear command - clears the console + case "!login": + isRightToSend = false; + rcon.getChildren().clear(); + WindowLoader.loadLogin(rootPane); + break; //Exit command - exits the program case "!exit": diff --git a/AdminTools/src/rconclient/gui/SettingsWindowController.java b/AdminTools/src/rconclient/gui/SettingsWindowController.java index 69ae14e..d1d7c3c 100644 --- a/AdminTools/src/rconclient/gui/SettingsWindowController.java +++ b/AdminTools/src/rconclient/gui/SettingsWindowController.java @@ -20,6 +20,7 @@ import javafx.scene.control.Slider; import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; import net.kronos.rkon.core.ex.AuthenticationException; import rconclient.util.CustomRcon; import rconclient.util.Data; @@ -27,7 +28,6 @@ import simplefxdialog.Dialog; import simplefxdialog.img.DialogImage; - /** * FXML Controller class * @@ -80,61 +80,80 @@ private void loadRcon() { private void loadStatus() { WindowLoader.loadStatus(rootPane); } - + @FXML - private void login(){ + private void login() { connectionIndicator.setProgress(ProgressBar.INDETERMINATE_PROGRESS); - Thread thread = new Thread(() ->{ - Data datao = Data.getInstance(); - boolean isSuccsesfull = true; - - try { - CustomRcon rcon = CustomRcon.getInstance(); - rcon.disconnect(); - - rcon = CustomRcon.getInstance(rconIP.getText(), Integer.valueOf(rconPort.getText()), rconPassword.getText().getBytes()); - } catch (IOException ex) { - isSuccsesfull = false; - Dialog.okDialog(DialogImage.error, "Server error", "Incorect ip or server is not up"); - rconIP.setText(datao.getHost()); - rconPort.setText(String.valueOf(datao.getPort())); - } catch (AuthenticationException ex){ - isSuccsesfull = false; - Dialog.okDialog(DialogImage.error, "Credentials error", "Credentials arent correct"); - rconPassword.setText(datao.getPasswordAsString()); - } - - if(isSuccsesfull){ - ArrayList data = Data.read(); - data.set(0, rconIP.getText()); - data.set(1, rconPort.getText()); - data.set(2, rconPassword.getText()); - data.set(6, String.valueOf(rconRemember.isSelected())); - Data.write(data); - Data.refresh(); - } - + Thread thread = new Thread(() -> { + Data datao = Data.getInstance(); + boolean isSuccsesfull = true; + + try { + CustomRcon rcon = CustomRcon.getInstance(); + rcon.disconnect(); + + rcon = CustomRcon.getInstance(rconIP.getText(), Integer.valueOf(rconPort.getText()), rconPassword.getText().getBytes()); + } catch (IOException ex) { + isSuccsesfull = false; + Dialog.okDialog(DialogImage.error, "Server error", "Incorect ip or server is not up"); + rconIP.setText(datao.getHost()); + rconPort.setText(String.valueOf(datao.getPort())); + } catch (AuthenticationException ex) { + isSuccsesfull = false; + Dialog.okDialog(DialogImage.error, "Credentials error", "Credentials arent correct"); + rconPassword.setText(datao.getPasswordAsString()); + } + + if (isSuccsesfull) { + ArrayList data = Data.read(); + data.set(3, String.valueOf(rconRemember.isSelected())); + Data.write(data); + + ArrayList credentials = Data.readCredentials(); + credentials.set(0, rconIP.getText()); + credentials.set(1, rconPort.getText()); + credentials.set(2, rconPassword.getText()); + try { + Data.writeCredentials(credentials); + } catch (IOException ex) { + Logger.getLogger(SettingsWindowController.class.getName()).log(Level.SEVERE, null, ex); + } + + Data.refresh(); + + Stage stage = (Stage) rootPane.getScene().getWindow(); + Data d = Data.getInstance(); + String barebonesq = ""; + if (Data.arguments.length > 0) { + if (Data.arguments[0].equals("barebones")) { + barebonesq = " [Barebones mode]"; + } + } + stage.setTitle("Admin Tools - " + d.getHost() + ":" + d.getPort() + barebonesq); + stage.show(); + } + }); - + connectionIndicator.setProgress(0.0); } - + @FXML - private void refresh(){ + private void refresh() { sARR.setText(String.valueOf(Math.round(settingsApiRequestR.getValue())) + "s"); } - + @FXML - private void apply(){ + private void apply() { ArrayList data = Data.read(); - data.set(7, settingsQuerryRR.getText()); - data.set(8, String.valueOf( Math.round(settingsApiRequestR.getValue()) )); + data.set(4, settingsQuerryRR.getText()); + data.set(5, String.valueOf(Math.round(settingsApiRequestR.getValue()))); Data.write(data); Data.refresh(); } - + @FXML - private void reset(){ + private void reset() { Data d = Data.getInstance(); settingsQuerryRR.setText(String.valueOf(d.getQuerryMcRefreshRate())); settingsApiRequestR.setValue(d.getQuerryMojangApiRefreshRate()); diff --git a/AdminTools/src/rconclient/gui/StatusWindowController.java b/AdminTools/src/rconclient/gui/StatusWindowController.java index ef3bb57..9ae847c 100644 --- a/AdminTools/src/rconclient/gui/StatusWindowController.java +++ b/AdminTools/src/rconclient/gui/StatusWindowController.java @@ -98,7 +98,7 @@ private void loadSettings() { @FXML public void handleMouseClick(MouseEvent arg0) { - //System.out.println("clicked on " + sOnlinePlayers.getSelectionModel().getSelectedItem()); + System.out.println("clicked on " + sOnlinePlayers.getSelectionModel().getSelectedItem()); } private void refreshApiStatus() { diff --git a/AdminTools/src/rconclient/gui/Style.css b/AdminTools/src/rconclient/gui/Style.css index b59e21f..37b4e64 100644 --- a/AdminTools/src/rconclient/gui/Style.css +++ b/AdminTools/src/rconclient/gui/Style.css @@ -292,4 +292,23 @@ .list-cell:even{ -fx-background-color : #575757; -fx-text-fill: white; +} + +.leftSidePane{ + -fx-background-color: #3d3d3d; + -fx-border-color: #5c5c5c; + -fx-border-width: 0px 1px 0px 0px; +} + +.imageBackground{ + -fx-background-image: url(/rconclient/image/background.png); + -fx-background-size: cover; +} + +.loginCenter{ + -fx-background-color: #3d3d3d; + -fx-border-color: #5c5c5c; + -fx-border-width: 1px; + -fx-border-radius: 10px; + -fx-background-radius: 10px; } \ No newline at end of file diff --git a/AdminTools/src/rconclient/image/background.png b/AdminTools/src/rconclient/image/background.png new file mode 100644 index 0000000..25ee40c Binary files /dev/null and b/AdminTools/src/rconclient/image/background.png differ diff --git a/AdminTools/src/rconclient/security/Mozaic.java b/AdminTools/src/rconclient/security/Mozaic.java new file mode 100644 index 0000000..7c64732 --- /dev/null +++ b/AdminTools/src/rconclient/security/Mozaic.java @@ -0,0 +1,90 @@ +package rconclient.security; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Mosaic algorithm for saving and writing encripred files + * + * @author lukak + */ +public class Mozaic { + + private final static String META_FILE_PATH = "meta.encdat"; + private final static String DATA_FILE_PATH = "prop.encdat"; + + public static byte[] readMetaData() { + try { + return readBinary(META_FILE_PATH); + } catch (IOException ex) { + byte[] key = generateKey(); + try { + writeMetaData(key); + } catch (IOException ex1) { + + } + return key; + } + } + + public static void writeMetaData(byte[] data) throws IOException { + writeBinary(META_FILE_PATH, data); + } + + public static byte[] generateKey() { + String protoKey = ""; + for (int i = 0; i < 16; i++) { + Random rand = new Random(); + protoKey += rand.nextInt(10); + } + MessageDigest digest; + try { + digest = MessageDigest.getInstance("SHA-256"); + return digest.digest(protoKey.getBytes()); + } catch (NoSuchAlgorithmException ex) { + Logger.getLogger(Mozaic.class.getName()).log(Level.SEVERE, null, ex); + } + return "0-sadwa546aAD4a87da3sAD".getBytes(); + } + + public static String read() throws IOException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { + byte[] data = readBinary(DATA_FILE_PATH); + + SecureIO sec = new SecureIO(); + + data = sec.decrypt(data, readMetaData()); + return new String(data); + } + + public static void write(String propsToWrite) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, IOException { + SecureIO sec = new SecureIO(); + + writeBinary(DATA_FILE_PATH, sec.encrypt(propsToWrite.getBytes(), readMetaData())); + } + + public static byte[] readBinary(String filePath) throws IOException { + File file = new File(filePath); + return Files.readAllBytes(file.toPath()); + } + + public static void writeBinary(String filePath, byte[] data) throws FileNotFoundException, IOException { + FileOutputStream fos = new FileOutputStream(filePath); + fos.write(data); + fos.close(); + } +} diff --git a/AdminTools/src/rconclient/security/SecureIO.java b/AdminTools/src/rconclient/security/SecureIO.java new file mode 100644 index 0000000..d874f63 --- /dev/null +++ b/AdminTools/src/rconclient/security/SecureIO.java @@ -0,0 +1,50 @@ +package rconclient.security; + +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Base64; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; + +/** + * + * @author lukak + */ +public class SecureIO { + + private SecretKeySpec secretKey; + private byte[] key; + + public void setKey(byte[] myKey) { + MessageDigest sha = null; + try { + key = myKey; + sha = MessageDigest.getInstance("SHA-1"); + key = sha.digest(key); + key = Arrays.copyOf(key, 16); + secretKey = new SecretKeySpec(key, "AES"); + } catch (NoSuchAlgorithmException e) { + + } + } + + public byte[] encrypt(byte[] data, byte[] secret) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException { + setKey(secret); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + return cipher.doFinal(data); + } + + public byte[] decrypt(byte[] data, byte[] secret) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { + setKey(secret); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); + cipher.init(Cipher.DECRYPT_MODE, secretKey); + return cipher.doFinal(data); + } +} diff --git a/AdminTools/src/rconclient/util/CustomRcon.java b/AdminTools/src/rconclient/util/CustomRcon.java index 6e98d5b..a30bc42 100644 --- a/AdminTools/src/rconclient/util/CustomRcon.java +++ b/AdminTools/src/rconclient/util/CustomRcon.java @@ -15,7 +15,6 @@ private CustomRcon(String host, int port, byte[] password) throws IOException, A public static CustomRcon getInstance() throws IOException, AuthenticationException { if (instance == null) { - //Variable declaration Data data = Data.getInstance(); String host = data.getHost(); diff --git a/AdminTools/src/rconclient/util/Data.java b/AdminTools/src/rconclient/util/Data.java index 252cd25..0b8ac8b 100644 --- a/AdminTools/src/rconclient/util/Data.java +++ b/AdminTools/src/rconclient/util/Data.java @@ -5,6 +5,7 @@ */ package rconclient.util; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -12,6 +13,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Properties; @@ -19,6 +24,10 @@ import java.util.logging.Logger; import javafx.collections.ObservableList; import javafx.scene.Node; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import rconclient.security.Mozaic; /** * @@ -27,9 +36,11 @@ public class Data { //All the variables - static File config = new File("RconClient.properties"); - ArrayList data; - + static File config = new File("rconclient.properties"); + static File cred = new File("prop.encdat"); + private ArrayList data; + private ArrayList credentials; + //public data /** * Java arguments @@ -39,7 +50,7 @@ public class Data { * Text elements from a text flow */ public static ObservableList rconTextData = null; - + public static boolean startingUp = true; //Singleton @@ -50,6 +61,14 @@ private Data() { write(defaults); } data = read(); + if(!cred.exists()){ + try { + writeCredentials(credentialsDefaults); + } catch (IOException ex) { + + } + } + credentials = readCredentials(); } /** @@ -80,7 +99,7 @@ public static Data refresh() { * @return String representation of IP */ public String getHost() { - return data.get(0); + return credentials.get(0); } /** @@ -89,7 +108,7 @@ public String getHost() { * @return port */ public int getPort() { - return Integer.parseInt(data.get(1)); + return Integer.parseInt(credentials.get(1)); } /** @@ -98,7 +117,7 @@ public int getPort() { * @return password */ public byte[] getPassword() { - return data.get(2).getBytes(); + return credentials.get(2).getBytes(); } /** @@ -107,7 +126,7 @@ public byte[] getPassword() { * @return String of password */ public String getPasswordAsString() { - return data.get(2); + return credentials.get(2); } /** @@ -116,7 +135,7 @@ public String getPasswordAsString() { * @return Colour hex */ public String getMarkdownErrorColour() { - return data.get(3); + return data.get(0); } /** @@ -125,7 +144,7 @@ public String getMarkdownErrorColour() { * @return Colour hex */ public String getMarkdownSuccsesfullReplyColour() { - return data.get(4); + return data.get(1); } /** @@ -134,54 +153,55 @@ public String getMarkdownSuccsesfullReplyColour() { * @return Colour hex */ public String getMarkdownNoCommandResponceColour() { - return data.get(5); + return data.get(2); } /** * Gets remember property + * * @return remember property */ public boolean getRconRemember() { - return Boolean.parseBoolean(data.get(6)); + return Boolean.parseBoolean(data.get(3)); } /** - * Gets the refresh rate for mc serv querry + * Gets the refresh rate for mc serv querry + * * @return refresh rate */ public int getQuerryMcRefreshRate() { - return Integer.parseInt(data.get(7)); + return Integer.parseInt(data.get(4)); } /** * Gets refresh rate for Mojang API + * * @return refresh rate */ public double getQuerryMojangApiRefreshRate() { - return Double.parseDouble(data.get(8)); + return Double.parseDouble(data.get(5)); } /** * Default valiues for the properties */ - public static ArrayList defaults = new ArrayList<>(Arrays.asList(new String[]{"localhost", "25575", "password", "#e02b2b", "#9cfc88", "#9cfc88", "false", "10", "100"})); + public static ArrayList defaults = new ArrayList<>(Arrays.asList(new String[]{"#e02b2b", "#9cfc88", "#9cfc88", "false", "10", "100"})); /** * Writes the properties to disk + * * @param props the properties that need to be written */ public static void write(ArrayList props) { Properties prop = new Properties(); try (OutputStream output = new FileOutputStream(config)) { - prop.setProperty("rcon.host", props.get(0)); - prop.setProperty("rcon.port", props.get(1)); - prop.setProperty("rcon.password", props.get(2)); - prop.setProperty("markdown.error.colour", props.get(3)); - prop.setProperty("markdown.succsesfullreply.colour", props.get(4)); - prop.setProperty("markdown.nocommandresponce.colour", props.get(5)); - prop.setProperty("rcon.remember", props.get(6)); - prop.setProperty("querry.mc.refreshrate", props.get(7)); - prop.setProperty("querry.api.mojang.refreshrate", props.get(8)); + prop.setProperty("markdown.error.colour", props.get(0)); + prop.setProperty("markdown.succsesfullreply.colour", props.get(1)); + prop.setProperty("markdown.nocommandresponce.colour", props.get(2)); + prop.setProperty("rcon.remember", props.get(3)); + prop.setProperty("querry.mc.refreshrate", props.get(4)); + prop.setProperty("querry.api.mojang.refreshrate", props.get(5)); prop.store(output, "RconClient properties" + System.lineSeparator() + "Created by: LukeOnuke - https://github.com/LukeOnuke"); } catch (FileNotFoundException ex) { @@ -193,6 +213,7 @@ public static void write(ArrayList props) { /** * Reads the properties from disk + * * @return ArrayList of properites */ public static ArrayList read() { @@ -201,15 +222,12 @@ public static ArrayList read() { Properties prop = new Properties(); try (InputStream input = new FileInputStream(config)) { prop.load(input); - arl.add(prop.getProperty("rcon.host", defaults.get(0))); - arl.add(prop.getProperty("rcon.port", defaults.get(1))); - arl.add(prop.getProperty("rcon.password", defaults.get(2))); - arl.add(prop.getProperty("markdown.error.colour", defaults.get(3))); - arl.add(prop.getProperty("markdown.succsesfullreply.colour", defaults.get(4))); - arl.add(prop.getProperty("markdown.nocommandresponce.colour", defaults.get(5))); - arl.add(prop.getProperty("rcon.remember", defaults.get(6))); - arl.add(prop.getProperty("querry.mc.refreshrate", defaults.get(7))); - arl.add(prop.getProperty("querry.api.mojang.refreshrate", defaults.get(8))); + arl.add(prop.getProperty("markdown.error.colour", defaults.get(0))); + arl.add(prop.getProperty("markdown.succsesfullreply.colour", defaults.get(1))); + arl.add(prop.getProperty("markdown.nocommandresponce.colour", defaults.get(2))); + arl.add(prop.getProperty("rcon.remember", defaults.get(3))); + arl.add(prop.getProperty("querry.mc.refreshrate", defaults.get(4))); + arl.add(prop.getProperty("querry.api.mojang.refreshrate", defaults.get(5))); } catch (FileNotFoundException ex) { Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex); @@ -219,4 +237,42 @@ public static ArrayList read() { return arl; } + + public static ArrayList credentialsDefaults = new ArrayList<>(Arrays.asList(new String[]{"localhost", "25575", "password"})); + + public static ArrayList readCredentials() { + ArrayList cred = new ArrayList<>(); + + Properties prop = new Properties(); + try (InputStream input = new ByteArrayInputStream(Mozaic.read().getBytes());) { + prop.load(input); + cred.add(prop.getProperty("rcon.host", credentialsDefaults.get(0))); + cred.add(prop.getProperty("rcon.port", credentialsDefaults.get(1))); + cred.add(prop.getProperty("rcon.password", credentialsDefaults.get(2))); + + } catch (FileNotFoundException ex) { + Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex); + } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchPaddingException ex) { + Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex); + } + + return cred; + } + + public static void writeCredentials(ArrayList credentials) throws IOException { + Properties prop = new Properties(); + StringWriter output = new StringWriter(); + prop.setProperty("rcon.host", credentials.get(0)); + prop.setProperty("rcon.port", credentials.get(1)); + prop.setProperty("rcon.password", credentials.get(2)); + prop.store(output, "RconClient credentials" + System.lineSeparator() + "Created by: LukeOnuke - https://github.com/LukeOnuke"); + + try { + Mozaic.write(output.getBuffer().toString()); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException ex) { + Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex); + } + } } diff --git a/AdminTools/src/rconclient/util/Utill.java b/AdminTools/src/rconclient/util/Utill.java index b52db09..2747d73 100644 --- a/AdminTools/src/rconclient/util/Utill.java +++ b/AdminTools/src/rconclient/util/Utill.java @@ -6,7 +6,6 @@ package rconclient.util; import java.io.BufferedReader; -import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; @@ -27,6 +26,7 @@ public static String getDate() { /** * Gets responce of GET request sent to a url + * * @param getUrl The url of the server to witch we send the GET request * @return String of what the servers responce was to the get request * @throws IOException When there is a IO error @@ -35,7 +35,7 @@ public static String getHTTPRequest(String getUrl) throws IOException { URL obj = new URL(getUrl); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); //create HTTP connection con.setRequestMethod("GET"); //Send get request - + int responseCode = con.getResponseCode(); //responce code if (responseCode == HttpURLConnection.HTTP_OK) { // success BufferedReader in = new BufferedReader(new InputStreamReader( @@ -54,10 +54,10 @@ public static String getHTTPRequest(String getUrl) throws IOException { throw new IOException(); } } - - public static String removeSpigotFormatting(String commandReply){ + + public static String removeSpigotFormatting(String commandReply) { commandReply = commandReply.replaceAll("[ยง][1-9a-zA-Z]", ""); //remove numbers and letters - + return commandReply; } } diff --git a/AdminTools/src/rconclient/util/WindowLoader.java b/AdminTools/src/rconclient/util/WindowLoader.java index 5e0b437..6ad1410 100644 --- a/AdminTools/src/rconclient/util/WindowLoader.java +++ b/AdminTools/src/rconclient/util/WindowLoader.java @@ -33,13 +33,36 @@ public static void loadStatus(AnchorPane rootPane) { loadWindow(rootPane, "/rconclient/gui/StatusWindow.fxml"); } + public static void loadLogin(AnchorPane rootPane) { + loadWindow(rootPane, "/rconclient/gui/LoginWindow.fxml"); + } + private static void loadWindow(AnchorPane rootPane, String url) { try { AnchorPane ap = FXMLLoader.load(SettingsWindowController.class.getResource(url)); Scene scene2 = new Scene(ap); Stage windowStage = (Stage) rootPane.getScene().getWindow(); + //Get widht and height + double width = windowStage.getWidth(); + double height = windowStage.getHeight(); + windowStage.setScene(scene2); + + //Refresh title + Data d = Data.getInstance(); + String barebonesq = ""; + if (Data.arguments.length > 0) { + if (Data.arguments[0].equals("barebones")) { + barebonesq = " [Barebones mode]"; + } + } + windowStage.setTitle("Admin Tools - " + d.getHost() + ":" + d.getPort() + barebonesq); + + //Set width after scene swithch + windowStage.setWidth(width); + windowStage.setHeight(height); + windowStage.show(); } catch (IOException ex) { Logger.getLogger(RconWindowController.class.getName()).log(Level.SEVERE, null, ex);