Skip to content
Open

fix #226

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
.idea/
*.iml

# VS Code user-specific stuff
.vscode/

# Compiled class file
*.class

Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"java.compile.nullAnalysis.mode": "automatic"
}
30 changes: 27 additions & 3 deletions src/main/java/net/elytrium/limboauth/LimboAuth.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
import com.velocitypowered.api.scheduler.ScheduledTask;
import com.velocitypowered.proxy.util.ratelimit.Ratelimiter;
import com.velocitypowered.proxy.util.ratelimit.Ratelimiters;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.whitfin.siphash.SipHasher;
import java.io.File;
Expand Down Expand Up @@ -137,7 +135,7 @@
)
public class LimboAuth {

public static final Ratelimiter<InetAddress> RATELIMITER = Ratelimiters.createWithMilliseconds(5000);
public static final InetAddressRateLimiter RATELIMITER = new InetAddressRateLimiter(5000);

// Architectury API appends /541f59e4256a337ea252bc482a009d46 to the channel name, that is a UUID.nameUUIDFromBytes from the TokenMessage class name
private static final ChannelIdentifier MOD_CHANNEL = MinecraftChannelIdentifier.create("limboauth", "mod/541f59e4256a337ea252bc482a009d46");
Expand Down Expand Up @@ -1112,4 +1110,30 @@ public enum PremiumState {
RATE_LIMIT,
ERROR
}

public static final class InetAddressRateLimiter {
private final long windowMillis;
private final ConcurrentHashMap<InetAddress, Long> lastAttempt = new ConcurrentHashMap<>();
private static final long CLEANUP_INTERVAL = 3600000; // 1 hour in milliseconds

public InetAddressRateLimiter(long windowMillis) {
this.windowMillis = windowMillis;
}

public boolean attempt(InetAddress address) {
long now = System.currentTimeMillis();
Long lastAttemptTime = this.lastAttempt.get(address);

if (lastAttemptTime == null || now - lastAttemptTime >= this.windowMillis) {
this.lastAttempt.put(address, now);
// Periodically cleanup old entries to prevent memory leaks
if (now % 60000 == 0) { // cleanup every minute
this.lastAttempt.entrySet().removeIf(e -> now - e.getValue() > CLEANUP_INTERVAL);
}
return true;
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,15 @@
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.Title;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AuthSessionHandler implements LimboSessionHandler {

public static final CodeVerifier TOTP_CODE_VERIFIER = new DefaultCodeVerifier(new DefaultCodeGenerator(), new SystemTimeProvider());
private static final BCrypt.Verifyer HASH_VERIFIER = BCrypt.verifyer();
private static final BCrypt.Hasher HASHER = BCrypt.withDefaults();
private static final Logger LOGGER = LoggerFactory.getLogger(AuthSessionHandler.class);

private static Component ratelimited;
private static BossBar.Color bossbarColor;
Expand Down Expand Up @@ -442,7 +445,7 @@ private void finishAuth() {
} catch (SQLException e) {
throw new SQLRuntimeException(e);
} catch (Throwable e) {
e.printStackTrace();
LOGGER.warn("Error occurred during finalization after authentication for player: {}", this.proxyPlayer.getUsername(), e);
}

this.plugin.cacheAuthUser(this.proxyPlayer);
Expand Down