Advertisement
Guest User

BukkitTelnet ClientSession.java for newer than 1.7.10

a guest
Jun 19th, 2016
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.88 KB | None | 0 0
  1. package me.StevenLawson.BukkitTelnet.session;
  2.  
  3. import me.StevenLawson.BukkitTelnet.api.TelnetPreLoginEvent;
  4. import me.StevenLawson.BukkitTelnet.api.TelnetCommandEvent;
  5. import java.io.BufferedReader;
  6. import java.io.BufferedWriter;
  7. import java.io.IOException;
  8. import java.io.InputStreamReader;
  9. import java.io.OutputStreamWriter;
  10. import java.net.Socket;
  11. import java.util.List;
  12. import java.util.Map;
  13. import java.util.regex.Pattern;
  14. import me.StevenLawson.BukkitTelnet.BukkitTelnet;
  15. import me.StevenLawson.BukkitTelnet.TelnetConfig;
  16. import me.StevenLawson.BukkitTelnet.TelnetLogAppender;
  17. import me.StevenLawson.BukkitTelnet.TelnetLogger;
  18. import me.StevenLawson.BukkitTelnet.Util;
  19. import org.bukkit.Bukkit;
  20. import org.bukkit.ChatColor;
  21. import org.bukkit.Server;
  22. import org.bukkit.scheduler.BukkitRunnable;
  23.  
  24. public final class ClientSession extends Thread
  25. {
  26.     public static final Pattern NONASCII_FILTER = Pattern.compile("[^\\x20-\\x7E]");
  27.     public static final Pattern AUTH_INPUT_FILTER = Pattern.compile("[^a-zA-Z0-9]");
  28.     public static final Pattern COMMAND_INPUT_FILTER = Pattern.compile("^[^a-zA-Z0-9/\\?!\\.]+");
  29.     //
  30.     private final Socket clientSocket;
  31.     private final String clientAddress;
  32.     //
  33.     private final SessionCommandSender commandSender;
  34.     private FilterMode filterMode;
  35.     //
  36.     private BufferedWriter writer;
  37.     private BufferedReader reader;
  38.     private String username;
  39.     private boolean hasTerminated;
  40.  
  41.     public ClientSession(Socket clientSocket)
  42.     {
  43.         this.clientSocket = clientSocket;
  44.         this.clientAddress = clientSocket.getInetAddress().getHostAddress();
  45.         this.username = "";
  46.         this.commandSender = new SessionCommandSender(this);
  47.         this.filterMode = FilterMode.FULL;
  48.         this.hasTerminated = false;
  49.  
  50.         TelnetLogger.info("Client connected: " + clientAddress);
  51.     }
  52.  
  53.     @Override
  54.     public void run()
  55.     {
  56.         try
  57.         {
  58.             synchronized (clientSocket)
  59.             {
  60.                 reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
  61.                 writer = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
  62.             }
  63.         }
  64.         catch (IOException ex)
  65.         {
  66.             TelnetLogger.severe(ex);
  67.             syncTerminateSession();
  68.             return;
  69.         }
  70.  
  71.         printRaw(":");
  72.         println("Session Started.");
  73.  
  74.         if (!authenticate())
  75.         {
  76.             println("Authentication failed.");
  77.             syncTerminateSession();
  78.         }
  79.  
  80.         mainLoop();
  81.         syncTerminateSession();
  82.     }
  83.  
  84.     public boolean syncIsConnected()
  85.     {
  86.         synchronized (clientSocket)
  87.         {
  88.             return !clientSocket.isClosed();
  89.         }
  90.     }
  91.  
  92.     public synchronized void syncTerminateSession()
  93.     {
  94.         if (hasTerminated)
  95.         {
  96.             return;
  97.         }
  98.  
  99.         hasTerminated = true;
  100.  
  101.         TelnetLogger.info("Closing connection: " + clientAddress + (username.isEmpty() ? "" : " (" + username + ")"));
  102.         TelnetLogAppender.getInstance().removeSession(this);
  103.  
  104.         synchronized (clientSocket)
  105.         {
  106.             if (clientSocket == null)
  107.             {
  108.                 return;
  109.             }
  110.  
  111.             println("Closing connection...");
  112.             try
  113.             {
  114.                 clientSocket.close();
  115.             }
  116.             catch (IOException ex)
  117.             {
  118.             }
  119.  
  120.         }
  121.     }
  122.  
  123.     public String getUserName()
  124.     {
  125.         return username;
  126.     }
  127.  
  128.     public SessionCommandSender getCommandSender()
  129.     {
  130.         return commandSender;
  131.     }
  132.  
  133.     public FilterMode getFilterMode()
  134.     {
  135.         return filterMode;
  136.     }
  137.  
  138.     public void setFilterMode(FilterMode filterMode)
  139.     {
  140.         this.filterMode = filterMode;
  141.     }
  142.  
  143.     public void printRaw(String message)
  144.     {
  145.         if (writer == null || !syncIsConnected())
  146.         {
  147.             return;
  148.         }
  149.  
  150.         try
  151.         {
  152.             writer.write(ChatColor.stripColor(message));
  153.             writer.flush();
  154.         }
  155.         catch (IOException ex)
  156.         {
  157.         }
  158.     }
  159.  
  160.     public void printRawln(String message)
  161.     {
  162.         printRaw(message + "\r\n:");
  163.     }
  164.  
  165.     public void print(String message)
  166.     {
  167.         printRaw("[" + (username.isEmpty() ? "" : username + "@") + "BukkitTelnet]$ " + message);
  168.     }
  169.  
  170.     public void println(String message)
  171.     {
  172.         print(message + "\r\n:");
  173.     }
  174.  
  175.     public void flush()
  176.     {
  177.         if (writer == null || !syncIsConnected())
  178.         {
  179.             return;
  180.         }
  181.  
  182.         try
  183.         {
  184.             writer.flush();
  185.         }
  186.         catch (IOException ex)
  187.         {
  188.         }
  189.     }
  190.  
  191.     public void syncExecuteCommand(final String command)
  192.     {
  193.         new BukkitRunnable()
  194.         {
  195.             @Override
  196.             public void run()
  197.             {
  198.                 final Server server = Bukkit.getServer();
  199.  
  200.                 final TelnetCommandEvent event = new TelnetCommandEvent(commandSender, command);
  201.                 server.getPluginManager().callEvent(event);
  202.  
  203.                 if (event.isCancelled())
  204.                 {
  205.                     return;
  206.                 }
  207.  
  208.                 if (event.getCommand().isEmpty())
  209.                 {
  210.                     return;
  211.                 }
  212.  
  213.                 server.dispatchCommand(event.getSender(), event.getCommand());
  214.             }
  215.         }.runTask(BukkitTelnet.plugin);
  216.     }
  217.  
  218.     private boolean authenticate()
  219.     {
  220.         if (hasTerminated)
  221.         {
  222.             return false;
  223.         }
  224.  
  225.         boolean passAuth = false;
  226.  
  227.         // Pre-authenticate IP addresses
  228.         if (clientAddress != null)
  229.         {
  230.             final Map<String, List<String>> admins = TelnetConfig.getInstance().getConfigEntries().getAdmins();
  231.  
  232.             // For every admin
  233.             for (String name : admins.keySet())
  234.             {
  235.  
  236.                 // For every IP of each admin
  237.                 for (String ip : admins.get(name))
  238.                 {
  239.                     if (Util.fuzzyIpMatch(ip, clientAddress, 3))
  240.                     {
  241.                         passAuth = true;
  242.                         this.username = name;
  243.                         break;
  244.                     }
  245.                 }
  246.             }
  247.         }
  248.  
  249.         // TelnetPreLoginEvent authentication
  250.         final TelnetPreLoginEvent event = new TelnetPreLoginEvent(clientAddress, username, passAuth);
  251.         Bukkit.getServer().getPluginManager().callEvent(event);
  252.  
  253.         if (event.isCancelled())
  254.         {
  255.             return false;
  256.         }
  257.  
  258.         if (event.canBypassPassword())
  259.         {
  260.             if (!event.getName().isEmpty()) // If the name hasn't been set, we'll ask for it.
  261.             {
  262.                 this.username = event.getName();
  263.                 return true;
  264.             }
  265.  
  266.             passAuth = true;
  267.         }
  268.  
  269.         // Username
  270.         boolean validUsername = false;
  271.  
  272.         int tries = 0;
  273.         while (tries++ < 3)
  274.         {
  275.             print("Username: ");
  276.  
  277.             String input;
  278.             try
  279.             {
  280.                 input = reader.readLine();
  281.             }
  282.             catch (IOException ex)
  283.             {
  284.                 continue;
  285.             }
  286.  
  287.             printRaw(":");
  288.  
  289.             if (input == null || input.isEmpty()) // End of stream
  290.             {
  291.                 continue;
  292.             }
  293.  
  294.             input = AUTH_INPUT_FILTER.matcher(input).replaceAll("").trim();
  295.  
  296.             if (input.isEmpty())
  297.             {
  298.                 println("Invalid username.");
  299.                 continue;
  300.             }
  301.  
  302.             this.username = input;
  303.             validUsername = true;
  304.             break;
  305.         }
  306.  
  307.         if (!validUsername)
  308.         {
  309.             return false;
  310.         }
  311.  
  312.         // If the TelnetPreLoginEvent authenticates the password,
  313.         // don't ask for it.
  314.         if (passAuth)
  315.         {
  316.             return true;
  317.         }
  318.  
  319.         // Password
  320.         tries = 0;
  321.         while (tries++ < 3)
  322.         {
  323.             print("Password: ");
  324.  
  325.             String input;
  326.  
  327.             try
  328.             {
  329.                 input = reader.readLine();
  330.             }
  331.             catch (IOException ex)
  332.             {
  333.                 continue;
  334.             }
  335.  
  336.             printRaw(":");
  337.  
  338.             if (input == null || input.isEmpty()) // End of stream
  339.             {
  340.                 continue;
  341.             }
  342.  
  343.             input = AUTH_INPUT_FILTER.matcher(input).replaceAll("").trim();
  344.  
  345.             if (TelnetConfig.getInstance().getConfigEntries().getPassword().equals(input))
  346.             {
  347.                 return true;
  348.             }
  349.  
  350.             println("Invalid password.");
  351.             try
  352.             {
  353.                 Thread.sleep(2000);
  354.             }
  355.             catch (InterruptedException ex)
  356.             {
  357.             }
  358.         }
  359.  
  360.         return false;
  361.     }
  362.  
  363.     private void mainLoop()
  364.     {
  365.         if (hasTerminated)
  366.         {
  367.             return;
  368.         }
  369.  
  370.         println("Logged in as " + username + ".");
  371.         TelnetLogger.info(clientAddress + " logged in as \"" + username + "\".");
  372.  
  373.         // Start feeding data to the client.
  374.         TelnetLogAppender.getInstance().addSession(this);
  375.  
  376.         // Process commands
  377.         while (syncIsConnected())
  378.         {
  379.             // Read a command
  380.             String command;
  381.             try
  382.             {
  383.                 command = reader.readLine();
  384.             }
  385.             catch (IOException ex)
  386.             {
  387.                 continue;
  388.             }
  389.  
  390.             printRaw(":");
  391.  
  392.             if (command == null || command.isEmpty()) // End of stream
  393.             {
  394.                 continue;
  395.             }
  396.  
  397.             command = COMMAND_INPUT_FILTER.matcher(NONASCII_FILTER.matcher(command).replaceAll("")).replaceFirst("").trim();
  398.             if (command.isEmpty())
  399.             {
  400.                 continue;
  401.             }
  402.  
  403.             if (command.toLowerCase().startsWith("telnet"))
  404.             {
  405.                 executeTelnetCommand(command);
  406.                 continue;
  407.             }
  408.  
  409.             syncExecuteCommand(command);
  410.         }
  411.     }
  412.  
  413.     private void executeTelnetCommand(String command)
  414.     {
  415.         if (command.equalsIgnoreCase("telnet.help"))
  416.         {
  417.             println("--- Telnet commands ---");
  418.             println("telnet.help  - See all of the telnet commands.");
  419.             println("telnet.stop  - Shut the server down.");
  420.             println("telnet.log   - Change your logging settings.");
  421.             println("telnet.exit  - Quit the telnet session.");
  422.             return;
  423.         }
  424.  
  425.         if (command.equalsIgnoreCase("telnet.stop"))
  426.         {
  427.             println("Shutting down the server...");
  428.             TelnetLogger.warning(username + ": Shutting down the server...");
  429.             System.exit(0);
  430.             return;
  431.         }
  432.  
  433.         if (command.equalsIgnoreCase("telnet.log"))
  434.         {
  435.             if (filterMode == FilterMode.FULL)
  436.             {
  437.                 filterMode = FilterMode.CHAT_ONLY;
  438.                 println("Showing only chat logs.");
  439.                 return;
  440.             }
  441.  
  442.             if (filterMode == FilterMode.CHAT_ONLY)
  443.             {
  444.                 filterMode = FilterMode.NONCHAT_ONLY;
  445.                 println("Showing only non-chat logs.");
  446.                 return;
  447.             }
  448.  
  449.             if (filterMode == FilterMode.NONCHAT_ONLY)
  450.             {
  451.                 filterMode = FilterMode.FULL;
  452.                 println("Showing all logs.");
  453.                 return;
  454.             }
  455.             return;
  456.         }
  457.  
  458.         if (command.equalsIgnoreCase("telnet.exit"))
  459.         {
  460.             println("Goodbye <3");
  461.             syncTerminateSession();
  462.         }
  463.  
  464.  
  465.         println("Invalid telnet command, use \"telnet.help\" to view help.");
  466.     }
  467. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement