From 5a247576c49203084d77a124d8e81721de9c3bb6 Mon Sep 17 00:00:00 2001 From: Justin Crawford Date: Sat, 23 Nov 2019 21:53:58 -0800 Subject: [PATCH] Formatting --- .../java/com/ryanmichela/sshd/BCrypt.java | 107 ++++++++++++------ .../sshd/ConfigPasswordAuthenticator.java | 4 +- .../sshd/ConsoleCommandCompleter.java | 34 +++--- .../sshd/ConsoleCommandFactory.java | 40 ++++--- .../ryanmichela/sshd/ConsoleShellFactory.java | 33 ++++-- .../com/ryanmichela/sshd/Cryptography.java | 5 +- .../ryanmichela/sshd/FlushyStreamHandler.java | 32 ++++-- .../com/ryanmichela/sshd/ReflectionUtil.java | 69 +++++++---- .../com/ryanmichela/sshd/SshTerminal.java | 10 +- .../sshd/StreamHandlerAppender.java | 54 +++++---- .../java/com/ryanmichela/sshd/Waitable.java | 42 ++++--- .../implementations/SSHDCommandSender.java | 66 +++++++---- .../SSHDConversationTracker.java | 59 ++++++---- 13 files changed, 360 insertions(+), 195 deletions(-) diff --git a/src/main/java/com/ryanmichela/sshd/BCrypt.java b/src/main/java/com/ryanmichela/sshd/BCrypt.java index e4385dd..bdab25d 100644 --- a/src/main/java/com/ryanmichela/sshd/BCrypt.java +++ b/src/main/java/com/ryanmichela/sshd/BCrypt.java @@ -61,7 +61,8 @@ import java.security.SecureRandom; * @author Damien Miller * @version 0.2 */ -public class BCrypt { +public class BCrypt +{ // BCrypt parameters private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10; private static final int BCRYPT_SALT_LEN = 16; @@ -383,8 +384,8 @@ public class BCrypt { * @return base64-encoded string * @exception IllegalArgumentException if the length is invalid */ - private static String encode_base64(byte d[], int len) - throws IllegalArgumentException { + private static String encode_base64(byte d[], int len) throws IllegalArgumentException + { int off = 0; StringBuffer rs = new StringBuffer(); int c1, c2; @@ -392,19 +393,23 @@ public class BCrypt { if (len <= 0 || len > d.length) throw new IllegalArgumentException ("Invalid len"); - while (off < len) { + while (off < len) + { c1 = d[off++] & 0xff; rs.append(base64_code[(c1 >> 2) & 0x3f]); c1 = (c1 & 0x03) << 4; - if (off >= len) { + if (off >= len) + { rs.append(base64_code[c1 & 0x3f]); break; } + c2 = d[off++] & 0xff; c1 |= (c2 >> 4) & 0x0f; rs.append(base64_code[c1 & 0x3f]); c1 = (c2 & 0x0f) << 2; - if (off >= len) { + if (off >= len) + { rs.append(base64_code[c1 & 0x3f]); break; } @@ -422,9 +427,11 @@ public class BCrypt { * @param x the base64-encoded value * @return the decoded value of x */ - private static byte char64(char x) { + private static byte char64(char x) + { if ((int)x < 0 || (int)x > index_64.length) return -1; + return index_64[(int)x]; } @@ -437,8 +444,8 @@ public class BCrypt { * @return an array containing the decoded bytes * @throws IllegalArgumentException if maxolen is invalid */ - private static byte[] decode_base64(String s, int maxolen) - throws IllegalArgumentException { + private static byte[] decode_base64(String s, int maxolen) throws IllegalArgumentException + { StringBuffer rs = new StringBuffer(); int off = 0, slen = s.length(), olen = 0; byte ret[]; @@ -447,7 +454,8 @@ public class BCrypt { if (maxolen <= 0) throw new IllegalArgumentException ("Invalid maxolen"); - while (off < slen - 1 && olen < maxolen) { + while (off < slen - 1 && olen < maxolen) + { c1 = char64(s.charAt(off++)); c2 = char64(s.charAt(off++)); if (c1 == -1 || c2 == -1) @@ -475,6 +483,7 @@ public class BCrypt { ret = new byte[olen]; for (off = 0; off < olen; off++) ret[off] = (byte)rs.charAt(off); + return ret; } @@ -484,11 +493,13 @@ public class BCrypt { * @param lr an array containing the two 32-bit half blocks * @param off the position in the array of the blocks */ - private final void encipher(int lr[], int off) { + private final void encipher(int lr[], int off) + { int i, n, l = lr[off], r = lr[off + 1]; l ^= P[0]; - for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) { + for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) + { // Feistel substitution on left word n = S[(l >> 24) & 0xff]; n += S[0x100 | ((l >> 16) & 0xff)]; @@ -514,12 +525,14 @@ public class BCrypt { * current offset into data * @return the next word of material from data */ - private static int streamtoword(byte data[], int offp[]) { + private static int streamtoword(byte data[], int offp[]) + { int i; int word = 0; int off = offp[0]; - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) + { word = (word << 8) | (data[off] & 0xff); off = (off + 1) % data.length; } @@ -531,7 +544,8 @@ public class BCrypt { /** * Initialise the Blowfish key schedule */ - private void init_key() { + private void init_key() + { P = (int[])P_orig.clone(); S = (int[])S_orig.clone(); } @@ -540,7 +554,8 @@ public class BCrypt { * Key the Blowfish cipher * @param key an array containing the key */ - private void key(byte key[]) { + private void key(byte key[]) + { int i; int koffp[] = { 0 }; int lr[] = { 0, 0 }; @@ -549,13 +564,15 @@ public class BCrypt { for (i = 0; i < plen; i++) P[i] = P[i] ^ streamtoword(key, koffp); - for (i = 0; i < plen; i += 2) { + for (i = 0; i < plen; i += 2) + { encipher(lr, 0); P[i] = lr[0]; P[i + 1] = lr[1]; } - for (i = 0; i < slen; i += 2) { + for (i = 0; i < slen; i += 2) + { encipher(lr, 0); S[i] = lr[0]; S[i + 1] = lr[1]; @@ -569,7 +586,8 @@ public class BCrypt { * @param data salt information * @param key password information */ - private void ekskey(byte data[], byte key[]) { + private void ekskey(byte data[], byte key[]) + { int i; int koffp[] = { 0 }, doffp[] = { 0 }; int lr[] = { 0, 0 }; @@ -578,7 +596,8 @@ public class BCrypt { for (i = 0; i < plen; i++) P[i] = P[i] ^ streamtoword(key, koffp); - for (i = 0; i < plen; i += 2) { + for (i = 0; i < plen; i += 2) + { lr[0] ^= streamtoword(data, doffp); lr[1] ^= streamtoword(data, doffp); encipher(lr, 0); @@ -586,7 +605,8 @@ public class BCrypt { P[i + 1] = lr[1]; } - for (i = 0; i < slen; i += 2) { + for (i = 0; i < slen; i += 2) + { lr[0] ^= streamtoword(data, doffp); lr[1] ^= streamtoword(data, doffp); encipher(lr, 0); @@ -604,7 +624,8 @@ public class BCrypt { * of rounds of hashing to apply * @return an array containing the binary hashed password */ - private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) { + private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) + { int rounds, i, j; int cdata[] = (int[])bf_crypt_ciphertext.clone(); int clen = cdata.length; @@ -612,24 +633,28 @@ public class BCrypt { if (log_rounds < 4 || log_rounds > 31) throw new IllegalArgumentException ("Bad number of rounds"); + rounds = 1 << log_rounds; if (salt.length != BCRYPT_SALT_LEN) throw new IllegalArgumentException ("Bad salt length"); init_key(); ekskey(salt, password); - for (i = 0; i < rounds; i++) { + for (i = 0; i < rounds; i++) + { key(password); key(salt); } - for (i = 0; i < 64; i++) { + for (i = 0; i < 64; i++) + { for (j = 0; j < (clen >> 1); j++) encipher(cdata, j << 1); } ret = new byte[clen * 4]; - for (i = 0, j = 0; i < clen; i++) { + for (i = 0, j = 0; i < clen; i++) + { ret[j++] = (byte)((cdata[i] >> 24) & 0xff); ret[j++] = (byte)((cdata[i] >> 16) & 0xff); ret[j++] = (byte)((cdata[i] >> 8) & 0xff); @@ -645,7 +670,8 @@ public class BCrypt { * using BCrypt.gensalt) * @return the hashed password */ - public static String hashpw(String password, String salt) { + public static String hashpw(String password, String salt) + { BCrypt B; String real_salt; byte passwordb[], saltb[], hashed[]; @@ -655,9 +681,11 @@ public class BCrypt { if (salt.charAt(0) != '$' || salt.charAt(1) != '2') throw new IllegalArgumentException ("Invalid salt version"); + if (salt.charAt(2) == '$') off = 3; - else { + else + { minor = salt.charAt(2); if (minor != 'a' || salt.charAt(3) != '$') throw new IllegalArgumentException ("Invalid salt revision"); @@ -670,9 +698,12 @@ public class BCrypt { rounds = Integer.parseInt(salt.substring(off, off + 2)); real_salt = salt.substring(off + 3, off + 25); - try { + try + { passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8"); - } catch (UnsupportedEncodingException uee) { + } + catch (UnsupportedEncodingException uee) + { throw new AssertionError("UTF-8 is not supported"); } @@ -684,14 +715,17 @@ public class BCrypt { rs.append("$2"); if (minor >= 'a') rs.append(minor); + rs.append("$"); if (rounds < 10) rs.append("0"); + rs.append(Integer.toString(rounds)); rs.append("$"); rs.append(encode_base64(saltb, saltb.length)); rs.append(encode_base64(hashed, - bf_crypt_ciphertext.length * 4 - 1)); + bf_crypt_ciphertext.length * 4 - 1)); + return rs.toString(); } @@ -703,7 +737,8 @@ public class BCrypt { * @param random an instance of SecureRandom to use * @return an encoded salt value */ - public static String gensalt(int log_rounds, SecureRandom random) { + public static String gensalt(int log_rounds, SecureRandom random) + { StringBuffer rs = new StringBuffer(); byte rnd[] = new byte[BCRYPT_SALT_LEN]; @@ -712,6 +747,7 @@ public class BCrypt { rs.append("$2a$"); if (log_rounds < 10) rs.append("0"); + rs.append(Integer.toString(log_rounds)); rs.append("$"); rs.append(encode_base64(rnd, rnd.length)); @@ -725,7 +761,8 @@ public class BCrypt { * 2**log_rounds. * @return an encoded salt value */ - public static String gensalt(int log_rounds) { + public static String gensalt(int log_rounds) + { return gensalt(log_rounds, new SecureRandom()); } @@ -735,7 +772,8 @@ public class BCrypt { * rounds to apply * @return an encoded salt value */ - public static String gensalt() { + public static String gensalt() + { return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS); } @@ -746,7 +784,8 @@ public class BCrypt { * @param hashed the previously-hashed password * @return true if the passwords match, false otherwise */ - public static boolean checkpw(String plaintext, String hashed) { + public static boolean checkpw(String plaintext, String hashed) + { return (hashed.compareTo(hashpw(plaintext, hashed)) == 0); } } \ No newline at end of file diff --git a/src/main/java/com/ryanmichela/sshd/ConfigPasswordAuthenticator.java b/src/main/java/com/ryanmichela/sshd/ConfigPasswordAuthenticator.java index 51566d6..74d8753 100644 --- a/src/main/java/com/ryanmichela/sshd/ConfigPasswordAuthenticator.java +++ b/src/main/java/com/ryanmichela/sshd/ConfigPasswordAuthenticator.java @@ -11,8 +11,8 @@ import java.util.Map; /** * Copyright 2013 Ryan Michela */ -public class ConfigPasswordAuthenticator implements PasswordAuthenticator { - +public class ConfigPasswordAuthenticator implements PasswordAuthenticator +{ private Map FailCounts = new HashMap(); @Override diff --git a/src/main/java/com/ryanmichela/sshd/ConsoleCommandCompleter.java b/src/main/java/com/ryanmichela/sshd/ConsoleCommandCompleter.java index 182a235..0d74b18 100644 --- a/src/main/java/com/ryanmichela/sshd/ConsoleCommandCompleter.java +++ b/src/main/java/com/ryanmichela/sshd/ConsoleCommandCompleter.java @@ -12,33 +12,41 @@ import java.util.List; import java.util.concurrent.ExecutionException; import java.util.logging.Level; -public class ConsoleCommandCompleter implements Completer { - - public int complete(final String buffer, final int cursor, final List candidates) { - Waitable> waitable = new Waitable>() { +public class ConsoleCommandCompleter implements Completer +{ + public int complete(final String buffer, final int cursor, final List candidates) + { + Waitable> waitable = new Waitable>() + { @Override - protected List evaluate() { + protected List evaluate() + { CommandMap commandMap = ReflectionUtil.getProtectedValue(Bukkit.getServer(), "commandMap"); return commandMap.tabComplete(Bukkit.getServer().getConsoleSender(), buffer); } }; + Bukkit.getScheduler().runTask(SshdPlugin.instance, waitable); - try { + try + { List offers = waitable.get(); - if (offers == null) { + if (offers == null) return cursor; - } + candidates.addAll(offers); final int lastSpace = buffer.lastIndexOf(' '); - if (lastSpace == -1) { + if (lastSpace == -1) return cursor - buffer.length(); - } else { + else return cursor - (buffer.length() - lastSpace - 1); - } - } catch (ExecutionException e) { + } + catch (ExecutionException e) + { SshdPlugin.instance.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e); - } catch (InterruptedException e) { + } + catch (InterruptedException e) + { Thread.currentThread().interrupt(); } return cursor; diff --git a/src/main/java/com/ryanmichela/sshd/ConsoleCommandFactory.java b/src/main/java/com/ryanmichela/sshd/ConsoleCommandFactory.java index 10c56e7..58e2658 100644 --- a/src/main/java/com/ryanmichela/sshd/ConsoleCommandFactory.java +++ b/src/main/java/com/ryanmichela/sshd/ConsoleCommandFactory.java @@ -14,51 +14,63 @@ import java.io.OutputStream; /** * Copyright 2013 Ryan Michela */ -public class ConsoleCommandFactory implements CommandFactory { +public class ConsoleCommandFactory implements CommandFactory +{ @Override - public Command createCommand(ChannelSession cs, String command) { + public Command createCommand(ChannelSession cs, String command) + { return new ConsoleCommand(command); } - public class ConsoleCommand implements Command { - + public class ConsoleCommand implements Command + { private String command; - private InputStream in; private OutputStream out; private OutputStream err; private ExitCallback callback; - public ConsoleCommand(String command) { + public ConsoleCommand(String command) + { this.command = command; } - public void setInputStream(InputStream in) { + public void setInputStream(InputStream in) + { this.in = in; } - public void setOutputStream(OutputStream out) { + public void setOutputStream(OutputStream out) + { this.out = out; } - public void setErrorStream(OutputStream err) { + public void setErrorStream(OutputStream err) + { this.err = err; } - public void setExitCallback(ExitCallback callback) { + public void setExitCallback(ExitCallback callback) + { this.callback = callback; } @Override - public void start(ChannelSession cs, Environment environment) throws IOException { - try { + public void start(ChannelSession cs, Environment environment) throws IOException + { + try + { SshdPlugin.instance.getLogger() .info("[U: " + environment.getEnv().get(Environment.ENV_USER) + "] " + command); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); - } catch (Exception e) { + } + catch (Exception e) + { SshdPlugin.instance.getLogger().severe("Error processing command from SSH -" + e.getMessage()); - } finally { + } + finally + { callback.onExit(0); } } diff --git a/src/main/java/com/ryanmichela/sshd/ConsoleShellFactory.java b/src/main/java/com/ryanmichela/sshd/ConsoleShellFactory.java index 09d29b6..987cf19 100644 --- a/src/main/java/com/ryanmichela/sshd/ConsoleShellFactory.java +++ b/src/main/java/com/ryanmichela/sshd/ConsoleShellFactory.java @@ -32,13 +32,16 @@ import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.StreamHandler; -public class ConsoleShellFactory implements ShellFactory { +public class ConsoleShellFactory implements ShellFactory +{ - public Command createShell(ChannelSession cs) { + public Command createShell(ChannelSession cs) + { return new ConsoleShell(); } - public class ConsoleShell implements Command, Runnable { + public class ConsoleShell implements Command, Runnable + { private InputStream in; private OutputStream out; @@ -52,35 +55,43 @@ public class ConsoleShellFactory implements ShellFactory { public ConsoleReader ConsoleReader; public SSHDCommandSender SshdCommandSender; - public InputStream getIn() { + public InputStream getIn() + { return in; } - public OutputStream getOut() { + public OutputStream getOut() + { return out; } - public OutputStream getErr() { + public OutputStream getErr() + { return err; } - public Environment getEnvironment() { + public Environment getEnvironment() + { return environment; } - public void setInputStream(InputStream in) { + public void setInputStream(InputStream in) + { this.in = in; } - public void setOutputStream(OutputStream out) { + public void setOutputStream(OutputStream out) + { this.out = out; } - public void setErrorStream(OutputStream err) { + public void setErrorStream(OutputStream err) + { this.err = err; } - public void setExitCallback(ExitCallback callback) { + public void setExitCallback(ExitCallback callback) + { this.callback = callback; } diff --git a/src/main/java/com/ryanmichela/sshd/Cryptography.java b/src/main/java/com/ryanmichela/sshd/Cryptography.java index a1f5372..1366db4 100644 --- a/src/main/java/com/ryanmichela/sshd/Cryptography.java +++ b/src/main/java/com/ryanmichela/sshd/Cryptography.java @@ -140,10 +140,10 @@ class Cryptography private static byte[] FromHex(String hex) throws NoSuchAlgorithmException { byte[] bytes = new byte[hex.length() / 2]; + for (int i = 0; i < bytes.length; i++) - { bytes[i] = (byte)Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); - } + return bytes; } @@ -152,6 +152,7 @@ class Cryptography BigInteger bi = new BigInteger(1, array); String hex = bi.toString(16); int paddingLength = (array.length * 2) - hex.length(); + if (paddingLength > 0) return String.format("%0" + paddingLength + "d", 0) + hex; else diff --git a/src/main/java/com/ryanmichela/sshd/FlushyStreamHandler.java b/src/main/java/com/ryanmichela/sshd/FlushyStreamHandler.java index 10c042c..192dcc8 100644 --- a/src/main/java/com/ryanmichela/sshd/FlushyStreamHandler.java +++ b/src/main/java/com/ryanmichela/sshd/FlushyStreamHandler.java @@ -10,39 +10,51 @@ 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) { + public synchronized void publish(LogRecord record) + { record.setMessage(record.getMessage().replace("\n", "\n\r")); 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 (SshException ex) + { // do nothing - } catch (IOException ex) { + } + catch (IOException ex) + { Logger.getLogger(FlushyStreamHandler.class.getName()).log(Level.SEVERE, null, ex); } } diff --git a/src/main/java/com/ryanmichela/sshd/ReflectionUtil.java b/src/main/java/com/ryanmichela/sshd/ReflectionUtil.java index 3d8d2d1..0d395c1 100644 --- a/src/main/java/com/ryanmichela/sshd/ReflectionUtil.java +++ b/src/main/java/com/ryanmichela/sshd/ReflectionUtil.java @@ -9,16 +9,20 @@ import java.lang.reflect.Modifier; */ public class ReflectionUtil { - public static void setProtectedValue(Object o, String field, Object newValue) { + public static void setProtectedValue(Object o, String field, Object newValue) + { setProtectedValue(o.getClass(), o, field, newValue); } - public static void setProtectedValue(Class c, String field, Object newValue) { + public static void setProtectedValue(Class c, String field, Object newValue) + { setProtectedValue(c, null, field, newValue); } - public static void setProtectedValue(Class c, Object o, String field, Object newValue) { - try { + public static void setProtectedValue(Class c, Object o, String field, Object newValue) + { + try + { Field f = c.getDeclaredField(field); @@ -29,18 +33,25 @@ public class ReflectionUtil { modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL); f.set(o, newValue); - } catch (NoSuchFieldException | IllegalAccessException ex) { + } + catch (NoSuchFieldException | IllegalAccessException ex) + { System.out.println("*** " + c.getName() + ":" + ex); } } - public static T getProtectedValue(Object obj, String fieldName) { - try { + public static T getProtectedValue(Object obj, String fieldName) + { + try + { Class c = obj.getClass(); - while (c != Object.class) { + while (c != Object.class) + { Field[] fields = c.getDeclaredFields(); - for (Field f : fields) { - if (f.getName() == fieldName) { + for (Field f : fields) + { + if (f.getName() == fieldName) + { f.setAccessible(true); return (T) f.get(obj); } @@ -49,46 +60,58 @@ public class ReflectionUtil { } System.out.println("*** " + obj.getClass().getName() + ":No such field"); return null; - } catch (Exception ex) { + } + catch (Exception ex) + { System.out.println("*** " + obj.getClass().getName() + ":" + ex); return null; } } - public static T getProtectedValue(Class c, String field) { - try { + public static T getProtectedValue(Class c, String field) + { + try + { Field f = c.getDeclaredField(field); f.setAccessible(true); return (T) f.get(c); - } catch (Exception ex) { + } + catch (Exception ex) + { System.out.println("*** " + c.getName() + ":" + ex); return null; } } - public static Object invokeProtectedMethod(Class c, String method, Object... args) { + public static Object invokeProtectedMethod(Class c, String method, Object... args) + { return invokeProtectedMethod(c, null, method, args); } - public static Object invokeProtectedMethod(Object o, String method, Object... args) { + public static Object invokeProtectedMethod(Object o, String method, Object... args) + { return invokeProtectedMethod(o.getClass(), o, method, args); } - public static Object invokeProtectedMethod(Class c, Object o, String method, Object... args) { - try { + public static Object invokeProtectedMethod(Class c, Object o, String method, Object... args) + { + try + { Class[] pTypes = new Class[args.length]; - for (int i = 0; i < args.length; i++) { - if (args[i] instanceof Integer) { + for (int i = 0; i < args.length; i++) + { + if (args[i] instanceof Integer) pTypes[i] = int.class; - } else { + else pTypes[i] = args[i].getClass(); - } } Method m = c.getDeclaredMethod(method, pTypes); m.setAccessible(true); return m.invoke(o, args); - } catch (Exception ex) { + } + catch (Exception ex) + { System.out.println("*** " + c.getName() + "." + method + "(): " + ex); return null; } diff --git a/src/main/java/com/ryanmichela/sshd/SshTerminal.java b/src/main/java/com/ryanmichela/sshd/SshTerminal.java index 876f1c4..a9b765d 100644 --- a/src/main/java/com/ryanmichela/sshd/SshTerminal.java +++ b/src/main/java/com/ryanmichela/sshd/SshTerminal.java @@ -5,14 +5,16 @@ import jline.TerminalSupport; /** * Copyright 2013 Ryan Michela */ -public class SshTerminal extends TerminalSupport { - - protected SshTerminal() { +public class SshTerminal extends TerminalSupport +{ + protected SshTerminal() + { super(true); } @Override - public void init() throws Exception { + public void init() throws Exception + { setAnsiSupported(true); setEchoEnabled(true); } diff --git a/src/main/java/com/ryanmichela/sshd/StreamHandlerAppender.java b/src/main/java/com/ryanmichela/sshd/StreamHandlerAppender.java index 1af7efe..c79ccd0 100644 --- a/src/main/java/com/ryanmichela/sshd/StreamHandlerAppender.java +++ b/src/main/java/com/ryanmichela/sshd/StreamHandlerAppender.java @@ -13,80 +13,88 @@ import java.util.logging.StreamHandler; /** * Copyright 2014 Ryan Michela */ -public class StreamHandlerAppender implements Appender { +public class StreamHandlerAppender implements Appender +{ private StreamHandler streamHandler; private UUID uuid; - public StreamHandlerAppender(StreamHandler streamHandler) { + public StreamHandlerAppender(StreamHandler streamHandler) + { this.streamHandler = streamHandler; uuid = UUID.randomUUID(); } @Override - public void append(LogEvent logEvent) { + public void append(LogEvent logEvent) + { java.util.logging.Level level; - if (logEvent.getLevel().equals(org.apache.logging.log4j.Level.DEBUG)) { + if (logEvent.getLevel().equals(org.apache.logging.log4j.Level.DEBUG)) level = java.util.logging.Level.FINE; - } else if (logEvent.getLevel().equals(org.apache.logging.log4j.Level.INFO)) { + else if (logEvent.getLevel().equals(org.apache.logging.log4j.Level.INFO)) level = java.util.logging.Level.INFO; - } else if (logEvent.getLevel().equals(org.apache.logging.log4j.Level.WARN)) { + else if (logEvent.getLevel().equals(org.apache.logging.log4j.Level.WARN)) level = java.util.logging.Level.WARNING; - } else if (logEvent.getLevel().equals(org.apache.logging.log4j.Level.ERROR)) { + else if (logEvent.getLevel().equals(org.apache.logging.log4j.Level.ERROR)) level = java.util.logging.Level.SEVERE; - } else { + else level = java.util.logging.Level.INFO; - } + + String message = logEvent.getMessage().getFormattedMessage(); - - LogRecord logRecord = new LogRecord(level, message); streamHandler.publish(logRecord); } @Override - public String getName() { + public String getName() + { return "StreamHandlerAppender:" + uuid.toString(); } @Override - public Layout getLayout() { + public Layout getLayout() + { return null; } @Override - public boolean ignoreExceptions() { + public boolean ignoreExceptions() + { return false; } @Override - public ErrorHandler getHandler() { + public ErrorHandler getHandler() + { return null; } @Override - public void setHandler(ErrorHandler errorHandler) { - + public void setHandler(ErrorHandler errorHandler) + { } @Override - public void start() { - + public void start() + { } @Override - public void stop() { - + public void stop() + { } @Override - public boolean isStarted() { + public boolean isStarted() + { return true; } @Override - public boolean isStopped() { + public boolean isStopped() + { return false; } } diff --git a/src/main/java/com/ryanmichela/sshd/Waitable.java b/src/main/java/com/ryanmichela/sshd/Waitable.java index f34444e..43ce6d5 100644 --- a/src/main/java/com/ryanmichela/sshd/Waitable.java +++ b/src/main/java/com/ryanmichela/sshd/Waitable.java @@ -5,9 +5,11 @@ import java.util.concurrent.ExecutionException; /** * Copyright 2013 Ryan Michela */ -public abstract class Waitable implements Runnable { +public abstract class Waitable implements Runnable +{ - private enum Status { + private enum Status + { WAITING, RUNNING, FINISHED, @@ -17,19 +19,28 @@ public abstract class Waitable implements Runnable { T value = null; Status status = Status.WAITING; - public final void run() { - synchronized (this) { - if (status != Status.WAITING) { + public final void run() + { + synchronized (this) + { + if (status != Status.WAITING) throw new IllegalStateException("Invalid state " + status); - } + status = Status.RUNNING; } - try { + + try + { value = evaluate(); - } catch (Throwable t) { + } + catch (Throwable t) + { this.t = t; - } finally { - synchronized (this) { + } + finally + { + synchronized (this) + { status = Status.FINISHED; this.notifyAll(); } @@ -38,13 +49,14 @@ public abstract class Waitable implements Runnable { protected abstract T evaluate(); - public synchronized T get() throws InterruptedException, ExecutionException { - while (status != Status.FINISHED) { + public synchronized T get() throws InterruptedException, ExecutionException + { + while (status != Status.FINISHED) this.wait(); - } - if (t != null) { + + if (t != null) throw new ExecutionException(t); - } + return value; } } diff --git a/src/main/java/com/ryanmichela/sshd/implementations/SSHDCommandSender.java b/src/main/java/com/ryanmichela/sshd/implementations/SSHDCommandSender.java index 19a7cdf..29ce605 100644 --- a/src/main/java/com/ryanmichela/sshd/implementations/SSHDCommandSender.java +++ b/src/main/java/com/ryanmichela/sshd/implementations/SSHDCommandSender.java @@ -61,91 +61,113 @@ public class SSHDCommandSender implements ConsoleCommandSender, CommandSender } } - public void sendMessage(String[] messages) { + public void sendMessage(String[] messages) + { Arrays.asList(messages).forEach(this::sendMessage); } - public String getName() { + public String getName() + { return "SSHD Console"; } - public boolean isOp() { + public boolean isOp() + { return true; } - public void setOp(boolean value) { + public void setOp(boolean value) + { throw new UnsupportedOperationException("Cannot change operator status of server console"); } - public boolean beginConversation(Conversation conversation) { + public boolean beginConversation(Conversation conversation) + { return this.conversationTracker.beginConversation(conversation); } - public void abandonConversation(Conversation conversation) { + public void abandonConversation(Conversation conversation) + { this.conversationTracker.abandonConversation(conversation, new ConversationAbandonedEvent(conversation, new ManuallyAbandonedConversationCanceller())); } - public void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) { + public void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) + { this.conversationTracker.abandonConversation(conversation, details); } - public void acceptConversationInput(String input) { + public void acceptConversationInput(String input) + { this.conversationTracker.acceptConversationInput(input); } - public boolean isConversing() { + public boolean isConversing() + { return this.conversationTracker.isConversing(); } - public boolean isPermissionSet(String name) { + public boolean isPermissionSet(String name) + { return this.perm.isPermissionSet(name); } - public boolean isPermissionSet(Permission perm) { + public boolean isPermissionSet(Permission perm) + { return this.perm.isPermissionSet(perm); } - public boolean hasPermission(String name) { + public boolean hasPermission(String name) + { return this.perm.hasPermission(name); } - public boolean hasPermission(Permission perm) { + public boolean hasPermission(Permission perm) + { return this.perm.hasPermission(perm); } - public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) + { return this.perm.addAttachment(plugin, name, value); } - public PermissionAttachment addAttachment(Plugin plugin) { + public PermissionAttachment addAttachment(Plugin plugin) + { return this.perm.addAttachment(plugin); } - public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) + { return this.perm.addAttachment(plugin, name, value, ticks); } - public PermissionAttachment addAttachment(Plugin plugin, int ticks) { + public PermissionAttachment addAttachment(Plugin plugin, int ticks) + { return this.perm.addAttachment(plugin, ticks); } - public void removeAttachment(PermissionAttachment attachment) { + public void removeAttachment(PermissionAttachment attachment) + { this.perm.removeAttachment(attachment); } - public void recalculatePermissions() { + public void recalculatePermissions() + { this.perm.recalculatePermissions(); } - public Set getEffectivePermissions() { + public Set getEffectivePermissions() + { return this.perm.getEffectivePermissions(); } - public boolean isPlayer() { + public boolean isPlayer() + { return false; } - public Server getServer() { + public Server getServer() + { return Bukkit.getServer(); } diff --git a/src/main/java/com/ryanmichela/sshd/implementations/SSHDConversationTracker.java b/src/main/java/com/ryanmichela/sshd/implementations/SSHDConversationTracker.java index 5b9bb4f..9dd39af 100644 --- a/src/main/java/com/ryanmichela/sshd/implementations/SSHDConversationTracker.java +++ b/src/main/java/com/ryanmichela/sshd/implementations/SSHDConversationTracker.java @@ -8,13 +8,17 @@ import org.bukkit.conversations.ManuallyAbandonedConversationCanceller; import java.util.LinkedList; import java.util.logging.Level; -public class SSHDConversationTracker { +public class SSHDConversationTracker +{ private LinkedList conversationQueue = new LinkedList<>(); - synchronized boolean beginConversation(Conversation conversation) { - if (!this.conversationQueue.contains(conversation)) { + synchronized boolean beginConversation(Conversation conversation) + { + if (!this.conversationQueue.contains(conversation)) + { this.conversationQueue.addLast(conversation); - if (this.conversationQueue.getFirst() == conversation) { + if (this.conversationQueue.getFirst() == conversation) + { conversation.begin(); conversation.outputNextPrompt(); return true; @@ -24,55 +28,66 @@ public class SSHDConversationTracker { return true; } - synchronized void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) { - if (!this.conversationQueue.isEmpty()) { - if (this.conversationQueue.getFirst() == conversation) { + synchronized void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) + { + if (!this.conversationQueue.isEmpty()) + { + if (this.conversationQueue.getFirst() == conversation) conversation.abandon(details); - } - if (this.conversationQueue.contains(conversation)) { + if (this.conversationQueue.contains(conversation)) this.conversationQueue.remove(conversation); - } - if (!this.conversationQueue.isEmpty()) { + if (!this.conversationQueue.isEmpty()) this.conversationQueue.getFirst().outputNextPrompt(); - } } } - public synchronized void abandonAllConversations() { + public synchronized void abandonAllConversations() + { LinkedList oldQueue = this.conversationQueue; this.conversationQueue = new LinkedList<>(); - for (Conversation conversation : oldQueue) { - try { + for (Conversation conversation : oldQueue) + { + try + { conversation.abandon(new ConversationAbandonedEvent(conversation, new ManuallyAbandonedConversationCanceller())); - } catch (Throwable var5) { + } + catch (Throwable var5) + { Bukkit.getLogger().log(Level.SEVERE, "Unexpected exception while abandoning a conversation", var5); } } } - synchronized void acceptConversationInput(String input) { - if (this.isConversing()) { + synchronized void acceptConversationInput(String input) + { + if (this.isConversing()) + { Conversation conversation = this.conversationQueue.getFirst(); - try { + try + { conversation.acceptInput(input); - } catch (Throwable var4) { + } + 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() { + synchronized boolean isConversing() + { return !this.conversationQueue.isEmpty(); } - public synchronized boolean isConversingModaly() { + public synchronized boolean isConversingModaly() + { return this.isConversing() && this.conversationQueue.getFirst().isModal(); } }