Require player re-join to confirm auto-login request

Fixes #159
Fixes #242
Fixes #256
Fixes #286
This commit is contained in:
games647
2020-03-20 16:06:42 +01:00
parent 65469ed579
commit 5676e99dec
18 changed files with 192 additions and 68 deletions
@@ -0,0 +1,15 @@
package com.github.games647.fastlogin.core;
public enum ConfirmationState {
/**
* Require server login where we request onlinemode authentication
*/
REQUIRE_RELOGIN,
/**
* The command have to be invoked again to confirm that the player who joined through onlinemode knows
* the password of the cracked account
*/
REQUIRE_AUTH_PLUGIN_LOGIN
}
@@ -29,6 +29,9 @@ public class ChangePremiumMessage implements ChannelMessage {
return willEnable;
}
/**
* @return true if the player invoker = target
*/
public boolean isSourceInvoker() {
return isSourceInvoker;
}
@@ -4,6 +4,7 @@ import com.github.games647.craftapi.resolver.MojangResolver;
import com.github.games647.craftapi.resolver.http.RotatingProxySelector;
import com.github.games647.fastlogin.core.AuthStorage;
import com.github.games647.fastlogin.core.CommonUtil;
import com.github.games647.fastlogin.core.ConfirmationState;
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
import com.github.games647.fastlogin.core.hooks.DefaultPasswordGenerator;
import com.github.games647.fastlogin.core.hooks.PasswordGenerator;
@@ -24,7 +25,6 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -47,7 +47,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
private final Map<String, String> localeMessages = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Object> pendingLogin = CommonUtil.buildCache(5, -1);
private final Collection<UUID> pendingConfirms = new HashSet<>();
private final ConcurrentMap<String, ConfirmationState> pendingConfirms = CommonUtil.buildCache(1, 1024);
private final T plugin;
private final MojangResolver resolver = new MojangResolver();
@@ -204,11 +204,18 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
this.passwordGenerator = passwordGenerator;
}
/**
* @return list of player names that are currently during the login process and might fail and so could be used
* for second attempt logins
*/
public ConcurrentMap<String, Object> getPendingLogin() {
return pendingLogin;
}
public Collection<UUID> getPendingConfirms() {
/**
* @return list of player names that request onlinemode authentication but are not yet approved
*/
public ConcurrentMap<String, ConfirmationState> getPendingConfirms() {
return pendingConfirms;
}
@@ -28,10 +28,16 @@ public abstract class ForceLoginManagement<P extends C, C, L extends LoginSessio
StoredProfile playerProfile = session.getProfile();
try {
if (isOnlineMode()) {
if (session.isConfirmationPending()) {
// do not perform force actions, because this confirmation login we have to verify that it's the
// owner of the account
return;
}
//premium player
AuthPlugin<P> authPlugin = core.getAuthPluginHook();
if (authPlugin == null) {
//maybe only bungeecord plugin
//maybe only bungeecord plugin without any auth plugins on Bungee
onForceActionSuccess(session);
} else {
boolean success = true;
@@ -2,6 +2,7 @@ package com.github.games647.fastlogin.core.shared;
import com.github.games647.craftapi.model.Profile;
import com.github.games647.craftapi.resolver.RateLimitException;
import com.github.games647.fastlogin.core.ConfirmationState;
import com.github.games647.fastlogin.core.StoredProfile;
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
@@ -37,7 +38,14 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
if (profile.isPremium()) {
requestPremiumLogin(source, profile, username, true);
} else {
startCrackedSession(source, profile, username);
ConfirmationState confirmationState = core.getPendingConfirms().get(username);
if (confirmationState == ConfirmationState.REQUIRE_RELOGIN) {
core.getPendingConfirms().put(username, ConfirmationState.REQUIRE_AUTH_PLUGIN_LOGIN);
requestPremiumLogin(source, profile, username, true);
} else {
// cracked player, but wants to change to premium
startCrackedSession(source, profile, username);
}
}
} else {
if (core.getPendingLogin().remove(ip + username) != null && config.get("secondAttemptCracked", false)) {
@@ -108,5 +116,7 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
public abstract void requestPremiumLogin(S source, StoredProfile profile, String username, boolean registered);
public abstract void requestConfirmationLogin(S source, StoredProfile profile, String username);
public abstract void startCrackedSession(S source, StoredProfile profile, String username);
}
@@ -13,12 +13,19 @@ public abstract class LoginSession {
protected boolean registered;
protected boolean confirmationLogin;
public LoginSession(String username, boolean registered, StoredProfile profile) {
this.username = username;
this.registered = registered;
this.profile = profile;
}
public LoginSession(String username, StoredProfile profile) {
this(username, true, profile);
this.confirmationLogin = true;
}
public String getUsername() {
return username;
}
@@ -54,6 +61,10 @@ public abstract class LoginSession {
this.uuid = uuid;
}
public synchronized boolean isConfirmationPending() {
return confirmationLogin;
}
@Override
public synchronized String toString() {
return this.getClass().getSimpleName() + '{' +
+5 -5
View File
@@ -115,11 +115,11 @@ nameChangeCheck: false
# ChangeSkin, SkinRestorer, ...
forwardSkin: true
# Displays a warning message that this message SHOULD only be invoked by
# users who actually are the owner of this account. So not by cracked players
#
# If they still want to invoke the command, they have to invoke /premium again
premium-warning: true
# Players have to rejoin to verify that they can join through onlinemode authentication.
# After that they have to confirm again using the /premium command that they are also the owner of the auth plugin
# account.
# If the onlinemode authentication fails or the player waits to long, it will fallback to offlinemode authentication.
premium-confirm: true
# If you have autoRegister or nameChangeCheck enabled, you could be rate-limited by Mojang.
# The requests of the both options will be only made by FastLogin if the username is unknown to the server
+3 -3
View File
@@ -89,9 +89,9 @@ invalid-requst: '&4Invalid request'
# Message if the Bukkit isn't fully started to inject the packets
not-started: '&cServer is not fully started yet. Please retry'
# Warning message if a user invoked /premium command
premium-warning: '&c&lWARNING: &6This command should &lonly&6 be invoked if you are the owner of this paid Minecraft account
Type &a/premium&6 again to confirm'
# Premium confirmation message if the player tries to activate the command
premium-confirm: '&6Please relogin and type the command again to apply the changes.
If the request fails or you wait to long, it will fallback to offlinemode.'
# ========= Bungee/Waterfall only ================================