Add support for authorized_keys files.
Each user can have a set of authorized keys for public key authentication. This is better to support as it lets us use different algorithms and not just RSA. In the age of security, it's good to have variety. I also added additional libraries to support ed25519-based public keys. I updated the SSH libraries so any upstream bug fixes are applied, fixed some warnings and a few other things.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
package com.ryanmichela.sshd;
|
||||
|
||||
import org.apache.sshd.server.Command;
|
||||
import org.apache.sshd.server.CommandFactory;
|
||||
import org.apache.sshd.server.command.Command;
|
||||
import org.apache.sshd.server.command.CommandFactory;
|
||||
import org.apache.sshd.server.channel.ChannelSession;
|
||||
import org.apache.sshd.server.Environment;
|
||||
import org.apache.sshd.server.ExitCallback;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -16,7 +17,7 @@ import java.io.OutputStream;
|
||||
public class ConsoleCommandFactory implements CommandFactory {
|
||||
|
||||
@Override
|
||||
public Command createCommand(String command) {
|
||||
public Command createCommand(ChannelSession cs, String command) {
|
||||
return new ConsoleCommand(command);
|
||||
}
|
||||
|
||||
@@ -50,7 +51,7 @@ public class ConsoleCommandFactory implements CommandFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Environment environment) throws IOException {
|
||||
public void start(ChannelSession cs, Environment environment) throws IOException {
|
||||
try {
|
||||
SshdPlugin.instance.getLogger()
|
||||
.info("[U: " + environment.getEnv().get(Environment.ENV_USER) + "] " + command);
|
||||
@@ -63,8 +64,6 @@ public class ConsoleCommandFactory implements CommandFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
public void destroy(ChannelSession cn) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
package com.ryanmichela.sshd;
|
||||
|
||||
import com.ryanmichela.sshd.ConsoleCommandCompleter;
|
||||
import com.ryanmichela.sshd.ConsoleLogFormatter;
|
||||
import com.ryanmichela.sshd.FlushyOutputStream;
|
||||
import com.ryanmichela.sshd.FlushyStreamHandler;
|
||||
import com.ryanmichela.sshd.SshTerminal;
|
||||
import com.ryanmichela.sshd.SshdPlugin;
|
||||
import com.ryanmichela.sshd.StreamHandlerAppender;
|
||||
import com.ryanmichela.sshd.implementations.SSHDCommandSender;
|
||||
import jline.console.ConsoleReader;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.core.Logger;
|
||||
import org.apache.sshd.common.Factory;
|
||||
import org.apache.sshd.server.Command;
|
||||
import org.apache.sshd.server.shell.ShellFactory;
|
||||
import org.apache.sshd.server.command.Command;
|
||||
import org.apache.sshd.server.channel.ChannelSession;
|
||||
import org.apache.sshd.server.Environment;
|
||||
import org.apache.sshd.server.ExitCallback;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -16,15 +25,11 @@ import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.StreamHandler;
|
||||
|
||||
public class ConsoleShellFactory implements Factory<Command> {
|
||||
public class ConsoleShellFactory implements ShellFactory {
|
||||
|
||||
static SSHDCommandSender sshdCommandSender = new SSHDCommandSender();
|
||||
|
||||
public Command get() {
|
||||
return this.create();
|
||||
}
|
||||
|
||||
public Command create() {
|
||||
public Command createShell(ChannelSession cs) {
|
||||
return new ConsoleShell();
|
||||
}
|
||||
|
||||
@@ -72,58 +77,76 @@ public class ConsoleShellFactory implements Factory<Command> {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void start(Environment env) throws IOException {
|
||||
try {
|
||||
consoleReader = new ConsoleReader(in, new FlushyOutputStream(out), new SshTerminal());
|
||||
consoleReader.setExpandEvents(true);
|
||||
consoleReader.addCompleter(new ConsoleCommandCompleter());
|
||||
@Override
|
||||
public void start(ChannelSession cs, Environment env) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
consoleReader = new ConsoleReader(in, new FlushyOutputStream(out), new SshTerminal());
|
||||
consoleReader.setExpandEvents(true);
|
||||
consoleReader.addCompleter(new ConsoleCommandCompleter());
|
||||
|
||||
StreamHandler streamHandler = new FlushyStreamHandler(out, new ConsoleLogFormatter(), consoleReader);
|
||||
streamHandlerAppender = new StreamHandlerAppender(streamHandler);
|
||||
StreamHandler streamHandler = new FlushyStreamHandler(out, new ConsoleLogFormatter(), consoleReader);
|
||||
streamHandlerAppender = new StreamHandlerAppender(streamHandler);
|
||||
|
||||
((Logger) LogManager.getRootLogger()).addAppender(streamHandlerAppender);
|
||||
((Logger)LogManager.getRootLogger()).addAppender(streamHandlerAppender);
|
||||
|
||||
environment = env;
|
||||
thread = new Thread(this, "SSHD ConsoleShell " + env.getEnv().get(Environment.ENV_USER));
|
||||
thread.start();
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Error starting shell", e);
|
||||
}
|
||||
environment = env;
|
||||
thread = new Thread(this, "SSHD ConsoleShell " + env.getEnv().get(Environment.ENV_USER));
|
||||
thread.start();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException("Error starting shell", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
((Logger) LogManager.getRootLogger()).removeAppender(streamHandlerAppender);
|
||||
}
|
||||
@Override
|
||||
public void destroy(ChannelSession cs) { ((Logger)LogManager.getRootLogger()).removeAppender(streamHandlerAppender); }
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!SshdPlugin.instance.getConfig().getString("mode").equals("RPC"))
|
||||
printPreamble(consoleReader);
|
||||
while (true) {
|
||||
while (true)
|
||||
{
|
||||
String command = consoleReader.readLine("\r>", null);
|
||||
if (command == null) continue;
|
||||
if (command.equals("exit") || command.equals("quit")) break;
|
||||
Bukkit.getScheduler().runTask(SshdPlugin.instance, () -> {
|
||||
if (SshdPlugin.instance.getConfig().getString("mode").equals("RPC") &&
|
||||
command.startsWith("rpc")) {
|
||||
//NO ECHO NO PREAMBLE AND SHIT
|
||||
String cmd = command.substring("rpc".length() + 1, command.length());
|
||||
Bukkit.dispatchCommand(sshdCommandSender, cmd);
|
||||
} else {
|
||||
SshdPlugin.instance.getLogger()
|
||||
.info("<" + environment.getEnv().get(Environment.ENV_USER) + "> " + command);
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||
}
|
||||
});
|
||||
if (command == null)
|
||||
continue;
|
||||
if (command.equals("exit") || command.equals("quit"))
|
||||
break;
|
||||
Bukkit.getScheduler().runTask(
|
||||
SshdPlugin.instance, () ->
|
||||
{
|
||||
if (SshdPlugin.instance.getConfig().getString("mode").equals("RPC") && command.startsWith("rpc"))
|
||||
{
|
||||
// NO ECHO NO PREAMBLE AND SHIT
|
||||
String cmd = command.substring("rpc".length() + 1, command.length());
|
||||
Bukkit.dispatchCommand(sshdCommandSender, cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
SshdPlugin.instance.getLogger().info("<" + environment.getEnv().get(Environment.ENV_USER) + "> "
|
||||
+ command);
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
SshdPlugin.instance.getLogger().log(Level.SEVERE, "Error processing command from SSH", e);
|
||||
} finally {
|
||||
}
|
||||
finally
|
||||
{
|
||||
callback.onExit(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void printPreamble(ConsoleReader consoleReader) throws IOException {
|
||||
private void printPreamble(ConsoleReader consoleReader) throws IOException
|
||||
{
|
||||
consoleReader.println(" _____ _____ _ _ _____" + "\r");
|
||||
consoleReader.println(" / ____/ ____| | | | __ \\" + "\r");
|
||||
consoleReader.println("| (___| (___ | |__| | | | |" + "\r");
|
||||
@@ -136,5 +159,5 @@ public class ConsoleShellFactory implements Factory<Command> {
|
||||
consoleReader.println("Type 'exit' to exit the shell." + "\r");
|
||||
consoleReader.println("===============================================" + "\r");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package com.ryanmichela.sshd;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.DSAPublicKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
|
||||
/**
|
||||
* Copyright 2013 Ryan Michela
|
||||
*/
|
||||
public class PemDecoder extends java.io.BufferedReader {
|
||||
|
||||
private static final String BEGIN = "^-+\\s*BEGIN.+";
|
||||
private static final String END = "^-+\\s*END.+";
|
||||
private static final String COMMENT = "Comment:";
|
||||
|
||||
public PemDecoder(Reader in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
public PublicKey getPemBytes() throws Exception {
|
||||
StringBuilder b64 = new StringBuilder();
|
||||
|
||||
String line = readLine();
|
||||
if (!line.matches(BEGIN)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (line = readLine(); line != null; line = readLine()) {
|
||||
if (!line.matches(END) && !line.startsWith(COMMENT)) {
|
||||
b64.append(line.trim());
|
||||
}
|
||||
}
|
||||
|
||||
return decodePublicKey(b64.toString());
|
||||
}
|
||||
|
||||
private byte[] bytes;
|
||||
private int pos;
|
||||
|
||||
private PublicKey decodePublicKey(String keyLine) throws Exception {
|
||||
bytes = null;
|
||||
pos = 0;
|
||||
|
||||
// look for the Base64 encoded part of the line to decode
|
||||
// both ssh-rsa and ssh-dss begin with "AAAA" due to the length bytes
|
||||
for (String part : keyLine.split(" ")) {
|
||||
if (part.startsWith("AAAA")) {
|
||||
bytes = Base64.decodeBase64(part.getBytes());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bytes == null) {
|
||||
throw new IllegalArgumentException("no Base64 part to decode");
|
||||
}
|
||||
|
||||
String type = decodeType();
|
||||
if (type.equals("ssh-rsa")) {
|
||||
BigInteger e = decodeBigInt();
|
||||
BigInteger m = decodeBigInt();
|
||||
RSAPublicKeySpec spec = new RSAPublicKeySpec(m, e);
|
||||
return KeyFactory.getInstance("RSA").generatePublic(spec);
|
||||
} else if (type.equals("ssh-dss")) {
|
||||
BigInteger p = decodeBigInt();
|
||||
BigInteger q = decodeBigInt();
|
||||
BigInteger g = decodeBigInt();
|
||||
BigInteger y = decodeBigInt();
|
||||
DSAPublicKeySpec spec = new DSAPublicKeySpec(y, p, q, g);
|
||||
return KeyFactory.getInstance("DSA").generatePublic(spec);
|
||||
} else {
|
||||
throw new IllegalArgumentException("unknown type " + type);
|
||||
}
|
||||
}
|
||||
|
||||
private String decodeType() {
|
||||
int len = decodeInt();
|
||||
String type = new String(bytes, pos, len);
|
||||
pos += len;
|
||||
return type;
|
||||
}
|
||||
|
||||
private int decodeInt() {
|
||||
return ((bytes[pos++] & 0xFF) << 24) | ((bytes[pos++] & 0xFF) << 16)
|
||||
| ((bytes[pos++] & 0xFF) << 8) | (bytes[pos++] & 0xFF);
|
||||
}
|
||||
|
||||
private BigInteger decodeBigInt() {
|
||||
int len = decodeInt();
|
||||
byte[] bigIntBytes = new byte[len];
|
||||
System.arraycopy(bytes, pos, bigIntBytes, 0, len);
|
||||
pos += len;
|
||||
return new BigInteger(bigIntBytes);
|
||||
}
|
||||
}
|
||||
@@ -1,54 +1,85 @@
|
||||
package com.ryanmichela.sshd;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
|
||||
import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
|
||||
import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
|
||||
import org.apache.sshd.server.session.ServerSession;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.io.FileReader;
|
||||
import java.security.PublicKey;
|
||||
|
||||
/**
|
||||
* Copyright 2013 Ryan Michela
|
||||
*/
|
||||
public class PublicKeyAuthenticator implements PublickeyAuthenticator {
|
||||
public class PublicKeyAuthenticator implements PublickeyAuthenticator
|
||||
{
|
||||
|
||||
private File authorizedKeysDir;
|
||||
private File authorizedKeysDir;
|
||||
|
||||
public PublicKeyAuthenticator(File authorizedKeysDir) {
|
||||
this.authorizedKeysDir = authorizedKeysDir;
|
||||
}
|
||||
public PublicKeyAuthenticator(File authorizedKeysDir) { this.authorizedKeysDir = authorizedKeysDir; }
|
||||
|
||||
@Override
|
||||
public boolean authenticate(String username, PublicKey key, ServerSession session) {
|
||||
byte[] keyBytes = key.getEncoded();
|
||||
File keyFile = new File(authorizedKeysDir, username);
|
||||
@Override public boolean authenticate(String username, PublicKey key, ServerSession session)
|
||||
{
|
||||
byte[] keyBytes = key.getEncoded();
|
||||
File keyFile = new File(authorizedKeysDir, username);
|
||||
|
||||
if (keyFile.exists()) {
|
||||
try {
|
||||
if (keyFile.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
List<AuthorizedKeyEntry> pklist = AuthorizedKeyEntry.readAuthorizedKeys(keyFile.toPath());
|
||||
|
||||
PublickeyAuthenticator auth = PublickeyAuthenticator.fromAuthorizedEntries(username, session, pklist,
|
||||
PublicKeyEntryResolver.IGNORING);
|
||||
|
||||
FileReader fr = new FileReader(keyFile);
|
||||
PemDecoder pd = new PemDecoder(fr);
|
||||
PublicKey k = pd.getPemBytes();
|
||||
pd.close();
|
||||
boolean accepted = auth.authenticate(username, key, session);
|
||||
|
||||
if (k != null) {
|
||||
if (ArrayUtils.isEquals(key.getEncoded(), k.getEncoded())) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
SshdPlugin.instance.getLogger().severe("Failed to parse PEM file. " + keyFile.getAbsolutePath());
|
||||
if (accepted)
|
||||
{
|
||||
SshdPlugin.instance.getLogger().info(
|
||||
username + " successfully authenticated via SSH session using key file " + keyFile.getAbsolutePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
SshdPlugin.instance.getLogger().info(
|
||||
username + " failed authentication via SSH session using key file " + keyFile.getAbsolutePath());
|
||||
}
|
||||
return accepted;
|
||||
/*
|
||||
|
||||
FileReader fr = new FileReader(keyFile);
|
||||
PemDecoder pd = new PemDecoder(fr);
|
||||
PublicKey k = pd.getPemBytes();
|
||||
pd.close();
|
||||
|
||||
if (k != null)
|
||||
{
|
||||
if (ArrayUtils.isEquals(key.getEncoded(), k.getEncoded()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SshdPlugin.instance.getLogger().severe("Failed to parse PEM file. " + keyFile.getAbsolutePath());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SshdPlugin.instance.getLogger()
|
||||
.severe("Failed to process public key " + keyFile.getAbsolutePath() + ". " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
SshdPlugin.instance.getLogger().warning("Could not locate public key for " + username +
|
||||
". Make sure the user's key is named the same as their user name " +
|
||||
"without a file extension.");
|
||||
}
|
||||
*/
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
SshdPlugin.instance.getLogger().severe("Failed to process public key " + keyFile.getAbsolutePath() + " " + e.getMessage());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SshdPlugin.instance.getLogger().warning("Could not locate public key for " + username
|
||||
+ ". Make sure the user's key is named the same as their user name "
|
||||
+ "without a file extension.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
|
||||
import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import com.ryanmichela.sshd.ConsoleShellFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
@@ -15,65 +17,72 @@ import java.util.logging.Level;
|
||||
/**
|
||||
* Copyright 2013 Ryan Michela
|
||||
*/
|
||||
public class SshdPlugin extends JavaPlugin {
|
||||
public
|
||||
class SshdPlugin extends JavaPlugin
|
||||
{
|
||||
|
||||
private SshServer sshd;
|
||||
public static SshdPlugin instance;
|
||||
private SshServer sshd;
|
||||
public static SshdPlugin instance;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
saveDefaultConfig();
|
||||
File authorizedKeys = new File(getDataFolder(), "authorized_keys");
|
||||
if (!authorizedKeys.exists()) {
|
||||
authorizedKeys.mkdirs();
|
||||
}
|
||||
@Override public void onLoad()
|
||||
{
|
||||
saveDefaultConfig();
|
||||
File authorizedKeys = new File(getDataFolder(), "authorized_keys");
|
||||
if (!authorizedKeys.exists())
|
||||
{
|
||||
authorizedKeys.mkdirs();
|
||||
}
|
||||
|
||||
// Don't go any lower than INFO or SSHD will cause a stack overflow exception.
|
||||
// SSHD will log that it wrote bites to the output stream, which writes
|
||||
// bytes to the output stream - ad nauseaum.
|
||||
getLogger().setLevel(Level.INFO);
|
||||
}
|
||||
// Don't go any lower than INFO or SSHD will cause a stack overflow exception.
|
||||
// SSHD will log that it wrote bites to the output stream, which writes
|
||||
// bytes to the output stream - ad nauseaum.
|
||||
getLogger().setLevel(Level.INFO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
@Override public void onEnable()
|
||||
{
|
||||
instance = this;
|
||||
|
||||
sshd = SshServer.setUpDefaultServer();
|
||||
sshd.setPort(getConfig().getInt("port", 22));
|
||||
String host = getConfig().getString("listenAddress", "all");
|
||||
sshd.setHost(host.equals("all") ? null : host);
|
||||
sshd = SshServer.setUpDefaultServer();
|
||||
sshd.setPort(getConfig().getInt("port", 22));
|
||||
String host = getConfig().getString("listenAddress", "all");
|
||||
sshd.setHost(host.equals("all") ? null : host);
|
||||
|
||||
File hostKey = new File(getDataFolder(), "hostkey");
|
||||
File authorizedKeys = new File(getDataFolder(), "authorized_keys");
|
||||
File hostKey = new File(getDataFolder(), "hostkey");
|
||||
File authorizedKeys = new File(getDataFolder(), "authorized_keys");
|
||||
|
||||
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(hostKey));
|
||||
sshd.setShellFactory(new ConsoleShellFactory());
|
||||
sshd.setPasswordAuthenticator(new ConfigPasswordAuthenticator());
|
||||
sshd.setPublickeyAuthenticator(new PublicKeyAuthenticator(authorizedKeys));
|
||||
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(hostKey.toPath()));
|
||||
sshd.setShellFactory(new ConsoleShellFactory());
|
||||
sshd.setPasswordAuthenticator(new ConfigPasswordAuthenticator());
|
||||
sshd.setPublickeyAuthenticator(new PublicKeyAuthenticator(authorizedKeys));
|
||||
|
||||
if (getConfig().getBoolean("enableSFTP")) {
|
||||
sshd.setSubsystemFactories(Collections.singletonList(new SftpSubsystemFactory()));
|
||||
sshd.setFileSystemFactory(new VirtualFileSystemFactory(
|
||||
FileSystems.getDefault().getPath(
|
||||
getDataFolder().getAbsolutePath()
|
||||
).getParent().getParent()
|
||||
));
|
||||
}
|
||||
if (getConfig().getBoolean("enableSFTP"))
|
||||
{
|
||||
sshd.setSubsystemFactories(Collections.singletonList(new SftpSubsystemFactory()));
|
||||
sshd.setFileSystemFactory(
|
||||
new VirtualFileSystemFactory(FileSystems.getDefault().getPath(getDataFolder().getAbsolutePath()).getParent().getParent()));
|
||||
}
|
||||
|
||||
sshd.setCommandFactory(new ConsoleCommandFactory());
|
||||
try {
|
||||
sshd.start();
|
||||
} catch (IOException e) {
|
||||
getLogger().log(Level.SEVERE, "Failed to start SSH server! ", e);
|
||||
}
|
||||
}
|
||||
sshd.setCommandFactory(new ConsoleCommandFactory());
|
||||
try
|
||||
{
|
||||
sshd.start();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
getLogger().log(Level.SEVERE, "Failed to start SSH server! ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
try {
|
||||
sshd.stop();
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@Override public void onDisable()
|
||||
{
|
||||
try
|
||||
{
|
||||
sshd.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.ryanmichela.sshd.implementations;
|
||||
|
||||
import com.ryanmichela.sshd.ConsoleShellFactory;
|
||||
import com.ryanmichela.sshd.SshdPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@@ -16,6 +15,8 @@ import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.ryanmichela.sshd.ConsoleShellFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
@@ -44,7 +45,7 @@ public class SSHDCommandSender implements ConsoleCommandSender, CommandSender {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "SSHD CONSOLE";
|
||||
return "Console";
|
||||
}
|
||||
|
||||
public boolean isOp() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: SSHD
|
||||
version: ${project.version}
|
||||
author: Ryan Michela, Haarolean, toxuin
|
||||
author: Ryan Michela, Haarolean, toxuin, Justin Crawford
|
||||
main: com.ryanmichela.sshd.SshdPlugin
|
||||
Reference in New Issue
Block a user