-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
1,284 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,6 @@ | |
*.jar | ||
*.war | ||
*.ear | ||
.idea | ||
*.iml | ||
target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>com.ryanmichela</groupId> | ||
<artifactId>SSHD</artifactId> | ||
<version>1.0</version> | ||
<url>http://dev.bukkit.org/server-mods/sshd/</url> | ||
|
||
<!-- Repositories --> | ||
<repositories> | ||
<repository> | ||
<id>bukkit-repo</id> | ||
<url>http://repo.bukkit.org/content/groups/public/</url> | ||
</repository> | ||
</repositories> | ||
|
||
<!-- License --> | ||
<licenses> | ||
<license> | ||
<name>GPL2</name> | ||
<url>http://www.gnu.org/licenses/gpl-2.0.html</url> | ||
</license> | ||
</licenses> | ||
|
||
<!-- Dependencies --> | ||
<dependencies> | ||
<dependency> | ||
<groupId>org.bukkit</groupId> | ||
<artifactId>craftbukkit</artifactId> | ||
<version>1.6.4-R1.0</version> | ||
<scope>provided</scope> | ||
<type>jar</type> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.sshd</groupId> | ||
<artifactId>sshd-core</artifactId> | ||
<version>0.9.0</version> | ||
<scope>compile</scope> | ||
<type>jar</type> | ||
</dependency> | ||
<!--<dependency>--> | ||
<!--<groupId>org.bouncycastle</groupId>--> | ||
<!--<artifactId>bcprov-jdk16</artifactId>--> | ||
<!--<version>1.46</version>--> | ||
<!--</dependency>--> | ||
</dependencies> | ||
|
||
<!-- Build --> | ||
<build> | ||
<plugins> | ||
<!-- Shade plugin --> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-shade-plugin</artifactId> | ||
<version>1.5</version> | ||
<executions> | ||
<execution> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>shade</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
<configuration> | ||
<filters> | ||
<filter> | ||
<artifact>*:*</artifact> | ||
<excludes> | ||
<exclude>META-INF/*.SF</exclude> | ||
<exclude>META-INF/*.DSA</exclude> | ||
<exclude>META-INF/*.RSA</exclude> | ||
</excludes> | ||
</filter> | ||
</filters> | ||
</configuration> | ||
</plugin> | ||
<!-- Compile plugin --> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.0</version> | ||
<configuration> | ||
<source>1.7</source> | ||
<target>1.7</target> | ||
<showDeprecation>true</showDeprecation> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<packaging>jar</packaging> | ||
</project> |
39 changes: 39 additions & 0 deletions
39
src/main/java/com/ryanmichela/sshd/ConfigPasswordAuthenticator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.ryanmichela.sshd; | ||
|
||
import org.apache.sshd.server.PasswordAuthenticator; | ||
import org.apache.sshd.server.session.ServerSession; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* Copyright 2013 Ryan Michela | ||
*/ | ||
public class ConfigPasswordAuthenticator implements PasswordAuthenticator { | ||
private Map<String, Integer> failCounts = new HashMap<String, Integer>(); | ||
|
||
@Override | ||
public boolean authenticate(String username, String password, ServerSession serverSession) { | ||
if (SshdPlugin.instance.getConfig().getString("credentials." + username).equals(password)) { | ||
failCounts.put(username, 0); | ||
return true; | ||
} | ||
SshdPlugin.instance.getLogger().info("Failed login for " + username + " using password authentication."); | ||
|
||
try { | ||
Thread.sleep(3000); | ||
if (failCounts.containsKey(username)) { | ||
failCounts.put(username, failCounts.get(username) + 1); | ||
} else { | ||
failCounts.put(username, 1); | ||
} | ||
if (failCounts.get(username) >= 3) { | ||
failCounts.put(username, 0); | ||
serverSession.close(true); | ||
} | ||
} catch (InterruptedException e) { | ||
// do nothing | ||
} | ||
return false; | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/main/java/com/ryanmichela/sshd/ConsoleCommandCompleter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.ryanmichela.sshd; | ||
|
||
/** | ||
* Copyright 2013 Ryan Michela | ||
*/ | ||
|
||
import org.bukkit.Bukkit; | ||
import org.bukkit.command.CommandMap; | ||
import org.bukkit.craftbukkit.libs.jline.console.completer.Completer; | ||
|
||
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<CharSequence> candidates) { | ||
Waitable<List<String>> waitable = new Waitable<List<String>>() { | ||
@Override | ||
protected List<String> evaluate() { | ||
CommandMap commandMap = ReflectionUtil.getProtectedValue(Bukkit.getServer(), "commandMap"); | ||
return commandMap.tabComplete(Bukkit.getServer().getConsoleSender(), buffer); | ||
} | ||
}; | ||
Bukkit.getScheduler().runTask(SshdPlugin.instance, waitable); | ||
try { | ||
List<String> offers = waitable.get(); | ||
if (offers == null) { | ||
return cursor; | ||
} | ||
candidates.addAll(offers); | ||
|
||
final int lastSpace = buffer.lastIndexOf(' '); | ||
if (lastSpace == -1) { | ||
return cursor - buffer.length(); | ||
} else { | ||
return cursor - (buffer.length() - lastSpace - 1); | ||
} | ||
} catch (ExecutionException e) { | ||
SshdPlugin.instance.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e); | ||
} catch (InterruptedException e) { | ||
Thread.currentThread().interrupt(); | ||
} | ||
return cursor; | ||
} | ||
} | ||
|
67 changes: 67 additions & 0 deletions
67
src/main/java/com/ryanmichela/sshd/ConsoleCommandFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.ryanmichela.sshd; | ||
|
||
import org.apache.sshd.server.Command; | ||
import org.apache.sshd.server.CommandFactory; | ||
import org.apache.sshd.server.Environment; | ||
import org.apache.sshd.server.ExitCallback; | ||
import org.bukkit.Bukkit; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
|
||
/** | ||
* Copyright 2013 Ryan Michela | ||
*/ | ||
public class ConsoleCommandFactory implements CommandFactory { | ||
@Override | ||
public Command createCommand(String command) { | ||
return new ConsoleCommand(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) { | ||
this.command = command; | ||
} | ||
|
||
public void setInputStream(InputStream in) { | ||
this.in = in; | ||
} | ||
|
||
public void setOutputStream(OutputStream out) { | ||
this.out = out; | ||
} | ||
|
||
public void setErrorStream(OutputStream err) { | ||
this.err = err; | ||
} | ||
|
||
public void setExitCallback(ExitCallback callback) { | ||
this.callback = callback; | ||
} | ||
|
||
@Override | ||
public void start(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) { | ||
SshdPlugin.instance.getLogger().severe("Error processing command from SSH"); | ||
} finally { | ||
callback.onExit(0); | ||
} | ||
} | ||
|
||
@Override | ||
public void destroy() { | ||
|
||
} | ||
} | ||
} |
128 changes: 128 additions & 0 deletions
128
src/main/java/com/ryanmichela/sshd/ConsoleShellFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package com.ryanmichela.sshd; | ||
|
||
import org.apache.sshd.common.Factory; | ||
import org.apache.sshd.server.Command; | ||
import org.apache.sshd.server.Environment; | ||
import org.apache.sshd.server.ExitCallback; | ||
import org.bukkit.Bukkit; | ||
import org.bukkit.craftbukkit.libs.jline.console.ConsoleReader; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import java.util.logging.Formatter; | ||
import java.util.logging.Logger; | ||
import java.util.logging.StreamHandler; | ||
|
||
public class ConsoleShellFactory implements Factory<Command> { | ||
|
||
public Command create() { | ||
return new ConsoleShell(); | ||
} | ||
|
||
public static class ConsoleShell implements Command, Runnable { | ||
|
||
private InputStream in; | ||
private OutputStream out; | ||
private OutputStream err; | ||
private ExitCallback callback; | ||
private Environment environment; | ||
private Thread thread; | ||
|
||
StreamHandler streamHandler; | ||
ConsoleReader consoleReader; | ||
|
||
public InputStream getIn() { | ||
return in; | ||
} | ||
|
||
public OutputStream getOut() { | ||
return out; | ||
} | ||
|
||
public OutputStream getErr() { | ||
return err; | ||
} | ||
|
||
public Environment getEnvironment() { | ||
return environment; | ||
} | ||
|
||
public void setInputStream(InputStream in) { | ||
this.in = in; | ||
} | ||
|
||
public void setOutputStream(OutputStream out) { | ||
this.out = out; | ||
} | ||
|
||
public void setErrorStream(OutputStream err) { | ||
this.err = err; | ||
} | ||
|
||
public void setExitCallback(ExitCallback callback) { | ||
this.callback = callback; | ||
} | ||
|
||
public void start(Environment env) throws IOException { | ||
|
||
Formatter bukkitFormatter = Bukkit.getLogger().getHandlers()[0].getFormatter(); | ||
|
||
try { | ||
consoleReader = new ConsoleReader(in, new FlushyOutputStream(out), new SshTerminal()); | ||
consoleReader.setExpandEvents(true); | ||
consoleReader.addCompleter(new ConsoleCommandCompleter()); | ||
|
||
streamHandler = new FlushyStreamHandler(out, bukkitFormatter, consoleReader); | ||
Bukkit.getLogger().addHandler(streamHandler); | ||
Logger.getLogger("").addHandler(streamHandler); | ||
|
||
environment = env; | ||
thread = new Thread(this, "EchoShell " + env.getEnv().get(Environment.ENV_USER)); | ||
thread.start(); | ||
} catch (Exception e) { | ||
throw new IOException("Error starting shell", e); | ||
} | ||
} | ||
|
||
public void destroy() { | ||
Bukkit.getLogger().removeHandler(streamHandler); | ||
Logger.getLogger("").removeHandler(streamHandler); | ||
} | ||
|
||
public void run() { | ||
String command; | ||
try { | ||
printPreamble(consoleReader); | ||
while(true) { | ||
command = consoleReader.readLine("\r>", null); | ||
if (command != null) { | ||
if (command.equals("exit")) { | ||
break; | ||
} | ||
SshdPlugin.instance.getLogger().info("[U: " + environment.getEnv().get(Environment.ENV_USER) + "] " + command); | ||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); | ||
} | ||
} | ||
} catch (IOException e) { | ||
SshdPlugin.instance.getLogger().severe("Error processing command from SSH"); | ||
} finally { | ||
callback.onExit(0); | ||
} | ||
} | ||
|
||
private void printPreamble(ConsoleReader consoleReader) throws IOException{ | ||
consoleReader.println(" _____ _____ _ _ _____"); | ||
consoleReader.println(" / ____/ ____| | | | __ \\"); | ||
consoleReader.println("| (___| (___ | |__| | | | |"); | ||
consoleReader.println(" \\___ \\\\___ \\| __ | | | |"); | ||
consoleReader.println(" ____) |___) | | | | |__| |"); | ||
consoleReader.println("|_____/_____/|_| |_|_____/"); | ||
consoleReader.println("Connected to: " + Bukkit.getServer().getName()); | ||
consoleReader.println("- " + Bukkit.getServer().getMotd()); | ||
consoleReader.println(); | ||
consoleReader.println("Type 'exit' to exit the shell."); | ||
consoleReader.println("==============================================="); | ||
} | ||
} | ||
} |
Oops, something went wrong.