diff --git a/README.md b/README.md index 2730233..2a3a85b 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ -Spigot-SSHD +Minecraft-SSHD =========== -[![Build Status](https://travis-ci.org/Justasic/Spigot-SSHD.svg?branch=master)](https://travis-ci.org/Justasic/Spigot-SSHD) -[![Release](https://img.shields.io/github/release/Justasic/Spigot-SSHD.svg?label=Release&maxAge=60)](https://github.com/Justasic/Spigot-SSHD/releases/latest) -[![GitHub license](https://img.shields.io/github/license/Justasic/Spigot-SSHD)](https://github.com/Justasic/Spigot-SSHD/blob/master/LICENSE) +[![Build Status](https://travis-ci.org/Justasic/Minecraft-SSHD.svg?branch=master)](https://travis-ci.org/Justasic/Minecraft-SSHD) +[![Release](https://img.shields.io/github/release/Justasic/Minecraft-SSHD.svg?label=Release&maxAge=60)](https://github.com/Justasic/Minecraft-SSHD/releases/latest) +[![GitHub license](https://img.shields.io/github/license/Justasic/Minecraft-SSHD)](https://github.com/Justasic/Minecraft-SSHD/blob/master/LICENSE) diskover
-**Have you ever wished you could remotely access your server's admin console without having to setup a complex remote access system? Now you can with SSHD.** +**Have you ever wished you could remotely access your server's admin console without having to setup a complex remote access system? Now you can with Minecraft-SSHD!** -SSHD securely exposes your BungeeCord admin console and the server filesystem using the SSH protocol - the same protocol that serves as the secure foundation for nearly all remote server administration.
+Minecraft-SSHD securely exposes your BungeeCord admin console and the server filesystem using the SSH protocol - the same protocol that serves as the secure foundation for nearly all remote server administration.
- Compatible with all ssh clients, regardless of operating system. - Remotely view your server log in real-time. @@ -20,7 +20,7 @@ SSHD securely exposes your BungeeCord admin console and the server filesystem us - Run Spigot without using screen or tmux (by adding `-noconsole`) - Remotely script your server by issuing one-off console commands with ssh. -### Why should I use SSHD? +### Why should I use Minecraft-SSHD? - You are in a shared hosting environment that only gives you access to the - log files. - You want to share access to your server console, but don't want to give anybody access to the machine its running on. @@ -93,8 +93,8 @@ mkpasswd supports the following hash algorithms: `sshd.mkpasswd` - Checks if the in-game user has access to run the mkpasswd command. -SSHD uses cryptographic certificates or a secure username and password to verify remote access. +Minecraft-SSHD uses cryptographic certificates or a secure username and password to verify remote access. ## Source Code -[Get the source on GitHub](https://github.com/Justasic/Spigot-SSHD "Source Code") +[Get the source on GitHub](https://github.com/Justasic/Minecraft-SSHD "Source Code") diff --git a/pom.xml b/pom.xml index 76fc8e8..edca522 100644 --- a/pom.xml +++ b/pom.xml @@ -6,8 +6,9 @@ com.ryanmichela sshd - 1.3.6.1 - https://github.com/Justasic/Bukkit-SSHD/ + Minecraft-SSHD: The SSH daemon for Minecraft servers. + 1.3.7 + https://github.com/Justasic/Minecraft-SSHD/ 1.8 diff --git a/src/main/java/com/ryanmichela/sshd/ConsoleLogFormatter.java b/src/main/java/com/ryanmichela/sshd/ConsoleLogFormatter.java index 629afce..f54d43d 100644 --- a/src/main/java/com/ryanmichela/sshd/ConsoleLogFormatter.java +++ b/src/main/java/com/ryanmichela/sshd/ConsoleLogFormatter.java @@ -96,7 +96,7 @@ public class ConsoleLogFormatter extends Formatter { stringbuilder.append(stringwriter.toString()); } - return stringbuilder.toString(); + return stringbuilder.toString().replace("\n", "\r\n"); } private void colorize(LogRecord logrecord) diff --git a/src/main/java/com/ryanmichela/sshd/ConsoleShellFactory.java b/src/main/java/com/ryanmichela/sshd/ConsoleShellFactory.java index d967e39..09d29b6 100644 --- a/src/main/java/com/ryanmichela/sshd/ConsoleShellFactory.java +++ b/src/main/java/com/ryanmichela/sshd/ConsoleShellFactory.java @@ -136,6 +136,8 @@ public class ConsoleShellFactory implements ShellFactory { if (command.equals("cls")) { this.ConsoleReader.clearScreen(); + this.ConsoleReader.drawLine(); + this.ConsoleReader.flush(); continue; } // Hide the mkpasswd command input from other users. @@ -152,10 +154,18 @@ public class ConsoleShellFactory implements ShellFactory { } else { + // Don't send our mkpasswd command output. This will echo passwords back + // to the console for all to see. This command is strictly between + // our plugin and the connected client. if (!mkpasswd) + { SshdPlugin.instance.getLogger().info("<" + this.Username + "> " + command); - - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + } + else + { + Bukkit.dispatchCommand(this.SshdCommandSender, command); + } } }); } diff --git a/src/main/java/com/ryanmichela/sshd/MkpasswdCommand.java b/src/main/java/com/ryanmichela/sshd/MkpasswdCommand.java index 60cdc66..f4d3408 100644 --- a/src/main/java/com/ryanmichela/sshd/MkpasswdCommand.java +++ b/src/main/java/com/ryanmichela/sshd/MkpasswdCommand.java @@ -12,9 +12,28 @@ import com.ryanmichela.sshd.SshdPlugin; class MkpasswdCommand implements CommandExecutor { - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) + // Because Spigot's failed syntax API is really less than ideal (you should be required to add a + // SendSyntax function override), we're just always going to return true even for syntax failures + // as we will handle the syntax message internally. This also lets us send the messages more + // securely to the client without people knowing we're using the command. This prevents password + // or hash leakages from the user to other connected users. Plus this syntax will show how + // to both use the command and what hashes we support which is important for people who don't + // know how to RTFM. - Justin + private void SendSyntax(CommandSender sender, boolean invalid) { + if (invalid) + sender.sendMessage("\u00A7cInvalid Syntax\u00A7r"); + sender.sendMessage("\u00A7a/mkpasswd \u00A7r"); + sender.sendMessage("\u00A79Supported Hashes: SHA256, PBKDF2, BCRYPT, PLAIN\u00A7r"); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) + { + // If we're not mkpasswd, just fuck off. + if (!label.equalsIgnoreCase("mkpasswd")) + return false; + String algoritm, password; try { @@ -22,78 +41,52 @@ class MkpasswdCommand implements CommandExecutor // spaces in their passwords otherwise it won't be as strong as it should be. algoritm = args[0]; password = String.join(" ", Arrays.copyOfRange(args, 1, args.length)); + if (password.trim().isEmpty()) // Shortcut to the catch statement below. + throw new ArrayIndexOutOfBoundsException(); } catch (ArrayIndexOutOfBoundsException e) { // ignore it. - return false; + this.SendSyntax(sender, true); + return true; } - // If they're console, allow regardless. - if (!(sender instanceof Player)) - { - if (label.equalsIgnoreCase("mkpasswd")) + boolean hasperm = (sender instanceof Player) ? ((Player)sender).hasPermission("sshd.mkpasswd") : true; + + if (hasperm) + { + try { - try + String hash = ""; + // Dumb but whatever. Some people are really dense. + if (algoritm.equalsIgnoreCase("PLAIN")) { - // Dumb but whatever. Some people are really dense. - if (algoritm.equalsIgnoreCase("PLAIN")) - { - // I mean c'mon... - sender.sendMessage("Bro really? it's literally your unencrypted password..."); - } - else if (algoritm.equalsIgnoreCase("pbkdf2")) - sender.sendMessage("Your hash: " + Cryptography.PBKDF2_HashPassword(password)); - else if (algoritm.equalsIgnoreCase("bcrypt")) - sender.sendMessage("Your hash: " + Cryptography.BCrypt_HashPassword(password)); - else if (algoritm.equalsIgnoreCase("sha256")) - sender.sendMessage("Your hash: " + Cryptography.SHA256_HashPassword(password)); - else if (algoritm.equalsIgnoreCase("help")) - sender.sendMessage("Supported hash algorithms: pbkdf2, bcrypt, sha256, plain"); - else - return false; + // I mean c'mon... + sender.sendMessage("Bro really? it's literally your unencrypted password..."); + return true; } - catch (Exception e) + else if (algoritm.equalsIgnoreCase("pbkdf2")) + hash = Cryptography.PBKDF2_HashPassword(password); + else if (algoritm.equalsIgnoreCase("bcrypt")) + hash = Cryptography.BCrypt_HashPassword(password); + else if (algoritm.equalsIgnoreCase("sha256")) + hash = Cryptography.SHA256_HashPassword(password); + else { - // We're console, just print the stack trace. - e.printStackTrace(); - return false; + this.SendSyntax(sender, !algoritm.equalsIgnoreCase("help")); + return true; } - return true; + + sender.sendMessage("\u00A79Your Hash: " + hash + "\u00A7r"); + } + catch (Exception e) + { + // We're console, just print the stack trace. + e.printStackTrace(); + sender.sendMessage("\u00A7cAn error occured. Please check console for details.\u00A7r"); } } - else - { - Player player = (Player) sender; - if (label.equalsIgnoreCase("mkpasswd")) - { - try - { - if (player.hasPermission("sshd.mkpasswd")) - { - // Dumb but whatever. Some people are really dense. - if (algoritm.equalsIgnoreCase("PLAIN")) - sender.sendMessage(password); - else if (algoritm.equalsIgnoreCase("pbkdf2")) - sender.sendMessage(Cryptography.PBKDF2_HashPassword(password)); - else if (algoritm.equalsIgnoreCase("bcrypt")) - sender.sendMessage(Cryptography.BCrypt_HashPassword(password)); - else if (algoritm.equalsIgnoreCase("sha256")) - sender.sendMessage(Cryptography.SHA256_HashPassword(password)); - else - return false; - } - } - catch (Exception e) - { - // since this is a player, send a failure message - sender.sendMessage("An error occured, please check console."); - e.printStackTrace(); - return false; - } - return true; - } - } - return false; - } + + return true; + } } \ No newline at end of file diff --git a/src/main/java/com/ryanmichela/sshd/implementations/SSHDCommandSender.java b/src/main/java/com/ryanmichela/sshd/implementations/SSHDCommandSender.java index 30b7baf..19a7cdf 100644 --- a/src/main/java/com/ryanmichela/sshd/implementations/SSHDCommandSender.java +++ b/src/main/java/com/ryanmichela/sshd/implementations/SSHDCommandSender.java @@ -16,21 +16,23 @@ import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; import com.ryanmichela.sshd.ConsoleShellFactory; +import com.ryanmichela.sshd.ConsoleLogFormatter; import java.io.IOException; import java.util.Arrays; import java.util.Set; import java.util.logging.Level; -public class SSHDCommandSender implements ConsoleCommandSender, CommandSender { - +public class SSHDCommandSender implements ConsoleCommandSender, CommandSender +{ private final PermissibleBase perm = new PermissibleBase(this); private final SSHDConversationTracker conversationTracker = new SSHDConversationTracker(); // Set by the upstream allocating function public ConsoleShellFactory.ConsoleShell console; - public void sendMessage(String message) { - this.sendRawMessage(message); + public void sendMessage(String message) + { + this.sendRawMessage(message + "\r"); } public void sendRawMessage(String message) @@ -40,7 +42,18 @@ public class SSHDCommandSender implements ConsoleCommandSender, CommandSender { return; try { - this.console.ConsoleReader.println(ChatColor.stripColor(message)); + this.console.ConsoleReader.println(ConsoleLogFormatter.ColorizeString(message).replace("\n", "\n\r")); + this.console.ConsoleReader.print(this.console.ConsoleReader.RESET_LINE + ""); + this.console.ConsoleReader.flush(); + try + { + this.console.ConsoleReader.drawLine(); + } + catch (Throwable ex) + { + this.console.ConsoleReader.getCursorBuffer().clear(); + } + this.console.ConsoleReader.flush(); } catch (IOException e) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index caf20ef..fb34c2c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: SSHD version: ${project.version} -author: Ryan Michela, Haarolean, toxuin, Justin Crawford +author: Ryan Michela, Haarolean, toxuin, Justin Crawford, Zachery Coleman main: com.ryanmichela.sshd.SshdPlugin load: STARTUP commands: