Most of the way there.

This commit is contained in:
Zachery 2019-10-09 00:19:04 -05:00
parent 047369105e
commit 1c6028199b
19 changed files with 1378 additions and 162 deletions

47
bungee/config.yml Normal file
View File

@ -0,0 +1,47 @@
forge_support: false
connection_throttle_limit: 3
timeout: 30000
online_mode: true
log_commands: false
listeners:
- query_port: 25577
motd: '&1Another Bungee server'
tab_list: GLOBAL_PING
query_enabled: false
proxy_protocol: false
forced_hosts:
pvp.md-5.net: pvp
ping_passthrough: false
priorities:
- lobby
bind_local_address: true
host: 0.0.0.0:25577
max_players: 1
tab_size: 60
force_default_server: false
connection_throttle: 4000
groups:
md_5:
- admin
log_pings: true
ip_forward: false
prevent_proxy_connections: false
network_compression_threshold: 256
disabled_commands:
- disabledcommandhere
stats: 8d157bd9-a8be-441b-8dec-fd61c19393e5
permissions:
default:
- bungeecord.command.server
- bungeecord.command.list
admin:
- bungeecord.command.alert
- bungeecord.command.end
- bungeecord.command.ip
- bungeecord.command.reload
servers:
lobby:
motd: '&1Just another BungeeCord - Forced Host'
address: localhost:25565
restricted: false
player_limit: -1

1
bungee/locations.yml Normal file
View File

@ -0,0 +1 @@
{}

8
bungee/modules.yml Normal file
View File

@ -0,0 +1,8 @@
version: 2
modules:
- jenkins://cmd_alert
- jenkins://cmd_find
- jenkins://cmd_list
- jenkins://cmd_send
- jenkins://cmd_server
- jenkins://reconnect_yaml

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDlOkUWRz4aOH8E0oX2Cx7WIqFdIK17n0aeLopLemE9xXPQnPQYKpxCXimU242GAF3c6UldRMWesrXqdyjaPOCe63NAgBpsc7v+nfDOZSYmN1OoBDTs/gDSIA/KlAK+c5W8kEQ108d0us5lmPT+KEKx8jo614jwSaKNRjPLY9G7pXcJ2u1q55wNW/6T/z//zzulo3Bvo6rFnj8hg85cFnOO/ZyiZbI72RO/ElAlP8Q+tpwRTP/JE5BR50sdf6jVuowsMw4BdTMi+U+ggRPbfOTowLoQybV8y/GM8F6+PCAi7ItZYgEYJvw3jjCl5F88hyrm5ayBo17tGKrrQ827HB0T zachery@Zachery

BIN
bungee/plugins/SSHD/hostkey Normal file

Binary file not shown.

View File

@ -0,0 +1,8 @@
§l§4 _____ _____ _ _ _____§r
§l§6 / ____/ ____| | | | __ \§r
§l§2| (___| (___ | |__| | | | |§r
§l§3 \___ \\___ \| __ | | | |§r
§l§9 ____) |___) | | | | |__| |§r
§l§5|_____/_____/|_| |_|_____/§r
===============================================

View File

@ -0,0 +1 @@
test: This configuration file works!

1212
bungee/proxy.log.0 Normal file

File diff suppressed because it is too large Load Diff

0
bungee/proxy.log.0.lck Normal file
View File

11
pom.xml
View File

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.ryanmichela</groupId>
<artifactId>sshd</artifactId>
<artifactId>sshd-bungee</artifactId>
<version>1.3.6.1</version>
<url>https://github.com/Justasic/Bukkit-SSHD/</url>
@ -101,14 +101,12 @@
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -117,16 +115,13 @@
<version>1.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-bootstrap</artifactId>
<version>1.13-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@ -6,6 +6,9 @@ import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ComponentBuilder;
import java.io.IOException;
import java.io.InputStream;
@ -56,11 +59,8 @@ public class ConsoleCommandFactory implements CommandFactory {
SshdPlugin.instance.getLogger()
.info("[U: " + environment.getEnv().get(Environment.ENV_USER) + "] " + command);
SshdPlugin.instance.getProxy().getPluginManager().dispatchCommand(SshdPlugin.instance.getProxy().getConsole(), command);
// getConsoleSender() doesn't exist in bungee, and is replaced with getConsole() from my understanding.
//SshdPlugin.instance.getProxy().getPluginManager().dispatchCommand(SshdPlugin.instance.getProxy().getConsoleSender().getInstance(), command);
//Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
if (!SshdPlugin.instance.getProxy().getPluginManager().dispatchCommand(SshdPlugin.instance.getProxy().getConsole(), command))
SshdPlugin.instance.getProxy().getConsole().sendMessage(new ComponentBuilder("Command not found").color(ChatColor.RED).create());
}
catch (Exception e)
{

View File

@ -15,12 +15,13 @@ import java.util.Map;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
public class ConsoleLogFormatter extends Formatter {
public class ConsoleLogFormatter extends Formatter
{
private SimpleDateFormat dateFormat;
private static final Map<ChatColor, String> replacements = new EnumMap<ChatColor, String>(ChatColor.class);
public ConsoleLogFormatter() {
public ConsoleLogFormatter()
{
this.dateFormat = new SimpleDateFormat("HH:mm:ss");
}

View File

@ -11,6 +11,8 @@ import com.ryanmichela.sshd.implementations.SSHDCommandSender;
import com.ryanmichela.sshd.ConsoleLogFormatter;
import jline.console.ConsoleReader;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ComponentBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Logger;
import org.apache.sshd.common.Factory;
@ -51,6 +53,7 @@ public class ConsoleShellFactory implements ShellFactory {
private String Username;
StreamHandlerAppender streamHandlerAppender;
StreamHandler streamHandler;
public ConsoleReader ConsoleReader;
public SSHDCommandSender SshdCommandSender;
@ -95,10 +98,10 @@ public class ConsoleShellFactory implements ShellFactory {
this.ConsoleReader.setExpandEvents(true);
//this.ConsoleReader.addCompleter(new ConsoleCommandCompleter());
StreamHandler streamHandler = new FlushyStreamHandler(out, new ConsoleLogFormatter(), this.ConsoleReader);
streamHandler = new FlushyStreamHandler(out, new ConsoleLogFormatter(), this.ConsoleReader);
this.streamHandlerAppender = new StreamHandlerAppender(streamHandler);
((Logger)LogManager.getRootLogger()).addAppender(this.streamHandlerAppender);
SshdPlugin.instance.getProxy().getLogger().addHandler(this.streamHandler);
this.environment = env;
this.Username = env.getEnv().get(Environment.ENV_USER);
@ -109,12 +112,13 @@ public class ConsoleShellFactory implements ShellFactory {
}
catch (Exception e)
{
e.printStackTrace();
throw new IOException("Error starting shell", e);
}
}
@Override
public void destroy(ChannelSession cs) { ((Logger)LogManager.getRootLogger()).removeAppender(this.streamHandlerAppender); }
public void destroy(ChannelSession cs) { SshdPlugin.instance.getProxy().getLogger().removeHandler(this.streamHandler); }
public void run()
{
@ -124,7 +128,7 @@ public class ConsoleShellFactory implements ShellFactory {
printPreamble(this.ConsoleReader);
while (true)
{
String command = this.ConsoleReader.readLine("\r>", null);
String command = this.ConsoleReader.readLine("\r> ", null);
// The user sent CTRL+D to close the shell, terminate the session.
if (command == null)
break;
@ -150,22 +154,23 @@ public class ConsoleShellFactory implements ShellFactory {
{
// NO ECHO NO PREAMBLE AND SHIT
String cmd = command.substring("rpc".length() + 1, command.length());
instance.getProxy().getPluginManager().dispatchCommand(this.SshdCommandSender, cmd);
//Bukkit.dispatchCommand(this.SshdCommandSender, cmd);
if (!instance.getProxy().getPluginManager().dispatchCommand(this.SshdCommandSender, cmd))
instance.getProxy().getConsole().sendMessage(new ComponentBuilder("Command not found").color(ChatColor.RED).create());
}
else
{
if (!mkpasswd)
instance.getLogger().info("<" + this.Username + "> " + command);
instance.getProxy().getPluginManager().dispatchCommand(instance.getProxy().getConsole(), command);
//Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
if (!instance.getProxy().getPluginManager().dispatchCommand(this.SshdCommandSender, command))
instance.getProxy().getConsole().sendMessage(new ComponentBuilder("Command not found").color(ChatColor.RED).create());
}
});
}
}
catch (IOException e)
{
e.printStackTrace();
instance.getLogger().log(Level.SEVERE, "Error processing command from SSH", e);
}
finally

View File

@ -2,6 +2,7 @@ package com.ryanmichela.sshd;
import jline.console.ConsoleReader;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.channel.exception.SshChannelClosedException;
import java.io.IOException;
import java.io.OutputStream;
@ -10,39 +11,50 @@ import java.util.logging.*;
/**
* Copyright 2013 Ryan Michela
*/
public class FlushyStreamHandler extends StreamHandler {
public class FlushyStreamHandler extends StreamHandler
{
private ConsoleReader reader;
public FlushyStreamHandler(OutputStream out, Formatter formatter, ConsoleReader reader) {
public FlushyStreamHandler(OutputStream out, Formatter formatter, ConsoleReader reader)
{
super(out, formatter);
this.reader = reader;
setLevel(Level.INFO);
}
@Override
public synchronized void publish(LogRecord record) {
record.setMessage(record.getMessage().replace("\n", "\n\r"));
public synchronized void publish(LogRecord record)
{
record.setMessage(record.getMessage().replace("\n", "\r\n"));
super.publish(record);
flush();
}
@Override
public synchronized void flush() {
try {
public synchronized void flush()
{
try
{
reader.print(ConsoleReader.RESET_LINE + "");
reader.flush();
super.flush();
try {
try
{
reader.drawLine();
} catch (Throwable ex) {
}
catch (Throwable ex)
{
reader.getCursorBuffer().clear();
}
reader.flush();
super.flush();
} catch (SshException ex) {
}
catch (SshChannelClosedException ex)
{
// do nothing
} catch (IOException ex) {
}
catch (IOException ex)
{
Logger.getLogger(FlushyStreamHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}

View File

@ -21,19 +21,21 @@ public class MkpasswdCommand extends Command
public void execute(CommandSender sender, String[] args)
{
ProxiedPlayer player = (ProxiedPlayer) sender;
String algoritm, password;
algoritm = args[0];
password = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
try
{
// Stupid bukkit, we have to concatenate the arguments together if they're using
// 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));
}
catch (ArrayIndexOutOfBoundsException e)
{
// ignore it.
sender.sendMessage("Invalid Syntax");
return;
}
// If they're console, allow regardless.
@ -50,6 +52,11 @@ public class MkpasswdCommand extends Command
sender.sendMessage(Cryptography.BCrypt_HashPassword(password));
else if (algoritm.equalsIgnoreCase("sha256"))
sender.sendMessage(Cryptography.SHA256_HashPassword(password));
else
{
sender.sendMessage("Invalid Syntax");
return;
}
}
}
catch (Exception e)

View File

@ -55,7 +55,6 @@ public final class SshdPlugin extends Plugin
e.printStackTrace();
}
try
{
if (!file.exists())
@ -108,7 +107,6 @@ public final class SshdPlugin extends Plugin
}
getProxy().getPluginManager().registerCommand(this, new MkpasswdCommand());
//this.getCommand("mkpasswd").setExecutor(new MkpasswdCommand());
sshd.setCommandFactory(new ConsoleCommandFactory());
try

View File

@ -5,26 +5,10 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ProxyServer;
/*
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.conversations.Conversation;
import org.bukkit.conversations.ConversationAbandonedEvent;
import org.bukkit.conversations.ManuallyAbandonedConversationCanceller;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
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;
@ -32,77 +16,91 @@ import java.util.Collection;
import java.util.Collections;
import java.util.logging.Level;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class SSHDCommandSender implements CommandSender {
private static final SSHDCommandSender instance = new SSHDCommandSender();
public final class SSHDCommandSender implements CommandSender
{
public ConsoleShellFactory.ConsoleShell console;
@Override
public void sendMessage(String message) {
ProxyServer.getInstance().getLogger().info(message);
public void sendMessage(String message)
{
if (message.indexOf('\n') != 0)
this.sendRawMessage(message);
else
Arrays.asList(message.split("\n")).forEach(this::sendMessage);
}
public void sendRawMessage(String message) {
// What the fuck does this code even do? Are we sending to one client or all of
// them?
public void sendRawMessage(String message)
{
if (this.console.ConsoleReader == null)
return;
try {
ProxyServer.getInstance().getLogger().info(message);
this.console.ConsoleReader.println(ChatColor.stripColor(message));
} catch (IOException e) {
SshdPlugin.instance.getLogger().log(Level.SEVERE, "Error sending message to SSHDCommandSender", e);
/*
try
{
this.console.ConsoleReader.println(ConsoleLogFormatter.ColorizeString(message).replace("\n", "\n\r"));
}
catch (IOException e)
{
SshdPlugin.instance.getLogger().log(Level.SEVERE, "Error sending message to SSHDCommandSender", e);
}*/
}
@Override
public void sendMessages(String... messages) {
public void sendMessages(String... messages)
{
Arrays.asList(messages).forEach(this::sendMessage);
}
@Override
public void sendMessage(BaseComponent... message) {
public void sendMessage(BaseComponent... message)
{
sendMessage(BaseComponent.toLegacyText(message));
}
@Override
public void sendMessage(BaseComponent message) {
public void sendMessage(BaseComponent message)
{
sendMessage(message.toLegacyText());
}
@Override
public String getName() {
return "CONSOLE";
public String getName()
{
return "SSHD CONSOLE";
}
@Override
public Collection<String> getGroups() {
public Collection<String> getGroups()
{
return Collections.emptySet();
}
@Override
public void addGroups(String... groups) {
public void addGroups(String... groups)
{
throw new UnsupportedOperationException("Console may not have groups");
}
@Override
public void removeGroups(String... groups) {
public void removeGroups(String... groups)
{
throw new UnsupportedOperationException("Console may not have groups");
}
@Override
public boolean hasPermission(String permission) {
public boolean hasPermission(String permission)
{
return true;
}
@Override
public void setPermission(String permission, boolean value) {
public void setPermission(String permission, boolean value)
{
throw new UnsupportedOperationException("Console has all permissions");
}
@Override
public Collection<String> getPermissions() {
public Collection<String> getPermissions()
{
return Collections.emptySet();
}
}

View File

@ -1,78 +0,0 @@
package com.ryanmichela.sshd.implementations;
import org.bukkit.Bukkit;
import org.bukkit.conversations.Conversation;
import org.bukkit.conversations.ConversationAbandonedEvent;
import org.bukkit.conversations.ManuallyAbandonedConversationCanceller;
import java.util.LinkedList;
import java.util.logging.Level;
public class SSHDConversationTracker {
private LinkedList<Conversation> conversationQueue = new LinkedList<>();
synchronized boolean beginConversation(Conversation conversation) {
if (!this.conversationQueue.contains(conversation)) {
this.conversationQueue.addLast(conversation);
if (this.conversationQueue.getFirst() == conversation) {
conversation.begin();
conversation.outputNextPrompt();
return true;
}
}
return true;
}
synchronized void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) {
if (!this.conversationQueue.isEmpty()) {
if (this.conversationQueue.getFirst() == conversation) {
conversation.abandon(details);
}
if (this.conversationQueue.contains(conversation)) {
this.conversationQueue.remove(conversation);
}
if (!this.conversationQueue.isEmpty()) {
this.conversationQueue.getFirst().outputNextPrompt();
}
}
}
public synchronized void abandonAllConversations() {
LinkedList<Conversation> oldQueue = this.conversationQueue;
this.conversationQueue = new LinkedList<>();
for (Conversation conversation : oldQueue) {
try {
conversation.abandon(new ConversationAbandonedEvent(conversation, new ManuallyAbandonedConversationCanceller()));
} catch (Throwable var5) {
Bukkit.getLogger().log(Level.SEVERE, "Unexpected exception while abandoning a conversation", var5);
}
}
}
synchronized void acceptConversationInput(String input) {
if (this.isConversing()) {
Conversation conversation = this.conversationQueue.getFirst();
try {
conversation.acceptInput(input);
} catch (Throwable var4) {
conversation.getContext().getPlugin().getLogger().log(Level.WARNING, String.format("Plugin %s generated an exception whilst handling conversation input", conversation.getContext().getPlugin().getDescription().getFullName()), var4);
}
}
}
synchronized boolean isConversing() {
return !this.conversationQueue.isEmpty();
}
public synchronized boolean isConversingModaly() {
return this.isConversing() && this.conversationQueue.getFirst().isModal();
}
}

View File

@ -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
commands:
mkpasswd: