Merge branch 'master' of https://github.com/AuthMe/AuthMeReloaded into 792-add-registration-date-and-ip

This commit is contained in:
ljacqu
2017-10-21 10:46:17 +02:00
21 changed files with 195 additions and 130 deletions
@@ -23,7 +23,6 @@ import fr.xephi.authme.listener.PlayerListener18;
import fr.xephi.authme.listener.PlayerListener19;
import fr.xephi.authme.listener.PlayerListener19Spigot;
import fr.xephi.authme.listener.ServerListener;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.crypts.Sha256;
import fr.xephi.authme.service.BackupService;
import fr.xephi.authme.service.BukkitService;
@@ -268,13 +267,6 @@ public class AuthMe extends JavaPlugin {
&& settings.getProperty(EmailSettings.SMTP_PORT) != 25) {
ConsoleLogger.warning("Note: You have set Email.useTls to false but this only affects mail over port 25");
}
// Unsalted hashes will be deprecated in 5.4 (see Github issue #1016)
HashAlgorithm hash = settings.getProperty(SecuritySettings.PASSWORD_HASH);
if (OnStartupTasks.isHashDeprecatedIn54(hash)) {
ConsoleLogger.warning("You are using an unsalted hash (" + hash + "). Support for this will be removed "
+ "in 5.4 -- do you still need it? Comment on https://github.com/AuthMe/AuthMeReloaded/issues/1016");
}
}
/**
@@ -17,6 +17,7 @@ import java.util.Date;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* The plugin's static logger.
@@ -168,7 +169,7 @@ public final class ConsoleLogger {
* @param message the message
* @param param1 parameter to replace in the message
*/
public static void debug(String message, String param1) {
public static void debug(String message, Object param1) {
if (logLevel.includes(LogLevel.DEBUG)) {
String debugMessage = "[DEBUG] " + message;
logger.log(Level.INFO, debugMessage, param1);
@@ -184,24 +185,9 @@ public final class ConsoleLogger {
* @param param2 second param to replace in message
*/
// Avoids array creation if DEBUG level is disabled
public static void debug(String message, String param1, String param2) {
public static void debug(String message, Object param1, Object param2) {
if (logLevel.includes(LogLevel.DEBUG)) {
debug(message, new String[]{param1, param2});
}
}
/**
* Log the DEBUG message.
*
* @param message the message
* @param params the params to replace in the message
*/
// Equivalent to debug(String, Object...) but avoids conversions
public static void debug(String message, String... params) {
if (logLevel.includes(LogLevel.DEBUG)) {
String debugMessage = "[DEBUG] " + message;
logger.log(Level.INFO, debugMessage, params);
writeLog(debugMessage + " {" + String.join(", ", params) + "}");
debug(message, new Object[]{param1, param2});
}
}
@@ -213,7 +199,10 @@ public final class ConsoleLogger {
*/
public static void debug(String message, Object... params) {
if (logLevel.includes(LogLevel.DEBUG)) {
debug(message, Arrays.stream(params).map(String::valueOf).toArray(String[]::new));
String debugMessage = "[DEBUG] " + message;
logger.log(Level.INFO, debugMessage, params);
writeLog(debugMessage + " {"
+ Arrays.stream(params).map(String::valueOf).collect(Collectors.joining(", ")) + "}");
}
}
@@ -583,7 +583,7 @@ public class MySQL implements DataSource {
public boolean hasSession(String user) {
String sql = "SELECT " + col.HAS_SESSION + " FROM " + tableName + " WHERE " + col.NAME + "=?;";
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
pst.setString(1, user);
pst.setString(1, user.toLowerCase());
try (ResultSet rs = pst.executeQuery()) {
return rs.next() && (rs.getInt(col.HAS_SESSION) == 1);
}
@@ -509,7 +509,7 @@ public class SQLite implements DataSource {
public boolean hasSession(String user) {
String sql = "SELECT " + col.HAS_SESSION + " FROM " + tableName + " WHERE LOWER(" + col.NAME + ")=?;";
try (PreparedStatement pst = con.prepareStatement(sql)) {
pst.setString(1, user);
pst.setString(1, user.toLowerCase());
try (ResultSet rs = pst.executeQuery()) {
if (rs.next()) {
return rs.getInt(col.HAS_SESSION) == 1;
@@ -526,7 +526,7 @@ public class SQLite implements DataSource {
String sql = "UPDATE " + tableName + " SET " + col.HAS_SESSION + "=? WHERE LOWER(" + col.NAME + ")=?;";
try (PreparedStatement pst = con.prepareStatement(sql)) {
pst.setInt(1, 1);
pst.setString(2, user);
pst.setString(2, user.toLowerCase());
pst.executeUpdate();
} catch (SQLException ex) {
logSqlException(ex);
@@ -538,7 +538,7 @@ public class SQLite implements DataSource {
String sql = "UPDATE " + tableName + " SET " + col.HAS_SESSION + "=? WHERE LOWER(" + col.NAME + ")=?;";
try (PreparedStatement pst = con.prepareStatement(sql)) {
pst.setInt(1, 0);
pst.setString(2, user);
pst.setString(2, user.toLowerCase());
pst.executeUpdate();
} catch (SQLException ex) {
logSqlException(ex);
@@ -7,9 +7,6 @@ import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.output.ConsoleFilter;
import fr.xephi.authme.output.Log4JFilter;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings;
@@ -103,23 +100,4 @@ public class OnStartupTasks {
}
}, 1, TICKS_PER_MINUTE * settings.getProperty(EmailSettings.DELAY_RECALL));
}
/**
* Returns whether the hash algorithm is deprecated and won't be able
* to be actively used anymore in 5.4.
*
* @param hash the hash algorithm to check
* @return true if the hash will be deprecated, false otherwise
* @see <a href="https://github.com/AuthMe/AuthMeReloaded/issues/1016">#1016</a>
*/
public static boolean isHashDeprecatedIn54(HashAlgorithm hash) {
if (hash.getClazz() == null || hash == HashAlgorithm.PLAINTEXT) {
// Exclude PLAINTEXT from this check because it already has a mandatory migration, which takes care of
// sending all the necessary messages and warnings.
return false;
}
Recommendation recommendation = hash.getClazz().getAnnotation(Recommendation.class);
return recommendation != null && recommendation.value() == Usage.DEPRECATED;
}
}
@@ -10,34 +10,34 @@ public enum HashAlgorithm {
BCRYPT(fr.xephi.authme.security.crypts.BCrypt.class),
BCRYPT2Y(fr.xephi.authme.security.crypts.BCrypt2y.class),
CRAZYCRYPT1(fr.xephi.authme.security.crypts.CrazyCrypt1.class),
DOUBLEMD5(fr.xephi.authme.security.crypts.DoubleMd5.class),
IPB3(fr.xephi.authme.security.crypts.Ipb3.class),
IPB4(fr.xephi.authme.security.crypts.Ipb4.class),
JOOMLA(fr.xephi.authme.security.crypts.Joomla.class),
MD5(fr.xephi.authme.security.crypts.Md5.class),
MD5VB(fr.xephi.authme.security.crypts.Md5vB.class),
MYBB(fr.xephi.authme.security.crypts.MyBB.class),
PBKDF2(fr.xephi.authme.security.crypts.Pbkdf2.class),
PBKDF2DJANGO(fr.xephi.authme.security.crypts.Pbkdf2Django.class),
PHPBB(fr.xephi.authme.security.crypts.PhpBB.class),
PHPFUSION(fr.xephi.authme.security.crypts.PhpFusion.class),
@Deprecated
PLAINTEXT(fr.xephi.authme.security.crypts.PlainText.class),
ROYALAUTH(fr.xephi.authme.security.crypts.RoyalAuth.class),
SALTED2MD5(fr.xephi.authme.security.crypts.Salted2Md5.class),
SALTEDSHA512(fr.xephi.authme.security.crypts.SaltedSha512.class),
SHA1(fr.xephi.authme.security.crypts.Sha1.class),
SHA256(fr.xephi.authme.security.crypts.Sha256.class),
SHA512(fr.xephi.authme.security.crypts.Sha512.class),
SMF(fr.xephi.authme.security.crypts.Smf.class),
TWO_FACTOR(fr.xephi.authme.security.crypts.TwoFactor.class),
WBB3(fr.xephi.authme.security.crypts.Wbb3.class),
WBB4(fr.xephi.authme.security.crypts.Wbb4.class),
WHIRLPOOL(fr.xephi.authme.security.crypts.Whirlpool.class),
WORDPRESS(fr.xephi.authme.security.crypts.Wordpress.class),
XAUTH(fr.xephi.authme.security.crypts.XAuth.class),
XFBCRYPT(fr.xephi.authme.security.crypts.XfBCrypt.class),
CUSTOM(null);
CUSTOM(null),
@Deprecated DOUBLEMD5(fr.xephi.authme.security.crypts.DoubleMd5.class),
@Deprecated MD5(fr.xephi.authme.security.crypts.Md5.class),
@Deprecated PLAINTEXT(fr.xephi.authme.security.crypts.PlainText.class),
@Deprecated SHA1(fr.xephi.authme.security.crypts.Sha1.class),
@Deprecated SHA512(fr.xephi.authme.security.crypts.Sha512.class),
@Deprecated WHIRLPOOL(fr.xephi.authme.security.crypts.Whirlpool.class);
private final Class<? extends EncryptionMethod> clazz;
@@ -5,6 +5,7 @@ import fr.xephi.authme.security.crypts.description.Usage;
import static fr.xephi.authme.security.HashUtils.md5;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class DoubleMd5 extends UnsaltedMethod {
@@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class Md5 extends UnsaltedMethod {
@@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class Sha1 extends UnsaltedMethod {
@@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class Sha512 extends UnsaltedMethod {
@@ -64,6 +64,7 @@ import fr.xephi.authme.security.crypts.description.Usage;
import java.util.Arrays;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class Whirlpool extends UnsaltedMethod {
@@ -3,8 +3,8 @@ package fr.xephi.authme.settings;
import ch.jalu.configme.properties.Property;
import ch.jalu.configme.resource.PropertyResource;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -27,9 +27,9 @@ public class EnumSetProperty<E extends Enum<E>> extends Property<Set<E>> {
@Override
protected Set<E> getFromResource(PropertyResource resource) {
List<?> elements = resource.getList(getPath());
if (elements != null) {
return elements.stream()
Object entry = resource.getObject(getPath());
if (entry instanceof Collection<?>) {
return ((Collection<?>) entry).stream()
.map(val -> toEnum(String.valueOf(val)))
.filter(e -> e != null)
.collect(Collectors.toCollection(LinkedHashSet::new));
@@ -10,6 +10,7 @@ import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.process.register.RegisterSecondaryArgument;
import fr.xephi.authme.process.register.RegistrationType;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
@@ -20,6 +21,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import static ch.jalu.configme.properties.PropertyInitializer.newListProperty;
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
@@ -73,6 +75,7 @@ public class SettingsMigrationService extends PlainMigrationService {
| hasSupportOldPasswordProperty(resource)
| convertToRegistrationType(resource)
| mergeAndMovePermissionGroupSettings(resource)
| moveDeprecatedHashAlgorithmIntoLegacySection(resource)
|| hasDeprecatedProperties(resource);
}
@@ -286,6 +289,31 @@ public class SettingsMigrationService extends PlainMigrationService {
return performedChanges;
}
/**
* If a deprecated hash is used, it is added to the legacy hashes option and the active hash
* is changed to SHA256.
*
* @param resource The property resource
* @return True if the configuration has changed, false otherwise
*/
private static boolean moveDeprecatedHashAlgorithmIntoLegacySection(PropertyResource resource) {
HashAlgorithm currentHash = SecuritySettings.PASSWORD_HASH.getValue(resource);
// Skip CUSTOM (has no class) and PLAINTEXT (is force-migrated later on in the startup process)
if (currentHash != HashAlgorithm.CUSTOM && currentHash != HashAlgorithm.PLAINTEXT) {
Class<?> encryptionClass = currentHash.getClazz();
if (encryptionClass.isAnnotationPresent(Deprecated.class)) {
resource.setValue(SecuritySettings.PASSWORD_HASH.getPath(), HashAlgorithm.SHA256);
Set<HashAlgorithm> legacyHashes = SecuritySettings.LEGACY_HASHES.getValue(resource);
legacyHashes.add(currentHash);
resource.setValue(SecuritySettings.LEGACY_HASHES.getPath(), legacyHashes);
ConsoleLogger.warning("The hash algorithm '" + currentHash
+ "' is no longer supported for active use. New hashes will be in SHA256.");
return true;
}
}
return false;
}
/**
* Checks for an old property path and moves it to a new path if it is present and the new path is not yet set.
*
@@ -53,7 +53,7 @@ public final class SecuritySettings implements SettingsHolder {
newProperty("settings.security.passwordMaxLength", 30);
@Comment({
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512, WHIRLPOOL,",
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512,",
"MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,",
"PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only). See full list at",
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md"