mirror of
https://github.com/TotalFreedomMC/BukkitTelnet.git
synced 2025-08-05 12:02:55 +00:00
Implement authentication
This commit is contained in:
parent
fed6962883
commit
a9c8930f3b
3 changed files with 163 additions and 29 deletions
|
@ -6,6 +6,9 @@ import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
@ -17,7 +20,7 @@ import org.bukkit.scheduler.BukkitRunnable;
|
||||||
public final class BT_ClientSession extends Thread
|
public final class BT_ClientSession extends Thread
|
||||||
{
|
{
|
||||||
private static final Pattern NONASCII_FILTER = Pattern.compile("[^\\x20-\\x7E]");
|
private static final Pattern NONASCII_FILTER = Pattern.compile("[^\\x20-\\x7E]");
|
||||||
private static final Pattern LOGIN_NAME_FILTER = Pattern.compile("[^a-zA-Z0-9\\-\\.\\_]");
|
private static final Pattern AUTH_INPUT_FILTER = Pattern.compile("[^a-zA-Z0-9\\-\\.\\_]");
|
||||||
//
|
//
|
||||||
private final Socket clientSocket;
|
private final Socket clientSocket;
|
||||||
private final String clientAddress;
|
private final String clientAddress;
|
||||||
|
@ -68,7 +71,7 @@ public final class BT_ClientSession extends Thread
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
writeOutFormatted("Closing connection.");
|
writeOutFormatted("Closing connection.", true);
|
||||||
this.clientSocket.close();
|
this.clientSocket.close();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -98,9 +101,9 @@ public final class BT_ClientSession extends Thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeOutFormatted(String message)
|
public void writeOutFormatted(String message, boolean newLine)
|
||||||
{
|
{
|
||||||
writeOut("[BukkitTelnet (Console)]: " + message + "\r\n:");
|
writeOut("[BukkitTelnet (Console)]: " + message + (newLine ? "\r\n:" : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush()
|
public void flush()
|
||||||
|
@ -181,30 +184,132 @@ public final class BT_ClientSession extends Thread
|
||||||
|
|
||||||
writeOut(":");
|
writeOut(":");
|
||||||
|
|
||||||
writeOutFormatted("Session Started.");
|
writeOutFormatted("Session Started.", true);
|
||||||
|
|
||||||
authenticateSession();
|
|
||||||
|
|
||||||
|
if (authenticateSession())
|
||||||
|
{
|
||||||
sessionMainLoop();
|
sessionMainLoop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeOutFormatted("Authentication failed.", true);
|
||||||
|
}
|
||||||
|
|
||||||
terminateSession();
|
terminateSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void authenticateSession()
|
private boolean authenticateSession()
|
||||||
{
|
{
|
||||||
if (this.hasTerminated)
|
if (this.hasTerminated)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
writeOutFormatted("Authentication not yet implemented...");
|
boolean isPreAuthenticated = false;
|
||||||
|
|
||||||
|
if (this.clientAddress != null)
|
||||||
|
{
|
||||||
|
final Iterator<Map.Entry<String, List<String>>> it = BT_Config.getInstance().getConfigEntries().getAdmins().entrySet().iterator();
|
||||||
|
adminMapLoop:
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
final Map.Entry<String, List<String>> entry = it.next();
|
||||||
|
final List<String> adminIPs = entry.getValue();
|
||||||
|
if (adminIPs != null)
|
||||||
|
{
|
||||||
|
for (final String ip : adminIPs)
|
||||||
|
{
|
||||||
|
if (fuzzyIpMatch(ip, this.clientAddress, 3))
|
||||||
|
{
|
||||||
|
isPreAuthenticated = true;
|
||||||
|
this.userName = entry.getKey();
|
||||||
|
break adminMapLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final TelnetPreLoginEvent event = new TelnetPreLoginEvent(this.clientAddress, isPreAuthenticated ? this.userName : null, isPreAuthenticated);
|
||||||
|
|
||||||
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
if (event.isCancelled())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.canBypassPassword())
|
||||||
|
{
|
||||||
|
this.userName = event.getName();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boolean gotValidUsername = false;
|
||||||
|
int tries = 0;
|
||||||
|
while (tries++ < 3)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writeOutFormatted("Username: ", false);
|
||||||
|
String _userName = AUTH_INPUT_FILTER.matcher(reader.readLine()).replaceAll("").trim();
|
||||||
|
writeOut(":");
|
||||||
|
|
||||||
|
if (_userName != null && !_userName.isEmpty())
|
||||||
|
{
|
||||||
|
this.userName = _userName;
|
||||||
|
gotValidUsername = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeOutFormatted("Invalid username.", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gotValidUsername)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tries = 0;
|
||||||
|
while (tries++ < 3)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writeOutFormatted("Password: ", false);
|
||||||
|
String _password = AUTH_INPUT_FILTER.matcher(reader.readLine()).replaceAll("").trim();
|
||||||
|
writeOut(":");
|
||||||
|
|
||||||
|
if (_password != null && !_password.isEmpty() && BT_TelnetServer.getInstance().getPassword().equals(_password))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeOutFormatted("Invalid password.", true);
|
||||||
|
Thread.sleep(2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
BT_Log.severe(ex);
|
BT_Log.severe(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sessionMainLoop()
|
private void sessionMainLoop()
|
||||||
|
@ -216,6 +321,9 @@ public final class BT_ClientSession extends Thread
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
writeOutFormatted("Logged in as " + this.userName + ".", true);
|
||||||
|
BT_Log.info(this.clientAddress + " logged in as \"" + this.userName + "\".");
|
||||||
|
|
||||||
BT_Log.getLogger().addHandler(this.sessionLogHandler = new SessionLogHandler(this));
|
BT_Log.getLogger().addHandler(this.sessionLogHandler = new SessionLogHandler(this));
|
||||||
|
|
||||||
while (this.isConnected())
|
while (this.isConnected())
|
||||||
|
@ -248,6 +356,44 @@ public final class BT_ClientSession extends Thread
|
||||||
return NONASCII_FILTER.matcher(string).replaceAll("");
|
return NONASCII_FILTER.matcher(string).replaceAll("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean fuzzyIpMatch(String a, String b, int octets)
|
||||||
|
{
|
||||||
|
boolean match = true;
|
||||||
|
|
||||||
|
String[] aParts = a.split("\\.");
|
||||||
|
String[] bParts = b.split("\\.");
|
||||||
|
|
||||||
|
if (aParts.length != 4 || bParts.length != 4)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (octets > 4)
|
||||||
|
{
|
||||||
|
octets = 4;
|
||||||
|
}
|
||||||
|
else if (octets < 1)
|
||||||
|
{
|
||||||
|
octets = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < octets && i < 4; i++)
|
||||||
|
{
|
||||||
|
if (aParts[i].equals("*") || bParts[i].equals("*"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aParts[i].equals(bParts[i]))
|
||||||
|
{
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
private static class SessionLogHandler extends BT_Handler
|
private static class SessionLogHandler extends BT_Handler
|
||||||
{
|
{
|
||||||
private final BT_ClientSession session;
|
private final BT_ClientSession session;
|
||||||
|
|
|
@ -19,23 +19,6 @@ public class BukkitTelnet extends JavaPlugin
|
||||||
|
|
||||||
BT_Config.getInstance().load();
|
BT_Config.getInstance().load();
|
||||||
|
|
||||||
// BT_Config.SimpleConfigEntries configEntries = BT_Config.getInstance().getConfigEntries();
|
|
||||||
//
|
|
||||||
// String address = configEntries.getAddress();
|
|
||||||
// String password = configEntries.getPassword();
|
|
||||||
// int port = configEntries.getPort();
|
|
||||||
//
|
|
||||||
// BT_Log.info("Config loaded - " + address + ":" + port + " - PW: " + password + " - Admins:");
|
|
||||||
//
|
|
||||||
// Iterator<Map.Entry<String, List<String>>> it = configEntries.getAdmins().entrySet().iterator();
|
|
||||||
// while (it.hasNext())
|
|
||||||
// {
|
|
||||||
// Map.Entry<String, List<String>> entry = it.next();
|
|
||||||
// String name = entry.getKey();
|
|
||||||
// List<String> ips = entry.getValue();
|
|
||||||
// BT_Log.info("Admin: " + name + " - IPs: " + StringUtils.join(ips, ","));
|
|
||||||
// }
|
|
||||||
|
|
||||||
BT_TelnetServer.getInstance().startServer();
|
BT_TelnetServer.getInstance().startServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ public class TelnetPreLoginEvent extends Event implements Cancellable
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
//
|
//
|
||||||
private final String ip;
|
private final String ip;
|
||||||
private final String name;
|
private String name = null;
|
||||||
private boolean bypassPassword;
|
private boolean bypassPassword;
|
||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
|
|
||||||
|
@ -53,6 +53,11 @@ public class TelnetPreLoginEvent extends Event implements Cancellable
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean canBypassPassword()
|
public boolean canBypassPassword()
|
||||||
{
|
{
|
||||||
return bypassPassword;
|
return bypassPassword;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue