From 7cd36ff24752b6fba03177076fa54d4fd3c66f6d Mon Sep 17 00:00:00 2001 From: Travis Burtrum Date: Mon, 4 Jul 2011 19:20:16 -0400 Subject: [PATCH] Added optional authURL support, as well as example PHP file for SMF 2.X. --- .../cypherx/xauth/commands/LoginCommand.java | 6 +- .../xauth/listeners/xAuthPlayerListener.java | 2 +- src/main/java/com/cypherx/xauth/xAuth.java | 56 ++++++++++++ .../java/com/cypherx/xauth/xAuthSettings.java | 15 +++ src/main/resources/config.yml | 8 ++ src/smf_auth.php | 91 +++++++++++++++++++ 6 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 src/smf_auth.php diff --git a/src/main/java/com/cypherx/xauth/commands/LoginCommand.java b/src/main/java/com/cypherx/xauth/commands/LoginCommand.java index b86b02a..7eb8682 100644 --- a/src/main/java/com/cypherx/xauth/commands/LoginCommand.java +++ b/src/main/java/com/cypherx/xauth/commands/LoginCommand.java @@ -27,7 +27,7 @@ public class LoginCommand implements CommandExecutor { if (args.length < 1) { xAuthMessages.send("loginUsage", player); return true; - } else if (!xPlayer.isRegistered()) { + } else if (!xAuthSettings.authURLEnabled && !xPlayer.isRegistered()) { xAuthMessages.send("loginErrRegistered", player); return true; } else if (xPlayer.hasSession()) { @@ -36,6 +36,10 @@ public class LoginCommand implements CommandExecutor { } Account account = xPlayer.getAccount(); + if(xAuthSettings.authURLEnabled && account == null){ + account = new Account(player.getName(), "authURL", null); + xPlayer.setAccount(account); + } String password = args[0]; if (!plugin.checkPassword(account, password)) { diff --git a/src/main/java/com/cypherx/xauth/listeners/xAuthPlayerListener.java b/src/main/java/com/cypherx/xauth/listeners/xAuthPlayerListener.java index ff1e85e..2570287 100644 --- a/src/main/java/com/cypherx/xauth/listeners/xAuthPlayerListener.java +++ b/src/main/java/com/cypherx/xauth/listeners/xAuthPlayerListener.java @@ -61,7 +61,7 @@ public class xAuthPlayerListener extends PlayerListener { final String fieldName; plugin.createGuest(xPlayer); - if (isRegistered) + if (isRegistered || xAuthSettings.authURLEnabled) fieldName = "joinLogin"; else fieldName = "joinRegister"; diff --git a/src/main/java/com/cypherx/xauth/xAuth.java b/src/main/java/com/cypherx/xauth/xAuth.java index b402599..f5c1c0a 100644 --- a/src/main/java/com/cypherx/xauth/xAuth.java +++ b/src/main/java/com/cypherx/xauth/xAuth.java @@ -12,6 +12,7 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; @@ -20,6 +21,15 @@ import org.bukkit.inventory.PlayerInventory; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + public class xAuth extends JavaPlugin { public static PluginDescriptionFile desc; public static File dataFolder; @@ -241,6 +251,19 @@ public class xAuth extends JavaPlugin { } public boolean checkPassword(Account account, String checkPass) { + if(xAuthSettings.authURLEnabled){ + StringBuilder sb = new StringBuilder(); + + boolean result = checkAuthURLPass(account.getPlayerName(), checkPass, sb); + // if true, tell whole server a player logged in + // else, send the returned string (error message) to the user + if(result) + Bukkit.getServer().broadcastMessage("Player '" + account.getPlayerName() + "' logged in with forum name '"+sb.toString()+"'"); + else + account.getPlayer().sendMessage(sb.toString()); + return result; + } + String realPass = account.getPassword(); // check for old encryption (md5 or whirlpool) @@ -269,6 +292,39 @@ public class xAuth extends JavaPlugin { return (hash.substring(0, saltPos) + salt + hash.substring(saltPos)).equals(realPass); } + public boolean checkAuthURLPass(String user, String pass, StringBuilder response) { + try { + user = URLEncoder.encode(user, "UTF-8"); + pass = URLEncoder.encode(pass, "UTF-8"); + + HttpURLConnection.setFollowRedirects(false); + HttpURLConnection uc = (HttpURLConnection) new URL(xAuthSettings.authURL).openConnection(); + + uc.setRequestMethod("POST"); + uc.setDoInput(true); + uc.setDoOutput(true); + uc.setUseCaches(false); + uc.setAllowUserInteraction(false); + uc.setInstanceFollowRedirects(false); + uc.setRequestProperty("User-Agent", "Mozilla/5.0 xAuth/" + desc.getVersion()); + uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + DataOutputStream out = new DataOutputStream(uc.getOutputStream()); + out.writeBytes("user=" + user + "&pass=" + pass); + out.flush(); + out.close(); + + BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream())); + String line = in.readLine(); + boolean success = line != null && line.equals("YES"); + response.append(in.readLine()); + in.close(); + return success; + } catch (Exception e) { + response.append(e.getMessage()); + return false; + } + } + public Location getLocationToTeleport(World world) { TeleLocation teleLocation = dataManager.getTeleLocation(world.getName()); return (teleLocation == null ? world.getSpawnLocation() : teleLocation.getLocation()); diff --git a/src/main/java/com/cypherx/xauth/xAuthSettings.java b/src/main/java/com/cypherx/xauth/xAuthSettings.java index 7981a88..5c47638 100644 --- a/src/main/java/com/cypherx/xauth/xAuthSettings.java +++ b/src/main/java/com/cypherx/xauth/xAuthSettings.java @@ -16,6 +16,10 @@ public class xAuthSettings { public static boolean autoDisable = true; public static boolean reverseESS = true; + // authURL + public static boolean authURLEnabled = false; + public static String authURL = "http://127.0.0.1/auth.php?field=minecra"; + // mysql public static String mysqlHost = "localhost"; public static int mysqlPort = 3306; @@ -110,6 +114,9 @@ public class xAuthSettings { autoDisable = getBool("main.auto-disable", autoDisable); reverseESS = getBool("main.reverse-enforce-single-session", reverseESS); + authURLEnabled = getBool("authurl.enabled", authURLEnabled); + authURL = getString("authurl.url", authURL); + mysqlHost = getString("mysql.host", mysqlHost); mysqlPort = getInt("mysql.port", mysqlPort); mysqlUser = getString("mysql.username", mysqlUser); @@ -171,6 +178,14 @@ public class xAuthSettings { rstrDmgTaken = getBool("restrict.damage-taken", rstrDmgTaken); rstrDmgGiven = getBool("restrict.damage-given", rstrDmgGiven); rstrMobTarget = getBool("restrict.mob-target", rstrMobTarget);*/ + + // authURL doesn't allow for registration, or password management, so automatically disable it + if (authURLEnabled) { + regEnabled = false; + regForced = true; + pwAllowChange = false; + activation = false; + } } private static String getString(String key, String def) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f03124b..c3b4cef 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -12,6 +12,14 @@ main: # already online, the player connecting will be kicked instead of the online player reverse-enforce-single-session: [reverseESS] +authurl: + # Send user/pass data to authURL for authentication instead of the database + # This option disables registration and password changes + enabled: [authURLEnabled] + # The URL to send user/pass data to, look at the example auth.php for an + # example that works with SMF forums. + url: [authURL] + mysql: # Location of the MySQL server. Can be either a host name or IP address host: [mysqlHost] diff --git a/src/smf_auth.php b/src/smf_auth.php new file mode 100644 index 0000000..f80d9e6 --- /dev/null +++ b/src/smf_auth.php @@ -0,0 +1,91 @@ +prepare("SELECT `member_name`, `passwd`, `real_name` FROM `smf_members` WHERE `is_activated` = '1' AND `id_member` = (SELECT `id_member` FROM `smf_themes` WHERE `value` = ? AND `variable` = ?) LIMIT 1") or done('MySQL Error'); +$stmt->bind_param("ss", $user, $field); +$stmt->execute(); +// bind result variables +$stmt->bind_result($member_name, $pass_hash, $display_name); +$success = $stmt->fetch(); +$stmt->close(); +$mysqli->close(); + +if(!$success) + done('Name not registered, must put in profile on forum: URL_TO_YOUR_FORUM'); + +// hash password +$sha_passwd = sha1(strtolower($member_name) . htmlspecialchars_decode($pass)); + +if($sha_passwd != $pass_hash) + done('Incorrect Password, make sure you use your forum password.'); + +done($display_name, "YES\n%s"); +?> \ No newline at end of file