diff --git a/README.md b/README.md
index d306fe86..c862068f 100644
--- a/README.md
+++ b/README.md
@@ -2,18 +2,17 @@
The most used authentication plugin for CraftBukkit/Spigot!
-####Development history:
-[](https://www.youtube.com/watch?v=hJRzNfYyd9k)
-
#####Development tools:
- DEVELOPMENT TEAM REPO (please send PRs here!): Github Development Page
- Developers ChatRoom: [](https://gitter.im/Xephi/AuthMeReloaded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-- Build status: [](https://travis-ci.org/Xephi/AuthMeReloaded) [](https://www.versioneye.com/user/projects/55bab9e8653762002000190a)
+- Build Server (DEVELOPMENT BUILDS): Xephi's Jenkins
-- Build status (CircleCI): [](https://circleci.com/gh/Xephi/AuthMeReloaded)
+- Build status: [](https://travis-ci.org/AuthMe-Team/AuthMeReloaded) [](https://www.versioneye.com/user/projects/55bab9e8653762002000190a)
+
+- Build status (CircleCI): [](https://circleci.com/gh/AuthMe-Team/AuthMeReloaded)
- Alternative Dev Build download link (via CircleCi): Download
- JitPack (just in case): [](https://jitpack.io/#AuthMe-Team/AuthMeReloaded)
@@ -21,9 +20,7 @@
- Issue Tracking : [](https://waffle.io/Xephi/AuthMeReloaded) [](https://waffle.io/Xephi/AuthMeReloaded) [](https://waffle.io/Xephi/AuthMeReloaded)
-- Build Server (DEVELOPMENT BUILDS): Xephi's Jenkins
-
-- JavaDocs: AuthMe Javadoc
+- JavaDoc: AuthMe Javadoc
- Maven Repo: AuthMe Repo
@@ -37,6 +34,9 @@ McStats: http://mcstats.org/plugin/AuthMe
+#####Development history:
+[](https://www.youtube.com/watch?v=hJRzNfYyd9k)
+
#####Compiling Requirements:
@@ -84,6 +84,7 @@ typing commands or using the inventory. It can also kick players with uncommonly
Xenforo: XFBCRYPT
MyBB: MYBB
IPB3: IPB3
+ IPB4: IPB4
PhpFusion: PHPFUSION
Joomla: JOOMLA
WBB3: WBB3*
diff --git a/src/main/java/fr/xephi/authme/security/RandomString.java b/src/main/java/fr/xephi/authme/security/RandomString.java
index 40274305..10926e11 100644
--- a/src/main/java/fr/xephi/authme/security/RandomString.java
+++ b/src/main/java/fr/xephi/authme/security/RandomString.java
@@ -8,18 +8,10 @@ import java.util.Random;
*/
public final class RandomString {
- private static final char[] chars = new char[36];
+ private static final String CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final Random RANDOM = new SecureRandom();
private static final int HEX_MAX_INDEX = 16;
-
- static {
- for (int idx = 0; idx < 10; ++idx) {
- chars[idx] = (char) ('0' + idx);
- }
- for (int idx = 10; idx < 36; ++idx) {
- chars[idx] = (char) ('a' + idx - 10);
- }
- }
+ private static final int LOWER_ALPHANUMERIC_INDEX = 36;
private RandomString() {
}
@@ -31,7 +23,7 @@ public final class RandomString {
* @return The random string
*/
public static String generate(int length) {
- return generate(length, chars.length);
+ return generate(length, LOWER_ALPHANUMERIC_INDEX);
}
/**
@@ -45,13 +37,24 @@ public final class RandomString {
return generate(length, HEX_MAX_INDEX);
}
+ /**
+ * Generate a random string with digits and lowercase and uppercase letters. The result of this
+ * method matches the pattern [0-9a-zA-Z].
+ *
+ * @param length The length of the random string to generate
+ * @return The random string
+ */
+ public static String generateLowerUpper(int length) {
+ return generate(length, CHARS.length());
+ }
+
private static String generate(int length, int maxIndex) {
if (length < 0) {
throw new IllegalArgumentException("Length must be positive but was " + length);
}
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; ++i) {
- sb.append(chars[RANDOM.nextInt(maxIndex)]);
+ sb.append(CHARS.charAt(RANDOM.nextInt(maxIndex)));
}
return sb.toString();
}
diff --git a/src/main/java/fr/xephi/authme/security/crypts/IPB4.java b/src/main/java/fr/xephi/authme/security/crypts/IPB4.java
index 515901bc..e54bcd03 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/IPB4.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/IPB4.java
@@ -1,19 +1,24 @@
package fr.xephi.authme.security.crypts;
import fr.xephi.authme.ConsoleLogger;
+import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.security.crypts.description.HasSalt;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.SaltType;
import fr.xephi.authme.security.crypts.description.Usage;
import fr.xephi.authme.util.StringUtils;
-import java.security.SecureRandom;
-
+/**
+ * Implementation for IPB4 (Invision Power Board 4).
+ *
+ * The hash uses standard BCrypt with 13 as log2 number of rounds. Additionally,
+ * IPB4 requires that the salt be stored additionally in the column "members_pass_hash"
+ * (even though BCrypt hashes already have the salt in the result).
+ */
@Recommendation(Usage.DOES_NOT_WORK)
-@HasSalt(value = SaltType.TEXT)
+@HasSalt(value = SaltType.TEXT, length = 22)
public class IPB4 implements EncryptionMethod {
- private SecureRandom random = new SecureRandom();
@Override
public String computeHash(String password, String salt, String name) {
@@ -38,16 +43,7 @@ public class IPB4 implements EncryptionMethod {
@Override
public String generateSalt() {
- StringBuilder sb = new StringBuilder(22);
- for (int i = 0; i < 22; i++) {
- char chr;
- do {
- chr = (char) (random.nextInt((122 - 48) + 1) + 48);
- }
- while ((chr >= 58 && chr <= 64) || (chr >= 91 && chr <= 96));
- sb.append(chr);
- }
- return sb.toString();
+ return RandomString.generateLowerUpper(22);
}
@Override
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index c9cdbfe6..151bc753 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -186,7 +186,7 @@ settings:
# Example unLoggedinGroup: NotLogged
unLoggedinGroup: unLoggedinGroup
# possible values: MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB,
- # MYBB, IPB3, PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512,
+ # MYBB, IPB3, IPB4, PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512,
# DOUBLEMD5, PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM(for developpers only)
passwordHash: SHA256
# salt length for the SALTED2MD5 MD5(MD5(password)+salt)
@@ -260,7 +260,7 @@ settings:
# If Xephi is registered, then Xephi can login, but not XEPHI/xephi/XePhI
preventOtherCase: false
ExternalBoardOptions:
- # MySQL column for the salt , needed for some forum/cms support
+ # MySQL column for the salt, needed for some forum/cms support
mySQLColumnSalt: ''
# MySQL column for the group, needed for some forum/cms support
mySQLColumnGroup: ''
@@ -275,7 +275,7 @@ ExternalBoardOptions:
bCryptLog2Round: 10
# phpBB prefix defined during phpbb installation process
phpbbTablePrefix: 'phpbb_'
- # phpBB activated group id , 2 is default registered group defined by phpbb
+ # phpBB activated group id, 2 is default registered group defined by phpbb
phpbbActivatedGroupId: 2
# WordPress prefix defined during WordPress installation process
wordpressTablePrefix: 'wp_'
diff --git a/src/test/java/fr/xephi/authme/security/RandomStringTest.java b/src/test/java/fr/xephi/authme/security/RandomStringTest.java
index 938f095c..71ea587c 100644
--- a/src/test/java/fr/xephi/authme/security/RandomStringTest.java
+++ b/src/test/java/fr/xephi/authme/security/RandomStringTest.java
@@ -44,6 +44,22 @@ public class RandomStringTest {
}
}
+ @Test
+ public void shouldGenerateRandomLowerUpperString() {
+ // given
+ int[] lengths = {0, 1, 17, 143, 1808};
+ Pattern badChars = Pattern.compile(".*[^0-9a-zA-Z].*");
+
+ // when / then
+ for (int length : lengths) {
+ String result = RandomString.generateHex(length);
+ assertThat("Result '" + result + "' should have length " + length,
+ result.length(), equalTo(length));
+ assertThat("Result '" + result + "' should only have characters a-z, A-Z, 0-9",
+ badChars.matcher(result).matches(), equalTo(false));
+ }
+ }
+
@Test(expected = IllegalArgumentException.class)
public void shouldThrowForInvalidLength() {
// given/when
diff --git a/src/test/java/fr/xephi/authme/security/crypts/IPB4Test.java b/src/test/java/fr/xephi/authme/security/crypts/IPB4Test.java
index 400a266b..58c6f570 100644
--- a/src/test/java/fr/xephi/authme/security/crypts/IPB4Test.java
+++ b/src/test/java/fr/xephi/authme/security/crypts/IPB4Test.java
@@ -1,13 +1,18 @@
package fr.xephi.authme.security.crypts;
+import fr.xephi.authme.ConsoleLoggerTestInitializer;
import fr.xephi.authme.util.WrapperMock;
import org.junit.BeforeClass;
+/**
+ * Test for {@link IPB4}.
+ */
public class IPB4Test extends AbstractEncryptionMethodTest {
@BeforeClass
public static void setUpSettings() {
WrapperMock.createInstance();
+ ConsoleLoggerTestInitializer.setupLogger();
}
public IPB4Test() {