Update 2.9.3

* Fix BungeeCord again
* Remove useless part of api
* Fix register api method
* Always store cache with lowercase players name
* Remove some useless asynchronous part
* Fix some thread problems
* Add PBKDF2 method
* Fix SQLite problem (world duplicate column)
* Fix cannot measure distance between two different world
This commit is contained in:
Xephi 2013-08-26 18:35:28 +02:00
parent 2522357982
commit 7e7afcbfd6
41 changed files with 1404 additions and 314 deletions

View File

@ -24,7 +24,7 @@
</plugin>
</plugins>
</build>
<version>2.9.2</version>
<version>2.9.3</version>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>

View File

@ -134,7 +134,7 @@ public class Management {
.getLimboPlayer(name);
final PlayerAuth getAuth = database.getAuth(name);
if (limbo != null) {
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -161,7 +161,7 @@ public class Management {
}
});
} else {
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -189,7 +189,7 @@ public class Management {
.contains(player.getWorld()
.getName())) {
final Location spawnL = spawnLoc;
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -222,7 +222,7 @@ public class Management {
}
});
} else {
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -244,7 +244,7 @@ public class Management {
});
}
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -256,7 +256,7 @@ public class Management {
if (Settings.protectInventoryBeforeLogInEnabled
&& player.hasPlayedBefore()) {
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -312,7 +312,7 @@ public class Management {
pllog.save();
} catch (NullPointerException ex) {
}
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -343,7 +343,7 @@ public class Management {
"[AuthMe] " + player.getName()
+ " logged in!"));
}
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -359,7 +359,7 @@ public class Management {
try {
final int gm = AuthMePlayerListener.gameMode
.get(name);
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -369,7 +369,7 @@ public class Management {
});
} catch (NullPointerException npe) {
}
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -393,7 +393,7 @@ public class Management {
.getLimboPlayer(name);
if (limbo != null) {
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -428,7 +428,7 @@ public class Management {
database.getAuth(name)
.getQuitLocZ() + 0.5D);
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -448,7 +448,7 @@ public class Management {
}
});
} else {
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -473,7 +473,7 @@ public class Management {
&& Settings.getForcedWorlds.contains(player
.getWorld().getName())) {
final Location spawnL = spawnLoc;
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -510,7 +510,7 @@ public class Management {
database.getAuth(name).getQuitLocX() + 0.5D,
database.getAuth(name).getQuitLocY() + 0.5D,
database.getAuth(name).getQuitLocZ() + 0.5D);
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -528,7 +528,7 @@ public class Management {
}
});
} else {
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -547,7 +547,7 @@ public class Management {
});
}
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -559,7 +559,7 @@ public class Management {
if (Settings.protectInventoryBeforeLogInEnabled
&& player.hasPlayedBefore()) {
Bukkit.getScheduler().runTask(plugin,
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable() {
@Override
public void run() {
@ -612,7 +612,7 @@ public class Management {
pllog.save();
} catch (NullPointerException ex) {
}
Bukkit.getScheduler().runTask(plugin, new Runnable() {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
Bukkit.getServer()
@ -638,7 +638,7 @@ public class Management {
"[AuthMe] " + player.getName()
+ " logged in!"));
}
Bukkit.getScheduler().runTask(plugin, new Runnable() {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
player.saveData();

View File

@ -11,7 +11,6 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import uk.org.whoami.authme.AuthMe;
import uk.org.whoami.authme.ConsoleLogger;
import uk.org.whoami.authme.Utils;
import uk.org.whoami.authme.cache.auth.PlayerAuth;
import uk.org.whoami.authme.cache.auth.PlayerCache;
@ -73,65 +72,9 @@ public class API {
return Utils.getInstance().isUnrestricted(player);
}
public static boolean isChatAllowed() {
return Settings.isChatAllowed;
}
public static boolean isAllowRestrictedIp() {
return Settings.isAllowRestrictedIp;
}
public static boolean isBackupActivated() {
return Settings.isBackupActivated;
}
public static boolean isForceSpawnLocOnJoinEnabled() {
return Settings.isForceSpawnLocOnJoinEnabled;
}
public static DataSourceType getDataSource() {
return Settings.getDataSource;
}
public static int getMovementRadius() {
return Settings.getMovementRadius;
}
public static List<String> getJoinPermissions() {
return Settings.getJoinPermissions;
}
public static Boolean isPasspartuEnable() {
return Settings.enablePasspartu;
}
public static String getcUnrestrictedName() {
return Settings.getcUnrestrictedName;
}
public static Boolean getEnablePasswordVerifier() {
return Settings.getEnablePasswordVerifier;
}
public static int getMaxNickLength() {
return Settings.getMaxNickLength;
}
public static int getMinNickLength() {
return Settings.getMinNickLength;
}
public static Array getLastLocationColumns() {
Array columns = null;
Array.set(columns, 0, Settings.getMySQLlastlocX);
Array.set(columns, 1, Settings.getMySQLlastlocY);
Array.set(columns, 2, Settings.getMySQLlastlocZ);
return columns;
}
public static Location getLastLocation(Player player) {
try {
PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName());
PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName().toLowerCase());
if (auth != null) {
Location loc = new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY() , auth.getQuitLocZ());
@ -145,30 +88,6 @@ public class API {
}
}
public static String getNickRegex() {
return Settings.getNickRegex;
}
public static int getPasswordMinLen() {
return Settings.getPasswordMinLen;
}
public static HashAlgorithm getPasswordHash() {
return Settings.getPasswordHash;
}
public static int getRegistrationTimeout() {
return Settings.getRegistrationTimeout;
}
public static int getSessionTimeout() {
return Settings.getSessionTimeout;
}
public static String getUnloggedinGroup() {
return Settings.getUnloggedinGroup;
}
public static void setPlayerInventory(Player player, ItemStack[] content, ItemStack[] armor) {
try {
player.getInventory().setContents(content);
@ -214,7 +133,7 @@ public class API {
try {
String name = playerName.toLowerCase();
String hash = PasswordSecurity.getHash(Settings.getPasswordHash, password, name);
if (database.isAuthAvailable(name)) {
if (isRegistered(name)) {
return false;
}
PlayerAuth auth = new PlayerAuth(name, hash, "198.18.0.1", 0);

View File

@ -220,5 +220,13 @@ public class PlayerAuth {
public String getWorld() {
return world;
}
@Override
public String toString() {
String s = "Player : " + nickname + " ! IP : " + ip + " ! LastLogin : " + lastLogin + " ! LastPosition : " + x + "," + y + "," + z + "," + world
+ " ! Email : " + email + " ! Hash : " + hash + " ! Salt : " + salt;
return s;
}
}

View File

@ -28,24 +28,24 @@ public class PlayerCache {
}
public void addPlayer(PlayerAuth auth) {
cache.put(auth.getNickname(), auth);
cache.put(auth.getNickname().toLowerCase(), auth);
}
public void updatePlayer(PlayerAuth auth) {
cache.remove(auth.getNickname());
cache.put(auth.getNickname(), auth);
cache.remove(auth.getNickname().toLowerCase());
cache.put(auth.getNickname().toLowerCase(), auth);
}
public void removePlayer(String user) {
cache.remove(user);
cache.remove(user.toLowerCase());
}
public boolean isAuthenticated(String user) {
return cache.containsKey(user);
return cache.containsKey(user.toLowerCase());
}
public PlayerAuth getAuth(String user) {
return cache.get(user);
return cache.get(user.toLowerCase());
}
public static PlayerCache getInstance() {

View File

@ -176,7 +176,7 @@ public class AdminCommand implements CommandExecutor {
if (!args[1].contains(".")) {
final CommandSender fSender = sender;
final String[] arguments = args;
Bukkit.getScheduler().runTask(plugin, new Runnable() {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
PlayerAuth pAuth = null;
@ -219,7 +219,7 @@ public class AdminCommand implements CommandExecutor {
} else {
final CommandSender fSender = sender;
final String[] arguments = args;
Bukkit.getScheduler().runTask(plugin, new Runnable() {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
String message = "[AuthMe] ";
@ -344,12 +344,16 @@ public class AdminCommand implements CommandExecutor {
bannedPlayers.add(off.getName().toLowerCase());
}
final List<String> bP = bannedPlayers;
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
database.purgeBanned(bP);
}
});
if (database instanceof Thread) {
database.purgeBanned(bP);
} else {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
database.purgeBanned(bP);
}
});
}
} else if (args[0].equalsIgnoreCase("spawn")) {
try {
if (sender instanceof Player) {

View File

@ -172,13 +172,18 @@ public class EmailCommand implements CommandExecutor {
}
final String finalhashnew = hashnew;
final PlayerAuth finalauth = auth;
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
finalauth.setHash(finalhashnew);
data.updatePassword(finalauth);
}
});
if (data instanceof Thread) {
finalauth.setHash(hashnew);
data.updatePassword(auth);
} else {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
finalauth.setHash(finalhashnew);
data.updatePassword(finalauth);
}
});
}
plugin.mail.main(auth, thePass);
player.sendMessage(m._("email_send"));
} catch (NoSuchAlgorithmException ex) {

View File

@ -100,7 +100,7 @@ public class UnregisterCommand implements CommandExecutor {
BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name), delay);
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id.getTaskId());
}
sched.runTask(plugin, new MessageTask(plugin, name, m._("reg_msg"), interval));
sched.scheduleSyncDelayedTask(plugin, new MessageTask(plugin, name, m._("reg_msg"), interval));
if(!Settings.unRegisteredGroup.isEmpty()){
Utils.getInstance().setGroup(player, Utils.groupType.UNREGISTERED);
}

View File

@ -153,8 +153,8 @@ private synchronized Connection getConnection3() throws SQLException {
else {
pconn = dataSource.getPooledConnection();
pconn.addConnectionEventListener(poolConnectionEventListener); }
activeConnections++;
Connection conn = pconn.getConnection();
activeConnections++;
assertInnerState();
return conn; }

View File

@ -283,7 +283,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public boolean updateSession(PlayerAuth auth) {
public synchronized boolean updateSession(PlayerAuth auth) {
Connection con = null;
PreparedStatement pst = null;
try {
@ -307,7 +307,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public int purgeDatabase(long until) {
public synchronized int purgeDatabase(long until) {
Connection con = null;
PreparedStatement pst = null;
try {
@ -350,7 +350,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public boolean updateQuitLoc(PlayerAuth auth) {
public synchronized boolean updateQuitLoc(PlayerAuth auth) {
Connection con = null;
PreparedStatement pst = null;
try {
@ -376,7 +376,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public int getIps(String ip) {
public synchronized int getIps(String ip) {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
@ -405,7 +405,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public boolean updateEmail(PlayerAuth auth) {
public synchronized boolean updateEmail(PlayerAuth auth) {
Connection con = null;
PreparedStatement pst = null;
try {
@ -428,7 +428,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public boolean updateSalt(PlayerAuth auth) {
public synchronized boolean updateSalt(PlayerAuth auth) {
if (columnSalt.isEmpty()) {
return false;
}
@ -497,7 +497,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public List<String> getAllAuthsByName(PlayerAuth auth) {
public synchronized List<String> getAllAuthsByName(PlayerAuth auth) {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
@ -526,7 +526,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public List<String> getAllAuthsByIp(String ip) {
public synchronized List<String> getAllAuthsByIp(String ip) {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
@ -555,7 +555,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public List<String> getAllAuthsByEmail(String email) {
public synchronized List<String> getAllAuthsByEmail(String email) {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
@ -584,7 +584,7 @@ public class MySQLDataSource implements DataSource {
}
@Override
public void purgeBanned(List<String> banned) {
public synchronized void purgeBanned(List<String> banned) {
Connection con = null;
PreparedStatement pst = null;
try {

View File

@ -1,7 +1,3 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package uk.org.whoami.authme.datasource;
import java.sql.*;
@ -106,6 +102,7 @@ public class SqliteDataSource implements DataSource {
+ "ALTER TABLE " + tableName + " ADD COLUMN " + lastlocZ + " smallint(6) NOT NULL DEFAULT '0';");
}
rs.close();
rs = con.getMetaData().getColumns(null, null, tableName, lastlocWorld);
if (!rs.next()) {
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT 'world' AFTER " + lastlocZ + ";");
}

View File

@ -170,7 +170,7 @@ public class AuthMePlayerListener implements Listener {
}
}
} else {
Bukkit.getScheduler().runTask(plugin, new Runnable()
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
@Override
public void run() {
@ -227,7 +227,7 @@ public class AuthMePlayerListener implements Listener {
}
}
} else {
Bukkit.getScheduler().runTask(plugin, new Runnable()
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
@Override
public void run() {
@ -285,7 +285,7 @@ public class AuthMePlayerListener implements Listener {
}
}
} else {
Bukkit.getScheduler().runTask(plugin, new Runnable()
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
@Override
public void run() {
@ -342,7 +342,7 @@ public class AuthMePlayerListener implements Listener {
}
}
} else {
Bukkit.getScheduler().runTask(plugin, new Runnable()
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
@Override
public void run() {
@ -399,7 +399,7 @@ public class AuthMePlayerListener implements Listener {
}
}
} else {
Bukkit.getScheduler().runTask(plugin, new Runnable()
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
@Override
public void run() {
@ -456,7 +456,7 @@ public class AuthMePlayerListener implements Listener {
}
}
} else {
Bukkit.getScheduler().runTask(plugin, new Runnable()
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
@Override
public void run() {
@ -827,16 +827,20 @@ public class AuthMePlayerListener implements Listener {
return;
}
if (PlayerCache.getInstance().isAuthenticated(name) && !player.isDead()) {
if (PlayerCache.getInstance().isAuthenticated(name) && !player.isDead()) {
if(Settings.isSaveQuitLocationEnabled && data.isAuthAvailable(name)) {
final PlayerAuth auth = new PlayerAuth(event.getPlayer().getName().toLowerCase(),loc.getBlockX(),loc.getBlockY(),loc.getBlockZ(),loc.getWorld().getName());
try {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
data.updateQuitLoc(auth);
}
});
if (data instanceof Thread) {
data.updateQuitLoc(auth);
} else {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable(){
@Override
public void run() {
data.updateQuitLoc(auth);
}
});
}
} catch (NullPointerException npe) { }
}
}
@ -898,12 +902,18 @@ public class AuthMePlayerListener implements Listener {
if ((PlayerCache.getInstance().isAuthenticated(name)) && (!player.isDead()) &&
(Settings.isSaveQuitLocationEnabled.booleanValue()) && data.isAuthAvailable(name)) {
final PlayerAuth auth = new PlayerAuth(event.getPlayer().getName().toLowerCase(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(),loc.getWorld().getName());
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
data.updateQuitLoc(auth);
}
});
try {
if (data instanceof Thread) {
data.updateQuitLoc(auth);
} else {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable(){
@Override
public void run() {
data.updateQuitLoc(auth);
}
});
}
} catch (NullPointerException npe) { }
}
if (LimboCache.getInstance().hasLimboPlayer(name))
@ -1181,12 +1191,18 @@ public class AuthMePlayerListener implements Listener {
if (Spawn.getInstance().getLocation() != null && Spawn.getInstance().getLocation().getWorld().equals(player.getWorld()))
spawn = Spawn.getInstance().getLocation();
final PlayerAuth auth = new PlayerAuth(event.getPlayer().getName().toLowerCase(), spawn.getBlockX(), spawn.getBlockY(), spawn.getBlockZ(),spawn.getWorld().getName());
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable(){
@Override
public void run() {
data.updateQuitLoc(auth);
}
});
try {
if (data instanceof Thread) {
data.updateQuitLoc(auth);
} else {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable(){
@Override
public void run() {
data.updateQuitLoc(auth);
}
});
}
} catch (NullPointerException npe) { }
event.setRespawnLocation(spawn);
}

View File

@ -8,7 +8,6 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageListener;
import uk.org.whoami.authme.AuthMe;
import uk.org.whoami.authme.ConsoleLogger;
public class BungeeCordMessage implements PluginMessageListener {
@ -24,7 +23,6 @@ public class BungeeCordMessage implements PluginMessageListener {
try {
final DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
if (in.readUTF().equals("IP")) { //We need only the IP channel
ConsoleLogger.info("PluginMessage send to " + player.getName() + " , the message was : " + message.toString());
plugin.realIp.put(player.getName().toLowerCase(), in.readUTF()); //Put the IP (only the ip not the port) in the hashmap
}
} catch (IOException ex) {

View File

@ -28,6 +28,8 @@ import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import uk.org.whoami.authme.AuthMe;
import uk.org.whoami.authme.security.pbkdf2.PBKDF2Engine;
import uk.org.whoami.authme.security.pbkdf2.PBKDF2Parameters;
import uk.org.whoami.authme.settings.Settings;
public class PasswordSecurity {
@ -105,6 +107,13 @@ public class PasswordSecurity {
private static String getWBB3(String message, String salt) throws NoSuchAlgorithmException {
return getSHA1(salt.concat(getSHA1(salt.concat(getSHA1(message)))));
}
private static String getPBKDF2(String password, String salt) throws NoSuchAlgorithmException {
String result = "pbkdf2_sha256$10000$"+salt+"$";
PBKDF2Parameters params = new PBKDF2Parameters("SHA-256", "UTF-8", salt.getBytes(), 10000);
PBKDF2Engine engine = new PBKDF2Engine(params);
return result + engine.deriveKey(password,57).toString();
}
private static String createSalt(int length) throws NoSuchAlgorithmException {
byte[] msg = new byte[40];
@ -226,6 +235,9 @@ public class PasswordSecurity {
return getSHA512(password);
case DOUBLEMD5:
return getMD5(getMD5(password));
case PBKDF2:
String saltpbkdf2 = createSalt(12);
return getPBKDF2(password, saltpbkdf2);
default:
throw new NoSuchAlgorithmException("Unknown hash algorithm");
}
@ -237,24 +249,24 @@ public class PasswordSecurity {
return checkHash.phpbb_check_hash(password, hash);
}
if(!Settings.getMySQLColumnSalt.isEmpty() && Settings.getPasswordHash == HashAlgorithm.WBB3) {
String saltwbb3 = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getWBB3(password, saltwbb3));
String salt = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getWBB3(password, salt));
}
if(!Settings.getMySQLColumnSalt.isEmpty() && Settings.getPasswordHash == HashAlgorithm.IPB3) {
String saltipb = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getSaltedIPB3(password, saltipb));
String salt = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getSaltedIPB3(password, salt));
}
if(!Settings.getMySQLColumnSalt.isEmpty() && Settings.getPasswordHash == HashAlgorithm.BCRYPT) {
String saltbcrypt = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(BCrypt.hashpw(password, saltbcrypt));
String salt = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(BCrypt.hashpw(password, salt));
}
if(!Settings.getMySQLColumnSalt.isEmpty() && Settings.getPasswordHash == HashAlgorithm.PHPFUSION) {
String saltfusion = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getPhPFusion(password, saltfusion));
String salt = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getPhPFusion(password, salt));
}
if(!Settings.getMySQLColumnSalt.isEmpty() && Settings.getPasswordHash == HashAlgorithm.MYBB) {
String saltmybb = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getSaltedMyBB(password, saltmybb));
String salt = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getSaltedMyBB(password, salt));
}
if(Settings.getPasswordHash == HashAlgorithm.SMF)
return hash.equals(getSHA1(playername.toLowerCase() + password));
@ -265,15 +277,23 @@ public class PasswordSecurity {
if(Settings.getPasswordHash == HashAlgorithm.DOUBLEMD5)
return hash.equals(getMD5(getMD5(password)));
if(!Settings.getMySQLColumnSalt.isEmpty() && Settings.getPasswordHash == HashAlgorithm.SALTED2MD5) {
String salt2md5 = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getMD5(getMD5(password) + salt2md5));
String salt = AuthMe.getInstance().database.getAuth(playername).getSalt();
return hash.equals(getMD5(getMD5(password) + salt));
}
if(Settings.getPasswordHash == HashAlgorithm.JOOMLA) {
String saltj = hash.split(":")[1];
return hash.equals(getMD5(password + saltj) + ":" + saltj);
String salt = hash.split(":")[1];
return hash.equals(getMD5(password + salt) + ":" + salt);
}
if(Settings.getPasswordHash == HashAlgorithm.SHA512)
return hash.equals(getSHA512(password));
if(Settings.getPasswordHash == HashAlgorithm.PBKDF2) {
String[] line = hash.split("\\$");
String salt = line[2];
String derivedKey = line[3];
PBKDF2Parameters params = new PBKDF2Parameters("SHA-256", "UTF-8", salt.getBytes(), 10000, derivedKey.getBytes());
PBKDF2Engine engine = new PBKDF2Engine(params);
return engine.verifyKey(password);
}
// PlainText Password
if(hash.length() < 32 )
return hash.equals(password);
@ -336,7 +356,7 @@ public class PasswordSecurity {
public enum HashAlgorithm {
MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB, PLAINTEXT, MYBB, IPB3, PHPFUSION, SMF, XFSHA1,
XFSHA256, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512, DOUBLEMD5
XFSHA256, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512, DOUBLEMD5, PBKDF2
}
}

View File

@ -0,0 +1,137 @@
package uk.org.whoami.authme.security.pbkdf2;
/**
* <p>
* Free auxiliary functions. Copyright (c) 2007 Matthias G&auml;rtner
* </p>
* <p>
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* </p>
* <p>
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
* </p>
* <p>
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* </p>
* <p>
* For Details, see <a
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
* </p>
*
* @author Matthias G&auml;rtner
* @version 1.0
*/
public class BinTools
{
public static final String hex = "0123456789ABCDEF";
/**
* Simple binary-to-hexadecimal conversion.
*
* @param b
* Input bytes. May be <code>null</code>.
* @return Hexadecimal representation of b. Uppercase A-F, two characters
* per byte. Empty string on <code>null</code> input.
*/
public static String bin2hex(final byte[] b)
{
if (b == null)
{
return "";
}
StringBuffer sb = new StringBuffer(2 * b.length);
for (int i = 0; i < b.length; i++)
{
int v = (256 + b[i]) % 256;
sb.append(hex.charAt((v / 16) & 15));
sb.append(hex.charAt((v % 16) & 15));
}
return sb.toString();
}
/**
* Convert hex string to array of bytes.
*
* @param s
* String containing hexadecimal digits. May be <code>null</code>.
* On odd length leading zero will be assumed.
* @return Array on bytes, non-<code>null</code>.
* @throws IllegalArgumentException
* when string contains non-hex character
*/
public static byte[] hex2bin(final String s)
{
String m = s;
if (s == null)
{
// Allow empty input string.
m = "";
}
else if (s.length() % 2 != 0)
{
// Assume leading zero for odd string length
m = "0" + s;
}
byte r[] = new byte[m.length() / 2];
for (int i = 0, n = 0; i < m.length(); n++)
{
char h = m.charAt(i++);
char l = m.charAt(i++);
r[n] = (byte) (hex2bin(h) * 16 + hex2bin(l));
}
return r;
}
/**
* Convert hex digit to numerical value.
*
* @param c
* 0-9, a-f, A-F allowd.
* @return 0-15
* @throws IllegalArgumentException
* on non-hex character
*/
public static int hex2bin(char c)
{
if (c >= '0' && c <= '9')
{
return (c - '0');
}
if (c >= 'A' && c <= 'F')
{
return (c - 'A' + 10);
}
if (c >= 'a' && c <= 'f')
{
return (c - 'a' + 10);
}
throw new IllegalArgumentException(
"Input string may only contain hex digits, but found '" + c
+ "'");
}
public static void main(String[] args)
{
byte b[] = new byte[256];
byte bb = 0;
for (int i = 0; i < 256; i++)
{
b[i] = bb++;
}
String s = bin2hex(b);
byte c[] = hex2bin(s);
String t = bin2hex(c);
if (!s.equals(t))
{
throw new AssertionError("Mismatch");
}
}
}

View File

@ -0,0 +1,111 @@
package uk.org.whoami.authme.security.pbkdf2;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/**
* Default PRF implementation based on standard javax.crypt.Mac mechanisms.
*
* <hr />
* <p>
* A free Java implementation of Password Based Key Derivation Function 2 as
* defined by RFC 2898. Copyright (c) 2007 Matthias G&auml;rtner
* </p>
* <p>
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* </p>
* <p>
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
* </p>
* <p>
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* </p>
* <p>
* For Details, see <a
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
* </p>
*
* @author Matthias G&auml;rtner
* @version 1.0
*/
public class MacBasedPRF implements PRF
{
protected Mac mac;
protected int hLen;
protected String macAlgorithm;
/**
* Create Mac-based Pseudo Random Function.
*
* @param macAlgorithm
* Mac algorithm to use, i.e. HMacSHA1 or HMacMD5.
*/
public MacBasedPRF(String macAlgorithm)
{
this.macAlgorithm = macAlgorithm;
try
{
mac = Mac.getInstance(macAlgorithm);
hLen = mac.getMacLength();
}
catch (NoSuchAlgorithmException e)
{
throw new RuntimeException(e);
}
}
public MacBasedPRF(String macAlgorithm, String provider)
{
this.macAlgorithm = macAlgorithm;
try
{
mac = Mac.getInstance(macAlgorithm, provider);
hLen = mac.getMacLength();
}
catch (NoSuchAlgorithmException e)
{
throw new RuntimeException(e);
}
catch (NoSuchProviderException e)
{
throw new RuntimeException(e);
}
}
public byte[] doFinal(byte[] M)
{
byte[] r = mac.doFinal(M);
return r;
}
public int getHLen()
{
return hLen;
}
public void init(byte[] P)
{
try
{
mac.init(new SecretKeySpec(P, macAlgorithm));
}
catch (InvalidKeyException e)
{
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,98 @@
package uk.org.whoami.authme.security.pbkdf2;
/**
* <p>
* A free Java implementation of Password Based Key Derivation Function 2 as
* defined by RFC 2898. Copyright (c) 2007 Matthias G&auml;rtner
* </p>
* <p>
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* </p>
* <p>
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
* </p>
* <p>
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* </p>
* <p>
* For Details, see <a
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
* </p>
*
* @author Matthias G&auml;rtner
* @version 1.0
*/
public interface PBKDF2
{
/**
* Convert String-based input to internal byte array, then invoke PBKDF2.
* Desired key length defaults to Pseudo Random Function block size.
*
* @param inputPassword
* Candidate password to compute the derived key for.
* @return internal byte array
*/
public abstract byte[] deriveKey(String inputPassword);
/**
* Convert String-based input to internal byte array, then invoke PBKDF2.
*
* @param inputPassword
* Candidate password to compute the derived key for.
* @param dkLen
* Specify desired key length
* @return internal byte array
*/
public abstract byte[] deriveKey(String inputPassword, int dkLen);
/**
* Convert String-based input to internal byte arrays, then invoke PBKDF2
* and verify result against the reference data that is supplied in the
* PBKDF2Parameters.
*
* @param inputPassword
* Candidate password to compute the derived key for.
* @return <code>true</code> password match; <code>false</code>
* incorrect password
*/
public abstract boolean verifyKey(String inputPassword);
/**
* Allow reading of configured parameters.
*
* @return Currently set parameters.
*/
public abstract PBKDF2Parameters getParameters();
/**
* Allow setting of configured parameters.
*
* @param parameters
*/
public abstract void setParameters(PBKDF2Parameters parameters);
/**
* Get currently set Pseudo Random Function.
*
* @return Currently set Pseudo Random Function
*/
public abstract PRF getPseudoRandomFunction();
/**
* Set the Pseudo Random Function to use. Note that deriveKeys/getPRF does
* init this object using the supplied candidate password. If this is
* undesired, one has to override getPRF.
*
* @param prf
* Pseudo Random Function to set.
*/
public abstract void setPseudoRandomFunction(PRF prf);
}

View File

@ -0,0 +1,401 @@
package uk.org.whoami.authme.security.pbkdf2;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* <p>
* Request for Comments: 2898 PKCS #5: Password-Based Cryptography Specification
* <p>
* Version 2.0
*
* <p>
* PBKDF2 (P, S, c, dkLen)
*
* <p>
* Options:
* <ul>
* <li>PRF underlying pseudorandom function (hLen denotes the length in octets
* of the pseudorandom function output). PRF is pluggable.</li>
* </ul>
*
* <p>
* Input:
* <ul>
* <li>P password, an octet string</li>
* <li>S salt, an octet string</li>
* <li>c iteration count, a positive integer</li>
* <li>dkLen intended length in octets of the derived key, a positive integer,
* at most (2^32 - 1) * hLen</li>
* </ul>
*
* <p>
* Output:
* <ul>
* <li>DK derived key, a dkLen-octet string</li>
* </ul>
*
* <hr />
* <p>
* A free Java implementation of Password Based Key Derivation Function 2 as
* defined by RFC 2898. Copyright (c) 2007 Matthias G&auml;rtner
* </p>
* <p>
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* </p>
* <p>
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
* </p>
* <p>
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* </p>
* <p>
* For Details, see <a
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
* </p>
*
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898</a>
* @author Matthias G&auml;rtner
* @version 1.0
*/
public class PBKDF2Engine implements PBKDF2
{
protected PBKDF2Parameters parameters;
protected PRF prf;
/**
* Constructor for PBKDF2 implementation object. PBKDF2 parameters must be
* passed later.
*/
public PBKDF2Engine()
{
this.parameters = null;
prf = null;
}
/**
* Constructor for PBKDF2 implementation object. PBKDF2 parameters are
* passed so that this implementation knows iteration count, method to use
* and String encoding.
*
* @param parameters
* Data holder for iteration count, method to use et cetera.
*/
public PBKDF2Engine(PBKDF2Parameters parameters)
{
this.parameters = parameters;
prf = null;
}
/**
* Constructor for PBKDF2 implementation object. PBKDF2 parameters are
* passed so that this implementation knows iteration count, method to use
* and String encoding.
*
* @param parameters
* Data holder for iteration count, method to use et cetera.
* @param prf
* Supply customer Pseudo Random Function.
*/
public PBKDF2Engine(PBKDF2Parameters parameters, PRF prf)
{
this.parameters = parameters;
this.prf = prf;
}
public byte[] deriveKey(String inputPassword)
{
return deriveKey(inputPassword, 0);
}
public byte[] deriveKey(String inputPassword, int dkLen)
{
byte[] r = null;
byte P[] = null;
String charset = parameters.getHashCharset();
if (inputPassword == null)
{
inputPassword = "";
}
try
{
if (charset == null)
{
P = inputPassword.getBytes();
}
else
{
P = inputPassword.getBytes(charset);
}
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
assertPRF(P);
if (dkLen == 0)
{
dkLen = prf.getHLen();
}
r = PBKDF2(prf, parameters.getSalt(), parameters.getIterationCount(),
dkLen);
return r;
}
public boolean verifyKey(String inputPassword)
{
byte[] referenceKey = getParameters().getDerivedKey();
if (referenceKey == null || referenceKey.length == 0)
{
return false;
}
byte[] inputKey = deriveKey(inputPassword, referenceKey.length);
if (inputKey == null || inputKey.length != referenceKey.length)
{
return false;
}
for (int i = 0; i < inputKey.length; i++)
{
if (inputKey[i] != referenceKey[i])
{
return false;
}
}
return true;
}
/**
* Factory method. Default implementation is (H)MAC-based. To be overridden
* in derived classes.
*
* @param P
* User-supplied candidate password as array of bytes.
*/
protected void assertPRF(byte[] P)
{
if (prf == null)
{
prf = new MacBasedPRF(parameters.getHashAlgorithm());
}
prf.init(P);
}
public PRF getPseudoRandomFunction()
{
return prf;
}
/**
* Core Password Based Key Derivation Function 2.
*
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898 5.2</a>
* @param prf
* Pseudo Random Function (i.e. HmacSHA1)
* @param S
* Salt as array of bytes. <code>null</code> means no salt.
* @param c
* Iteration count (see RFC 2898 4.2)
* @param dkLen
* desired length of derived key.
* @return internal byte array
*/
protected byte[] PBKDF2(PRF prf, byte[] S, int c, int dkLen)
{
if (S == null)
{
S = new byte[0];
}
int hLen = prf.getHLen();
int l = ceil(dkLen, hLen);
int r = dkLen - (l - 1) * hLen;
byte T[] = new byte[l * hLen];
int ti_offset = 0;
for (int i = 1; i <= l; i++)
{
_F(T, ti_offset, prf, S, c, i);
ti_offset += hLen;
}
if (r < hLen)
{
// Incomplete last block
byte DK[] = new byte[dkLen];
System.arraycopy(T, 0, DK, 0, dkLen);
return DK;
}
return T;
}
/**
* Integer division with ceiling function.
*
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898 5.2 Step 2.</a>
* @param a
* @param b
* @return ceil(a/b)
*/
protected int ceil(int a, int b)
{
int m = 0;
if (a % b > 0)
{
m = 1;
}
return a / b + m;
}
/**
* Function F.
*
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898 5.2 Step 3.</a>
* @param dest
* Destination byte buffer
* @param offset
* Offset into destination byte buffer
* @param prf
* Pseudo Random Function
* @param S
* Salt as array of bytes
* @param c
* Iteration count
* @param blockIndex
*/
protected void _F(byte[] dest, int offset, PRF prf, byte[] S, int c,
int blockIndex)
{
int hLen = prf.getHLen();
byte U_r[] = new byte[hLen];
// U0 = S || INT (i);
byte U_i[] = new byte[S.length + 4];
System.arraycopy(S, 0, U_i, 0, S.length);
INT(U_i, S.length, blockIndex);
for (int i = 0; i < c; i++)
{
U_i = prf.doFinal(U_i);
xor(U_r, U_i);
}
System.arraycopy(U_r, 0, dest, offset, hLen);
}
/**
* Block-Xor. Xor source bytes into destination byte buffer. Destination
* buffer must be same length or less than source buffer.
*
* @param dest
* @param src
*/
protected void xor(byte[] dest, byte[] src)
{
for (int i = 0; i < dest.length; i++)
{
dest[i] ^= src[i];
}
}
/**
* Four-octet encoding of the integer i, most significant octet first.
*
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898 5.2 Step 3.</a>
* @param dest
* @param offset
* @param i
*/
protected void INT(byte[] dest, int offset, int i)
{
dest[offset + 0] = (byte) (i / (256 * 256 * 256));
dest[offset + 1] = (byte) (i / (256 * 256));
dest[offset + 2] = (byte) (i / (256));
dest[offset + 3] = (byte) (i);
}
public PBKDF2Parameters getParameters()
{
return parameters;
}
public void setParameters(PBKDF2Parameters parameters)
{
this.parameters = parameters;
}
public void setPseudoRandomFunction(PRF prf)
{
this.prf = prf;
}
/**
* Convenience client function. Convert supplied password with random 8-byte
* salt and 1000 iterations using HMacSHA1. Assume that password is in
* ISO-8559-1 encoding. Output result as
* &quot;Salt:iteration-count:PBKDF2&quot; with binary data in hexadecimal
* encoding.
*
* Example: Password &quot;password&quot; (without the quotes) leads to
* 48290A0B96C426C3:1000:973899B1D4AFEB3ED371060D0797E0EE0142BD04
*
* @param args
* Supply the password as argument.
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public static void main(String[] args) throws IOException,
NoSuchAlgorithmException
{
String password = "password";
String candidate = null;
PBKDF2Formatter formatter = new PBKDF2HexFormatter();
if (args.length >= 1)
{
password = args[0];
}
if (args.length >= 2)
{
candidate = args[1];
}
if (candidate == null)
{
// Creation mode
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[8];
sr.nextBytes(salt);
int iterations = 1000;
PBKDF2Parameters p = new PBKDF2Parameters("HmacSHA1", "ISO-8859-1",
salt, iterations);
PBKDF2Engine e = new PBKDF2Engine(p);
p.setDerivedKey(e.deriveKey(password));
candidate = formatter.toString(p);
System.out.println(candidate);
}
else
{
// Verification mode
PBKDF2Parameters p = new PBKDF2Parameters();
p.setHashAlgorithm("HmacSHA1");
p.setHashCharset("ISO-8859-1");
if (formatter.fromString(p, candidate))
{
throw new IllegalArgumentException(
"Candidate data does not have correct format (\""
+ candidate + "\")");
}
PBKDF2Engine e = new PBKDF2Engine(p);
boolean verifyOK = e.verifyKey(password);
System.out.println(verifyOK ? "OK" : "FAIL");
System.exit(verifyOK ? 0 : 1);
}
}
}

View File

@ -0,0 +1,54 @@
package uk.org.whoami.authme.security.pbkdf2;
/**
* <p>
* A free Java implementation of Password Based Key Derivation Function 2 as
* defined by RFC 2898. Copyright (c) 2007 Matthias G&auml;rtner
* </p>
* <p>
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* </p>
* <p>
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
* </p>
* <p>
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* </p>
* <p>
* For Details, see <a
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
* </p>
*
* @author Matthias G&auml;rtner
* @version 1.0
*/
public interface PBKDF2Formatter
{
/**
* Convert parameters to String.
*
* @param p
* Parameters object to output.
* @return String representation
*/
public abstract String toString(PBKDF2Parameters p);
/**
* Convert String to parameters. Depending on actual implementation, it may
* be required to set further fields externally.
*
* @param s
* String representation of parameters to decode.
* @return <code>false</code> syntax OK, <code>true</code> some syntax
* issue.
*/
public abstract boolean fromString(PBKDF2Parameters p, String s);
}

View File

@ -0,0 +1,65 @@
package uk.org.whoami.authme.security.pbkdf2;
/**
* <p>
* A free Java implementation of Password Based Key Derivation Function 2 as
* defined by RFC 2898. Copyright (c) 2007 Matthias G&auml;rtner
* </p>
* <p>
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* </p>
* <p>
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
* </p>
* <p>
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* </p>
* <p>
* For Details, see <a
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
* </p>
*
* @author Matthias G&auml;rtner
* @version 1.0
*/
public class PBKDF2HexFormatter implements PBKDF2Formatter
{
public boolean fromString(PBKDF2Parameters p, String s)
{
if (p == null || s == null)
{
return true;
}
String[] p123 = s.split(":");
if (p123 == null || p123.length != 3)
{
return true;
}
byte salt[] = BinTools.hex2bin(p123[0]);
int iterationCount = Integer.parseInt(p123[1]);
byte bDK[] = BinTools.hex2bin(p123[2]);
p.setSalt(salt);
p.setIterationCount(iterationCount);
p.setDerivedKey(bDK);
return false;
}
public String toString(PBKDF2Parameters p)
{
String s = BinTools.bin2hex(p.getSalt()) + ":"
+ String.valueOf(p.getIterationCount()) + ":"
+ BinTools.bin2hex(p.getDerivedKey());
return s;
}
}

View File

@ -0,0 +1,165 @@
package uk.org.whoami.authme.security.pbkdf2;
/**
* <p>
* Parameter data holder for PBKDF2 configuration.
* </p>
*
* <hr />
* <p>
* A free Java implementation of Password Based Key Derivation Function 2 as
* defined by RFC 2898. Copyright (c) 2007 Matthias G&auml;rtner
* </p>
* <p>
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* </p>
* <p>
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
* </p>
* <p>
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* </p>
* <p>
* For Details, see <a
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
* </p>
*
* @author Matthias G&auml;rtner
* @version 1.0
*/
public class PBKDF2Parameters
{
protected byte[] salt;
protected int iterationCount;
protected String hashAlgorithm;
protected String hashCharset;
/**
* The derived key is actually only a convenience to store a reference
* derived key. It is not used during computation.
*/
protected byte[] derivedKey;
/**
* Constructor. Defaults to <code>null</code> for byte arrays, UTF-8 as
* character set and 1000 for iteration count.
*
*/
public PBKDF2Parameters()
{
this.hashAlgorithm = null;
this.hashCharset = "UTF-8";
this.salt = null;
this.iterationCount = 1000;
this.derivedKey = null;
}
/**
* Constructor.
*
* @param hashAlgorithm
* for example HMacSHA1 or HMacMD5
* @param hashCharset
* for example UTF-8
* @param salt
* Salt as byte array, may be <code>null</code> (not
* recommended)
* @param iterationCount
* Number of iterations to execute. Recommended value 1000.
*/
public PBKDF2Parameters(String hashAlgorithm, String hashCharset,
byte[] salt, int iterationCount)
{
this.hashAlgorithm = hashAlgorithm;
this.hashCharset = hashCharset;
this.salt = salt;
this.iterationCount = iterationCount;
this.derivedKey = null;
}
/**
* Constructor.
*
* @param hashAlgorithm
* for example HMacSHA1 or HMacMD5
* @param hashCharset
* for example UTF-8
* @param salt
* Salt as byte array, may be <code>null</code> (not
* recommended)
* @param iterationCount
* Number of iterations to execute. Recommended value 1000.
* @param derivedKey
* Convenience data holder, not used during computation.
*/
public PBKDF2Parameters(String hashAlgorithm, String hashCharset,
byte[] salt, int iterationCount, byte[] derivedKey)
{
this.hashAlgorithm = hashAlgorithm;
this.hashCharset = hashCharset;
this.salt = salt;
this.iterationCount = iterationCount;
this.derivedKey = derivedKey;
}
public int getIterationCount()
{
return iterationCount;
}
public void setIterationCount(int iterationCount)
{
this.iterationCount = iterationCount;
}
public byte[] getSalt()
{
return salt;
}
public void setSalt(byte[] salt)
{
this.salt = salt;
}
public byte[] getDerivedKey()
{
return derivedKey;
}
public void setDerivedKey(byte[] derivedKey)
{
this.derivedKey = derivedKey;
}
public String getHashAlgorithm()
{
return hashAlgorithm;
}
public void setHashAlgorithm(String hashAlgorithm)
{
this.hashAlgorithm = hashAlgorithm;
}
public String getHashCharset()
{
return hashCharset;
}
public void setHashCharset(String hashCharset)
{
this.hashCharset = hashCharset;
}
}

View File

@ -0,0 +1,60 @@
package uk.org.whoami.authme.security.pbkdf2;
/**
* <p>
* A free Java implementation of Password Based Key Derivation Function 2 as
* defined by RFC 2898. Copyright (c) 2007 Matthias G&auml;rtner
* </p>
* <p>
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* </p>
* <p>
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
* </p>
* <p>
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* </p>
* <p>
* For Details, see <a
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
* </p>
*
* @author Matthias G&auml;rtner
* @version 1.0
*/
public interface PRF
{
/**
* Initialize this instance with the user-supplied password.
*
* @param P
* The password supplied as array of bytes. It is the caller's
* task to convert String passwords to bytes as appropriate.
*/
public void init(byte[] P);
/**
* Pseudo Random Function
*
* @param M
* Input data/message etc. Together with any data supplied during
* initilization.
* @return Random bytes of hLen length.
*/
public byte[] doFinal(byte[] M);
/**
* Query block size of underlying algorithm/mechanism.
*
* @return block size
*/
public int getHLen();
}

View File

@ -299,7 +299,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public boolean updateSession(PlayerAuth auth) {
public synchronized boolean updateSession(PlayerAuth auth) {
Connection con = null;
PreparedStatement pst = null;
try {
@ -323,7 +323,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public int purgeDatabase(long until) {
public synchronized int purgeDatabase(long until) {
Connection con = null;
PreparedStatement pst = null;
try {
@ -366,7 +366,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public boolean updateQuitLoc(PlayerAuth auth) {
public synchronized boolean updateQuitLoc(PlayerAuth auth) {
Connection con = null;
PreparedStatement pst = null;
try {
@ -392,7 +392,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public int getIps(String ip) {
public synchronized int getIps(String ip) {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
@ -421,7 +421,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public boolean updateEmail(PlayerAuth auth) {
public synchronized boolean updateEmail(PlayerAuth auth) {
Connection con = null;
PreparedStatement pst = null;
try {
@ -444,7 +444,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public boolean updateSalt(PlayerAuth auth) {
public synchronized boolean updateSalt(PlayerAuth auth) {
if (columnSalt.isEmpty()) {
return false;
}
@ -513,7 +513,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public List<String> getAllAuthsByName(PlayerAuth auth) {
public synchronized List<String> getAllAuthsByName(PlayerAuth auth) {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
@ -542,7 +542,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public List<String> getAllAuthsByIp(String ip) {
public synchronized List<String> getAllAuthsByIp(String ip) {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
@ -571,7 +571,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public List<String> getAllAuthsByEmail(String email) {
public synchronized List<String> getAllAuthsByEmail(String email) {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
@ -600,7 +600,7 @@ public class MySQLThread extends Thread implements DataSource {
}
@Override
public void purgeBanned(List<String> banned) {
public synchronized void purgeBanned(List<String> banned) {
Connection con = null;
PreparedStatement pst = null;
try {
@ -617,4 +617,35 @@ public class MySQLThread extends Thread implements DataSource {
close(con);
}
}
/* public synchronized boolean makeSureConnectionIsReady() {
try {
conPool.getValidConnection();
return true;
} catch (TimeoutException te) {
try {
reconnect();
} catch (TimeoutException e) {
return false;
} catch (ClassNotFoundException e) {
return false;
} catch (SQLException e) {
return false;
}
return true;
}
}
private synchronized void reconnect() throws ClassNotFoundException, SQLException, TimeoutException {
conPool.dispose();
Class.forName("com.mysql.jdbc.Driver");
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
dataSource.setDatabaseName(database);
dataSource.setServerName(host);
dataSource.setPort(Integer.parseInt(port));
dataSource.setUser(username);
dataSource.setPassword(password);
conPool = new MiniConnectionPoolManager(dataSource, 10);
ConsoleLogger.info("Connection pool reconnected");
} */
}

View File

@ -123,6 +123,7 @@ public class SQLiteThread extends Thread implements DataSource {
+ "ALTER TABLE " + tableName + " ADD COLUMN " + lastlocZ + " smallint(6) NOT NULL DEFAULT '0';");
}
rs.close();
rs = con.getMetaData().getColumns(null, null, tableName, lastlocWorld);
if (!rs.next()) {
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT 'world' AFTER " + lastlocZ + ";");
}

View File

@ -15,7 +15,7 @@ no_perm: '&cSem permissao!'
error: '&fOcorreu um erro de sistema, por favor reporte ao ADM.'
login_msg: '&cPara entrar digite: "/login password"'
reg_msg: '&cPara registrar um nick digite: "/register senha senha"'
reg_email_msg: '&cPlease register with "/register <email> <confirmEmail>"'
reg_email_msg: '&cPara registrar um nick digite: "/register <e-mail> <e-mail>"'
usage_unreg: '&cPara desregistrar digite: /unregister senha'
pwd_changed: '&cSenha modificada!'
user_unknown: '&cNome de usuario nao existe. Verifique.'
@ -29,23 +29,23 @@ registered: '&cRegistrado com sucesso!'
pass_len: '&fSenha muito curta.'
reload: '&fAuthMe Recarregado.'
timeout: '&fDemorou....'
name_len: '&cYour nickname is too Short or too long'
regex: '&cYour nickname contains illegal characters. Allowed chars: REG_EX'
add_email: '&cPlease add your email with : /email add yourEmail confirmEmail'
bad_database_email: '[AuthMe] This /email command only available with MySQL and SQLite, contact an Admin'
recovery_email: '&cForgot your password? Please use /email recovery <yourEmail>'
usage_captcha: '&cUsage: /captcha <theCaptcha>'
wrong_captcha: '&cWrong Captcha, please use : /captcha THE_CAPTCHA'
valid_captcha: '&cYour captcha is valid !'
kick_forvip: '&cA VIP Player join the full server!'
name_len: '&cSeu nome de usuário é muito longo'
regex: '&cSeu nome de usuário tem caracteres ilegais. Permitido: REG_EX'
add_email: '&cAdicione seu e-mail, digite: /email add e-mail e-mail'
bad_database_email: '[AuthMe] Comando /email disponibilizado apenas com MySQL e SQLite, contate um Admin'
recovery_email: '&cEsqueceu sua senha? Digite /email recovery <e-mail>'
usage_captcha: '&cDigite: /captcha <theCaptcha>'
wrong_captcha: '&Captcha errado, digite: /captcha THE_CAPTCHA'
valid_captcha: '&cSeu captcha é válido!'
kick_forvip: '&cUsuário VIP entrou no servidor cheio!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'
email_invalid: '[AuthMe] Invalid Email'
email_added: '[AuthMe] Email Added !'
email_confirm: '[AuthMe] Confirm your Email !'
email_changed: '[AuthMe] Email Change !'
email_send: '[AuthMe] Recovery Email Send !'
usage_email_add: '&fDigite: /email add <e-mail> <e-mail> '
usage_email_change: '&fDigite: /email change <e-mailAnterior> <novoE-mail> '
usage_email_recovery: '&fDigite: /email recovery <e-mail>'
new_email_invalid: '[AuthMe] Novo e-mail inválido!'
old_email_invalid: '[AuthMe] E-mail anterior, inválido!'
email_invalid: '[AuthMe] E-mail iválido'
email_added: '[AuthMe] E-mail adicionado com sucesso!'
email_confirm: '[AuthMe] Confirme seu e-mail!'
email_changed: '[AuthMe] E-mail alterado!'
email_send: '[AuthMe] E-mail com nova senha enviado!'

View File

@ -41,8 +41,8 @@ wrong_captcha: '&cSpatne opsana Captcha, pouzij prosim: /captcha CAPTCHA_TEXT'
valid_captcha: '&cZadana captcha je OK !'
kick_forvip: '&cA VIP Hrac se pripojil na plny server!'
kick_fullserver: '&cServer je plne obsazen, zkus to pozdeji prosim !'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> newEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'

View File

@ -41,8 +41,8 @@ wrong_captcha: '&cFalsches Captcha, bitte nutze: /captcha <dasCaptcha>'
valid_captcha: '&cDas Captcha ist korrekt!'
kick_forvip: '&cEin VIP Spieler hat den vollen Server betreten!'
kick_fullserver: '&cDer Server ist momentan voll, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'

View File

@ -41,8 +41,8 @@ wrong_captcha: '&cWrong Captcha, please use : /captcha THE_CAPTCHA'
valid_captcha: '&cYour captcha is valid !'
kick_forvip: '&cA VIP Player join the full server!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_add: '&fUsage: /email add <email> <confirmeEmail> '
usage_email_change: '&fUsage: /email change oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'

View File

@ -42,8 +42,8 @@ wrong_captcha: '&cCaptcha incorrecto, please use : /captcha EL_CAPTCHA'
valid_captcha: '&c¡ Captcha ingresado correctamente !'
kick_forvip: '&cA VIP Player join the full server!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'

View File

@ -41,8 +41,8 @@ wrong_captcha: '&cVäärä varmistus, käytä : /captcha THE_CAPTCHA'
valid_captcha: '&cSinun varmistus epäonnistui.!'
kick_forvip: '&cA VIP Player join the full server!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'

View File

@ -41,8 +41,8 @@ wrong_captcha: '&cWrong Captcha, please use : /captcha THE_CAPTCHA'
valid_captcha: '&cYour captcha is valid !'
kick_forvip: '&cA VIP Player join the full server!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'

View File

@ -41,13 +41,13 @@ wrong_captcha: '&cCaptcha sbagliato, perfavore fai: /captcha THE_CAPTCHA'
valid_captcha: "&cIl tuo captcha è valido!"
kick_forvip: "&cUn player VIP è entrato mentre il server era pieno!"
kick_fullserver: "&cIl server è attualmente pieno, ci dispiace!"
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'
email_invalid: '[AuthMe] Invalid Email'
email_added: '[AuthMe] Email Added !'
email_confirm: '[AuthMe] Confirm your Email !'
email_changed: '[AuthMe] Email Change !'
email_send: '[AuthMe] Recovery Email Send !'
usage_email_add: '&fUtilizzo: /email add <email> <confermaEmail>'
usage_email_change: '&fUtilizzo: /email change <vecchiaEmail> <nuovaEmail>'
usage_email_recovery: '&fUtilizzo: /email recovery <email>'
new_email_invalid: '[AuthMe] La nuova email non è valida!'
old_email_invalid: '[AuthMe] La vecchia email non è valida!'
email_invalid: "[AuthMe] L'email non è valida"
email_added: '[AuthMe] Email Aggiunta!'
email_confirm: '[AuthMe] Conferma la tua Email!'
email_changed: '[AuthMe] Email cambiata!'
email_send: '[AuthMe] Email di recupero inviata!'

View File

@ -1,53 +1,53 @@
unknown_user: 사용자는 데이터베이스에 없습니다
unsafe_spawn: 당신이 나갔던 위치는 안전하지 않았습니다, 당신을 윌드 스폰으로 텔레포트시킵니다
not_logged_in: '&c로그인하지 않았습니다!'
reg_voluntarily: 당신이 서버에 게정을 등록하고 싶다면 "/register 비밀번호 비밀번호재입력"을 치세요
usage_log: '&c사용법: /login 비밀번호'
wrong_pwd: '&c잘못된 비밀번호입니다'
unregistered: '&c성공적으로 회원탈퇴되었습니다!'
reg_disabled: '&c회원가입이 성공적으로 비활성화되었습니다'
valid_session: '&c세션 로그인'
login: '&c성공적으로 로그인 되었습니다!'
vb_nonActiv: 당신의 계정은 활성화되어 있지 않습니다 당신의 이메일을 체크해주세요!
user_regged: '&c사용자 이름은 이미 등록되어 있습니다'
usage_reg: '&c사용법: /register 비밀번호 비밀번호재입력'
max_reg: 당신은 가입할 수 있는 계정의 최대 한도 수를 넘었습니다
no_perm: '&c권한이 없습니다'
error: 오류가 발생했습니다; 관리자한테 문의하세요
login_msg: '&c로그인 하실려면 "/login 비밀번호"를 치세요'
reg_msg: '&c가입하실려면 "/register 비밀번호 비밀번호재입력"을 치세요'
reg_email_msg: '&c가입하실려면 "/register <이메일> <이메일재입력>을 치세요"'
usage_unreg: '&c사용법: /unregister 비밀번호'
pwd_changed: '&c비밀번호가 변경되었습니다!'
user_unknown: '&c사용자 이름은 등록되지 않았습니다'
password_error: 비밀번호가 일치하지 않습니다
unvalid_session: Session Dataes doesnt corrispond 세션이 끝날때 까지 기달려주세요
reg_only: 회원가입은 플레이어만 할 수 있습니다! http://example.com 에 가입해주세요
logged_in: '&c이미 로그인되어 있습니다!'
logout: '&c성공적으로 로그아웃되었습니다'
same_nick: 같은 닉네임이 이미 게임중입니다
registered: '&c성공적으로 회원가입되었습니다!'
pass_len: 당신의 비밀번호는 최소 글자나 최대글자를 초과하였습니다 적당한 비밀번호 글자로 해주세요
reload: 설정과 데이터베이스가 리로드되었습니다
timeout: 로그인 시간 초과
usage_changepassword: '사용법: /changepassword 기존비밀번호 새비밀번호'
name_len: '&c당신의 닉네임은 너무 길거나 짧습니다'
regex: '&c당신의 닉네임에 잘못된 문자가 포함되어 있습니다. 허용된 글자: REG_EX'
add_email: '&c당신의 이메일을 : /email add yourEmail confirmEmail 명령어로 추가해주세요'
bad_database_email: '[AuthMe] /email 명령어는 오직 MySQL 와 SQLite에서만 가능합니다, 관리자에게 문의해보세요'
recovery_email: '&c비밀번호를 잊어버리셨다고요? /email recovery <자신의이메일>을 사용해서 복구해보세요'
usage_captcha: '&c사용법: /captcha <캡차>'
wrong_captcha: '&c잘못된 캡차입니다, 올바른 사용법 : /captcha THE_CAPTCHA'
valid_captcha: '&c당신의 캡차는 올바릅니다 !'
kick_forvip: '&c한 VIP 플레이어가 만원인 서버에 입장했습니다!!'
kick_fullserver: '&c그 서버는 실제로 만원입니다, 미안!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'
email_invalid: '[AuthMe] Invalid Email'
email_added: '[AuthMe] Email Added !'
email_confirm: '[AuthMe] Confirm your Email !'
email_changed: '[AuthMe] Email Change !'
email_send: '[AuthMe] Recovery Email Send !'
unknown_user: 사용자는 데이터베이스에 없습니다
unsafe_spawn: 당신이 나갔던 위치는 안전하지 않았습니다, 당신을 윌드 스폰으로 텔레포트시킵니다
not_logged_in: '&c로그인하지 않았습니다!'
reg_voluntarily: 당신이 서버에 게정을 등록하고 싶다면 "/register 비밀번호 비밀번호재입력"을 치세요
usage_log: '&c사용법: /login 비밀번호'
wrong_pwd: '&c잘못된 비밀번호입니다'
unregistered: '&c성공적으로 회원탈퇴되었습니다!'
reg_disabled: '&c회원가입이 성공적으로 비활성화되었습니다'
valid_session: '&c세션 로그인'
login: '&c성공적으로 로그인 되었습니다!'
vb_nonActiv: 당신의 계정은 활성화되어 있지 않습니다 당신의 이메일을 체크해주세요!
user_regged: '&c사용자 이름은 이미 등록되어 있습니다'
usage_reg: '&c사용법: /register 비밀번호 비밀번호재입력'
max_reg: 당신은 가입할 수 있는 계정의 최대 한도 수를 넘었습니다
no_perm: '&c권한이 없습니다'
error: 오류가 발생했습니다; 관리자한테 문의하세요
login_msg: '&c로그인 하실려면 "/login 비밀번호"를 치세요'
reg_msg: '&c가입하실려면 "/register 비밀번호 비밀번호재입력"을 치세요'
reg_email_msg: '&c가입하실려면 "/register <이메일> <이메일재입력>을 치세요"'
usage_unreg: '&c사용법: /unregister 비밀번호'
pwd_changed: '&c비밀번호가 변경되었습니다!'
user_unknown: '&c사용자 이름은 등록되지 않았습니다'
password_error: 비밀번호가 일치하지 않습니다
unvalid_session: 세션 데이터베이스가 일치하지 않습니다 세션이 끝날때 까지 기달려주세요
reg_only: 회원가입은 플레이어만 할 수 있습니다! http://example.com 에 가입해주세요
logged_in: '&c이미 로그인되어 있습니다!'
logout: '&c성공적으로 로그아웃되었습니다'
same_nick: 같은 닉네임이 이미 게임중입니다
registered: '&c성공적으로 회원가입되었습니다!'
pass_len: 당신의 비밀번호는 최소 글자나 최대글자를 초과하였습니다 적당한 비밀번호 글자로 해주세요
reload: 설정과 데이터베이스가 리로드되었습니다
timeout: 로그인 시간 초과
usage_changepassword: '사용법: /changepassword 기존비밀번호 새비밀번호'
name_len: '&c당신의 닉네임은 너무 길거나 짧습니다'
regex: '&c당신의 닉네임에 잘못된 문자가 포함되어 있습니다. 허용된 글자: REG_EX'
add_email: '&c당신의 이메일을 : /email add yourEmail confirmEmail 명령어로 추가해주세요'
bad_database_email: '[AuthMe] /email 명령어는 오직 MySQL 와 SQLite에서만 가능합니다, 관리자에게 문의해보세요'
recovery_email: '&c비밀번호를 잊어버리셨다고요? /email recovery <자신의이메일>을 사용해서 복구해보세요'
usage_captcha: '&c사용법: /captcha <캡차>'
wrong_captcha: '&c잘못된 캡차입니다, 올바른 사용법 : /captcha THE_CAPTCHA'
valid_captcha: '&c당신의 캡차는 올바릅니다 !'
kick_forvip: '&c한 VIP 플레이어가 만원인 서버에 입장했습니다!!'
kick_fullserver: '&c그 서버는 실제로 만원입니다, 미안!'
usage_email_add: '&f사용법: /email add <이메일> <이메일재입력> '
usage_email_change: '&f사용법: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&f사용법: /email recovery <이메일>'
new_email_invalid: '[AuthMe] 새 이메일이 잘못되었습니다!'
old_email_invalid: '[AuthMe] 기존 이메일이 잘못되었습니다!'
email_invalid: '[AuthMe] 이메일이 잘못되었습니다'
email_added: '[AuthMe] 이메일 추가됨 !'
email_confirm: '[AuthMe] 이메일을 확인해주세요 !'
email_changed: '[AuthMe] 이메일 변경됨 !'
email_send: '[AuthMe] 복구 이메일 발송됨 !'

View File

@ -41,9 +41,9 @@ wrong_captcha: '&cNeteisinga Captcha, naudokite : /captcha THE_CAPTCHA'
valid_captcha: '&cJusu captcha Teisinga!'
kick_forvip: '&cA VIP prisijunge i pilna serveri!'
kick_fullserver: '&cServeris yra pilnas, Atsiprasome.'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'
email_invalid: '[AuthMe] Invalid Email'

View File

@ -41,9 +41,9 @@ wrong_captcha: '&cWrong Captcha, please use : /captcha THE_CAPTCHA'
valid_captcha: '&cYour captcha is valid !'
kick_forvip: '&cA VIP Player join the full server!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'
email_invalid: '[AuthMe] Invalid Email'

View File

@ -15,7 +15,7 @@ max_reg: '&cAtingiu o numero máximo de registos permitidos'
no_perm: '&cSem Permissões'
error: '&fOcorreu um erro; Por favor contacte um admin'
login_msg: '&cIdentifique-se com "/login password"'
reg_msg: '&cPor favor registe-se com "/register password ConfirmePassword"'
reg_msg: '&cPor favor registe-se com "/register password confirmePassword"'
reg_email_msg: '&ePor favor registe-se com "/register <email> <confirmarEmail>"'
usage_unreg: '&cUse: /unregister password'
pwd_changed: '&cPassword alterada!'
@ -37,14 +37,14 @@ add_email: '&cPor favor adicione o seu email com : /email add seuEmail confirmar
bad_database_email: '[AuthMe] O comando /email não está disponível contacte o staff via ticket'
recovery_email: '&cPerdeu a sua password? Para a recuperar escreva /email recovery <seuEmail>'
usage_captcha: '&cUse: /captcha <theCaptcha>'
wrong_captcha: '&cCaptcha errado, por favor use : /captcha THE_CAPTCHA'
wrong_captcha: '&cCaptcha errado, por favor use: /captcha THE_CAPTCHA'
valid_captcha: '&cO seu captcha é válido!'
kick_forvip: '&cUm jogador VIP entrou no servidor cheio!'
kick_fullserver: '&cO servidor está actualmente cheio, lamentamos!'
usage_email_add: '&fUse: /email add <Email> <confirmeEmail> '
usage_email_add: '&fUse: /email add <email> <confirmeEmail> '
usage_email_change: '&fUse: /email change <emailAntigo> <emailNovo> '
usage_email_recovery: '&fUse: /email recovery <Email>'
email_add: '/email add <Email> <confirmEmail>'
usage_email_recovery: '&fUse: /email recovery <email>'
email_add: '/email add <email> <confirmeEmail>'
new_email_invalid: 'Novo email inválido!'
old_email_invalid: 'Email antigo inválido!'
email_invalid: 'Email inválido!'

View File

@ -46,9 +46,9 @@ wrong_captcha: '&cWrong Captcha, please use : /captcha THE_CAPTCHA'
valid_captcha: '&cYour captcha is valid !'
kick_forvip: '&cA VIP Player join the full server!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'
email_invalid: '[AuthMe] Invalid Email'

View File

@ -10,7 +10,7 @@ usage_reg: '&cPríkaz: /register heslo zopakujHeslo'
usage_log: '&cPríkaz: /login heslo'
user_unknown: '&cZadané meno nie je zaregistrované!'
pwd_changed: '&cHeslo zmenené!'
reg_only: '&fVstup iba pre registrovanych! Navstiv http://www.cs-gaming.eu pre registráciu'
reg_only: '&fVstup iba pre registrovanych! Navstiv http://example.com pre registráciu'
valid_session: '&cZapamätané prihlásenie'
login_msg: '&cPrihlás sa príkazom "/login heslo"'
reg_msg: '&cZaregistruj sa príkazom "/register heslo zopakujHeslo"'
@ -45,9 +45,9 @@ wrong_captcha: '&cWrong Captcha, please use : /captcha THE_CAPTCHA'
valid_captcha: '&cYour captcha is valid !'
kick_forvip: '&cA VIP Player join the full server!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'
email_invalid: '[AuthMe] Invalid Email'

View File

@ -41,9 +41,9 @@ wrong_captcha: '&c错误的验证码请输入“/captcha <验证码>”'
valid_captcha: '&c你的验证码是有效的'
kick_forvip: '&cA VIP Player join the full server!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'
email_invalid: '[AuthMe] Invalid Email'

View File

@ -22,7 +22,7 @@ pwd_changed: '&c你成功的更換了你的密碼 '
user_unknown: '&c此用戶名沒有已登記資料 。'
password_error: '&f密碼不符合 。'
unvalid_session: '&f登入階段資料已損壞 請等待登入階段結束 。'
reg_only: '&f限已註冊會員 請先到 http://member.usociety.org 註冊 。'
reg_only: '&f限已註冊會員 請先到 http://example.com 註冊 。'
logged_in: '&c你已經登入過了 。'
logout: '&b你成功的登出了 。'
same_nick: '&f同名玩家已在遊玩 。'
@ -41,9 +41,9 @@ wrong_captcha: '&c你輸入了錯誤的驗證碼請使用 《 /captcha <驗
valid_captcha: '&c你的驗證碼是無效的 '
kick_forvip: '&cA VIP Player join the full server!'
kick_fullserver: '&cThe server is actually full, Sorry!'
usage_email_add: '&fUsage: /email add <Email> <ConfirmeEmail> '
usage_email_change: '&fUsage: /email change <EmailAntigo> <NovoEmail> '
usage_email_recovery: '&fUsage: /email recovery <Email>'
usage_email_add: '&fUsage: /email add <email> <confirmEmail> '
usage_email_change: '&fUsage: /email change <oldEmail> <newEmail> '
usage_email_recovery: '&fUsage: /email recovery <email>'
new_email_invalid: '[AuthMe] New email invalid!'
old_email_invalid: '[AuthMe] Old email invalid!'
email_invalid: '[AuthMe] Invalid Email'

View File

@ -3,7 +3,7 @@ author: Xephi59
website: http://www.multiplayer-italia.com/
description: AuthMe prevents people, which aren't logged in, from doing stuff like placing blocks, moving, typing commands or seeing the inventory of the current player.
main: uk.org.whoami.authme.AuthMe
version: 2.9.2
version: 2.9.3
softdepend: [Vault, ChestShop, Spout, Multiverse-Core, Notifications, Citizens, CombatTag, Essentials, EssentialsSpawn]
commands:
register: