Advertisement
Guest User

BukkitTelnet ClientSession.java for 1.7.10

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