package net.limework.networking; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; public class AppleTunneler extends JavaPlugin { private Session sshSession; private final JSch jsch = new JSch(); private synchronized void createNewConnection() throws JSchException { if (sshSession != null) { sshSession.disconnect(); } sshSession = jsch.getSession(getUsername(), getHost(), getPort()); sshSession.connect(2000); getLogger().info("Ssh connection started successfully!"); loadRemoteToLocalPortForwarding(); } private void connectionFailedLog(JSchException exception) { getLogger().severe("=========================="); getLogger().severe("failed to start a connection"); exception.printStackTrace(); getLogger().severe("=========================="); } private void loadIds() throws JSchException { File file = new File(getDataFolder(), "Identities"); if (file.mkdir()) { getLogger().info("created Identities folder."); } File[] files = file.listFiles(); if (files == null || files.length == 0) { getLogger().warning("no Identities files found, please put them in " + file.getPath()); throw new RuntimeException("no Identities files found"); } for (File id : files) { jsch.addIdentity(id.getPath()); } getLogger().info("Ids were loaded!"); } private void loadRemoteToLocalPortForwarding() throws JSchException { for (String line : getConfig().getStringList("ports")) { sshSession.setPortForwardingL(line); getLogger().info(line); } getLogger().info("ports has been set!"); } private void loadKnownHostFile() throws FileNotFoundException, JSchException { File knownHosts = new File(getDataFolder(), ".known_hosts"); // check whatever known hosts file is folder somehow if so delete it. if (knownHosts.isDirectory()) { knownHosts.delete(); } if (!knownHosts.exists()) { getLogger().severe("FILE at path: " + knownHosts.getAbsolutePath() + " Does not exists"); throw new RuntimeException("Known host file does not exists in plugin folder"); } this.jsch.setKnownHosts(new FileInputStream(knownHosts)); getLogger().info("host file was loaded!"); } @Override public void onLoad() { this.saveDefaultConfig(); try { loadIds(); loadKnownHostFile(); } catch (JSchException | FileNotFoundException e) { throw new RuntimeException(e); } try { createNewConnection(); } catch (JSchException e) { connectionFailedLog(e); } } @Override public void onEnable() { new BukkitRunnable() { private boolean isConnecting = false; @Override public void run() { if (isConnecting) { return; } if (!sshSession.isConnected()) { isConnecting = true; try { createNewConnection(); } catch (JSchException e) { connectionFailedLog(e); } isConnecting = false; } } }.runTaskTimerAsynchronously(this, 0, 20); getLogger().info("reconnecting task was registered successfully"); } /* Currently there is no onDisable because plugin might disable itself before another which might causes disconnections and data never saved */ private int getPort() { return this.getConfig().getInt("port"); } private String getUsername() { return this.getConfig().getString("username"); } private String getHost() { return this.getConfig().getString("host"); } }