mirror of
https://github.com/moparisthebest/xAuth
synced 2024-08-13 16:53:52 -04:00
Added optional authURL support, as well as example PHP file for SMF 2.X.
This commit is contained in:
parent
a18a4cb336
commit
7cd36ff247
@ -27,7 +27,7 @@ public class LoginCommand implements CommandExecutor {
|
|||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
xAuthMessages.send("loginUsage", player);
|
xAuthMessages.send("loginUsage", player);
|
||||||
return true;
|
return true;
|
||||||
} else if (!xPlayer.isRegistered()) {
|
} else if (!xAuthSettings.authURLEnabled && !xPlayer.isRegistered()) {
|
||||||
xAuthMessages.send("loginErrRegistered", player);
|
xAuthMessages.send("loginErrRegistered", player);
|
||||||
return true;
|
return true;
|
||||||
} else if (xPlayer.hasSession()) {
|
} else if (xPlayer.hasSession()) {
|
||||||
@ -36,6 +36,10 @@ public class LoginCommand implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Account account = xPlayer.getAccount();
|
Account account = xPlayer.getAccount();
|
||||||
|
if(xAuthSettings.authURLEnabled && account == null){
|
||||||
|
account = new Account(player.getName(), "authURL", null);
|
||||||
|
xPlayer.setAccount(account);
|
||||||
|
}
|
||||||
String password = args[0];
|
String password = args[0];
|
||||||
|
|
||||||
if (!plugin.checkPassword(account, password)) {
|
if (!plugin.checkPassword(account, password)) {
|
||||||
|
@ -61,7 +61,7 @@ public class xAuthPlayerListener extends PlayerListener {
|
|||||||
final String fieldName;
|
final String fieldName;
|
||||||
plugin.createGuest(xPlayer);
|
plugin.createGuest(xPlayer);
|
||||||
|
|
||||||
if (isRegistered)
|
if (isRegistered || xAuthSettings.authURLEnabled)
|
||||||
fieldName = "joinLogin";
|
fieldName = "joinLogin";
|
||||||
else
|
else
|
||||||
fieldName = "joinRegister";
|
fieldName = "joinRegister";
|
||||||
|
@ -12,6 +12,7 @@ import java.sql.Timestamp;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -20,6 +21,15 @@ import org.bukkit.inventory.PlayerInventory;
|
|||||||
import org.bukkit.plugin.PluginDescriptionFile;
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
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 class xAuth extends JavaPlugin {
|
||||||
public static PluginDescriptionFile desc;
|
public static PluginDescriptionFile desc;
|
||||||
public static File dataFolder;
|
public static File dataFolder;
|
||||||
@ -241,6 +251,19 @@ public class xAuth extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkPassword(Account account, String checkPass) {
|
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();
|
String realPass = account.getPassword();
|
||||||
|
|
||||||
// check for old encryption (md5 or whirlpool)
|
// 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);
|
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) {
|
public Location getLocationToTeleport(World world) {
|
||||||
TeleLocation teleLocation = dataManager.getTeleLocation(world.getName());
|
TeleLocation teleLocation = dataManager.getTeleLocation(world.getName());
|
||||||
return (teleLocation == null ? world.getSpawnLocation() : teleLocation.getLocation());
|
return (teleLocation == null ? world.getSpawnLocation() : teleLocation.getLocation());
|
||||||
|
@ -16,6 +16,10 @@ public class xAuthSettings {
|
|||||||
public static boolean autoDisable = true;
|
public static boolean autoDisable = true;
|
||||||
public static boolean reverseESS = 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
|
// mysql
|
||||||
public static String mysqlHost = "localhost";
|
public static String mysqlHost = "localhost";
|
||||||
public static int mysqlPort = 3306;
|
public static int mysqlPort = 3306;
|
||||||
@ -110,6 +114,9 @@ public class xAuthSettings {
|
|||||||
autoDisable = getBool("main.auto-disable", autoDisable);
|
autoDisable = getBool("main.auto-disable", autoDisable);
|
||||||
reverseESS = getBool("main.reverse-enforce-single-session", reverseESS);
|
reverseESS = getBool("main.reverse-enforce-single-session", reverseESS);
|
||||||
|
|
||||||
|
authURLEnabled = getBool("authurl.enabled", authURLEnabled);
|
||||||
|
authURL = getString("authurl.url", authURL);
|
||||||
|
|
||||||
mysqlHost = getString("mysql.host", mysqlHost);
|
mysqlHost = getString("mysql.host", mysqlHost);
|
||||||
mysqlPort = getInt("mysql.port", mysqlPort);
|
mysqlPort = getInt("mysql.port", mysqlPort);
|
||||||
mysqlUser = getString("mysql.username", mysqlUser);
|
mysqlUser = getString("mysql.username", mysqlUser);
|
||||||
@ -171,6 +178,14 @@ public class xAuthSettings {
|
|||||||
rstrDmgTaken = getBool("restrict.damage-taken", rstrDmgTaken);
|
rstrDmgTaken = getBool("restrict.damage-taken", rstrDmgTaken);
|
||||||
rstrDmgGiven = getBool("restrict.damage-given", rstrDmgGiven);
|
rstrDmgGiven = getBool("restrict.damage-given", rstrDmgGiven);
|
||||||
rstrMobTarget = getBool("restrict.mob-target", rstrMobTarget);*/
|
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) {
|
private static String getString(String key, String def) {
|
||||||
|
@ -12,6 +12,14 @@ main:
|
|||||||
# already online, the player connecting will be kicked instead of the online player
|
# already online, the player connecting will be kicked instead of the online player
|
||||||
reverse-enforce-single-session: [reverseESS]
|
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:
|
mysql:
|
||||||
# Location of the MySQL server. Can be either a host name or IP address
|
# Location of the MySQL server. Can be either a host name or IP address
|
||||||
host: [mysqlHost]
|
host: [mysqlHost]
|
||||||
|
91
src/smf_auth.php
Normal file
91
src/smf_auth.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
// this script is tested with SMF 2.X
|
||||||
|
|
||||||
|
/* The format is pretty simple, and always returns exactly 2 lines.
|
||||||
|
|
||||||
|
if successful, return this:
|
||||||
|
|
||||||
|
YES
|
||||||
|
forum_name
|
||||||
|
|
||||||
|
if not successful, return this:
|
||||||
|
|
||||||
|
ERROR
|
||||||
|
String to return to user describing error
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// $localaddr should be the IP your webserver is listening on, if this page isn't being visited by the same IP ($_SERVER['REMOTE_ADDR'])
|
||||||
|
// then errors are logged and a warning email is sent to the email configured in done() so no one tries to use this to bruteforce
|
||||||
|
// passwords, you really should just restrict this to only the server accessing it, I only make it accessible over localhost or to
|
||||||
|
// my home address over SSL only.
|
||||||
|
$localaddr = "127.0.0.1";
|
||||||
|
if($_SERVER['REMOTE_ADDR'] != $localaddr && $_SERVER['REMOTE_ADDR'] != gethostbyname('an.allowed.hostname') && $_SERVER['REMOTE_ADDR'] != '192.168.1.212' ) die("Access Denied!");
|
||||||
|
|
||||||
|
function writeToFile($message, $fname = 'auth.log', $mode = 'a'){
|
||||||
|
$fp = fopen($fname, $mode);
|
||||||
|
fwrite($fp, time().': '.$message."\n");
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
function done($msg, $template = "ERROR\n%s"){
|
||||||
|
printf($template, $msg);
|
||||||
|
global $localaddr;
|
||||||
|
if($_SERVER['REMOTE_ADDR'] != $localaddr){
|
||||||
|
$result = sprintf(str_replace("\n", ", ", $template), $msg);
|
||||||
|
writeToFile("result: ".$result);
|
||||||
|
// only if it's a bad pass, text me
|
||||||
|
if(strpos($msg, 'assword') === FALSE)
|
||||||
|
exit;
|
||||||
|
$to = "YOUR_EMAIL_ADDRESS_IF_REQUIRED";
|
||||||
|
$subject = "auth alert";
|
||||||
|
$message .= $result."\n";
|
||||||
|
$message .= $_SERVER['REMOTE_ADDR']." user: ".$_REQUEST['user'].", field: ".$_REQUEST['field'].", pass length: ".strlen($_REQUEST['pass']);
|
||||||
|
$from = "EMAIL_TO_SEND_FROM";
|
||||||
|
$headers = "From: $from";
|
||||||
|
$sendmail_params = "-f $from -r $from";
|
||||||
|
writeToFile("mail sent: ".(mail($to,$subject,$message,$headers, $sendmail_params) ? 'true' : 'false'));
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(($_SERVER['REMOTE_ADDR'] != $localaddr && !isset($_SERVER['HTTPS']))
|
||||||
|
|| !isset($_REQUEST['pass']) || !isset($_REQUEST['user']) || !isset($_REQUEST['field'])
|
||||||
|
|| ($_REQUEST['field'] != 'minecra'))
|
||||||
|
die("Access Denied!");
|
||||||
|
|
||||||
|
$user = $_REQUEST['user'];
|
||||||
|
$pass = $_REQUEST['pass'];
|
||||||
|
$field = 'cust_'.$_REQUEST['field'];
|
||||||
|
|
||||||
|
if($_SERVER['REMOTE_ADDR'] != $localaddr)
|
||||||
|
writeToFile($_SERVER['REMOTE_ADDR']." user: $user, field: $field, pass length: ".strlen($pass));
|
||||||
|
|
||||||
|
$db_server = 'localhost';
|
||||||
|
$db_name = 'smf';
|
||||||
|
$db_user = 'smfadmin';
|
||||||
|
$db_passwd = 'your_db_pass';
|
||||||
|
$db_prefix = 'smf_';
|
||||||
|
|
||||||
|
$mysqli = new mysqli($db_server, $db_user, $db_passwd, $db_name);
|
||||||
|
|
||||||
|
$stmt = $mysqli->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");
|
||||||
|
?>
|
Loading…
Reference in New Issue
Block a user