Use the headers provided by a context to get the IP address

should acknowledge #1975
This commit is contained in:
KingRainbow44
2023-05-31 02:10:25 -04:00
parent 6c97da3715
commit ff421c01f9
5 changed files with 59 additions and 31 deletions

View File

@@ -1,8 +1,5 @@
package emu.grasscutter.auth; package emu.grasscutter.auth;
import static emu.grasscutter.config.Configuration.ACCOUNT;
import static emu.grasscutter.utils.lang.Language.translate;
import at.favre.lib.crypto.bcrypt.BCrypt; import at.favre.lib.crypto.bcrypt.BCrypt;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerRunMode; import emu.grasscutter.Grasscutter.ServerRunMode;
@@ -17,13 +14,17 @@ import emu.grasscutter.utils.DispatchUtils;
import emu.grasscutter.utils.FileUtils; import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import io.javalin.http.ContentType; import io.javalin.http.ContentType;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.crypto.Cipher;
import static emu.grasscutter.config.Configuration.ACCOUNT;
import static emu.grasscutter.utils.lang.Language.translate;
/** A class containing default authenticators. */ /** A class containing default authenticators. */
public final class DefaultAuthenticators { public final class DefaultAuthenticators {
@@ -38,7 +39,7 @@ public final class DefaultAuthenticators {
assert requestData != null; // This should never be null. assert requestData != null; // This should never be null.
boolean successfulLogin = false; boolean successfulLogin = false;
String address = request.getContext().ip(); String address = Utils.address(request.getContext());
String responseMessage = translate("messages.dispatch.account.username_error"); String responseMessage = translate("messages.dispatch.account.username_error");
String loggerMessage = ""; String loggerMessage = "";
@@ -98,7 +99,7 @@ public final class DefaultAuthenticators {
assert requestData != null; // This should never be null. assert requestData != null; // This should never be null.
boolean successfulLogin = false; boolean successfulLogin = false;
String address = request.getContext().ip(); String address = Utils.address(request.getContext());
String responseMessage = translate("messages.dispatch.account.username_error"); String responseMessage = translate("messages.dispatch.account.username_error");
String loggerMessage = ""; String loggerMessage = "";
String decryptedPassword = ""; String decryptedPassword = "";
@@ -209,7 +210,7 @@ public final class DefaultAuthenticators {
assert requestData != null; assert requestData != null;
boolean successfulLogin; boolean successfulLogin;
String address = request.getContext().ip(); String address = Utils.address(request.getContext());
String loggerMessage; String loggerMessage;
// Log the attempt. // Log the attempt.
@@ -257,7 +258,7 @@ public final class DefaultAuthenticators {
assert loginData != null; assert loginData != null;
boolean successfulLogin; boolean successfulLogin;
String address = request.getContext().ip(); String address = Utils.address(request.getContext());
String loggerMessage; String loggerMessage;
// Get account from database. // Get account from database.
@@ -395,7 +396,7 @@ public final class DefaultAuthenticators {
// Check to see if an IP authentication can be performed. // Check to see if an IP authentication can be performed.
if (Grasscutter.getRunMode() == ServerRunMode.HYBRID) { if (Grasscutter.getRunMode() == ServerRunMode.HYBRID) {
var player = Grasscutter.getGameServer().getPlayerByIpAddress(ctx.ip()); var player = Grasscutter.getGameServer().getPlayerByIpAddress(Utils.address(ctx));
if (player != null) { if (player != null) {
// Get the player's session token. // Get the player's session token.
var sessionKey = player.getAccount().getSessionKey(); var sessionKey = player.getAccount().getSessionKey();

View File

@@ -1,7 +1,5 @@
package emu.grasscutter.server.http.dispatch; package emu.grasscutter.server.http.dispatch;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.auth.AuthenticationSystem; import emu.grasscutter.auth.AuthenticationSystem;
import emu.grasscutter.auth.OAuthAuthenticator.ClientType; import emu.grasscutter.auth.OAuthAuthenticator.ClientType;
@@ -11,9 +9,12 @@ import emu.grasscutter.server.http.objects.ComboTokenReqJson.LoginTokenData;
import emu.grasscutter.server.http.objects.LoginAccountRequestJson; import emu.grasscutter.server.http.objects.LoginAccountRequestJson;
import emu.grasscutter.server.http.objects.LoginTokenRequestJson; import emu.grasscutter.server.http.objects.LoginTokenRequestJson;
import emu.grasscutter.utils.JsonUtils; import emu.grasscutter.utils.JsonUtils;
import emu.grasscutter.utils.Utils;
import io.javalin.Javalin; import io.javalin.Javalin;
import io.javalin.http.Context; import io.javalin.http.Context;
import static emu.grasscutter.utils.lang.Language.translate;
/** Handles requests related to authentication. */ /** Handles requests related to authentication. */
public final class AuthenticationHandler implements Router { public final class AuthenticationHandler implements Router {
/** /**
@@ -36,7 +37,7 @@ public final class AuthenticationHandler implements Router {
ctx.json(responseData); ctx.json(responseData);
// Log to console. // Log to console.
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_attempt", ctx.ip())); Grasscutter.getLogger().info(translate("messages.dispatch.account.login_attempt", Utils.address(ctx)));
} }
/** /**
@@ -59,7 +60,7 @@ public final class AuthenticationHandler implements Router {
ctx.json(responseData); ctx.json(responseData);
// Log to console. // Log to console.
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_attempt", ctx.ip())); Grasscutter.getLogger().info(translate("messages.dispatch.account.login_attempt", Utils.address(ctx)));
} }
/** /**
@@ -85,7 +86,7 @@ public final class AuthenticationHandler implements Router {
ctx.json(responseData); ctx.json(responseData);
// Log to console. // Log to console.
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_attempt", ctx.ip())); Grasscutter.getLogger().info(translate("messages.dispatch.account.login_attempt", Utils.address(ctx)));
} }
@Override @Override

View File

@@ -1,7 +1,5 @@
package emu.grasscutter.server.http.dispatch; package emu.grasscutter.server.http.dispatch;
import static emu.grasscutter.config.Configuration.*;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
@@ -23,12 +21,15 @@ import emu.grasscutter.utils.JsonUtils;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import io.javalin.Javalin; import io.javalin.Javalin;
import io.javalin.http.Context; import io.javalin.http.Context;
import org.slf4j.Logger;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.slf4j.Logger;
import static emu.grasscutter.config.Configuration.*;
/** Handles requests related to region queries. */ /** Handles requests related to region queries. */
public final class RegionHandler implements Router { public final class RegionHandler implements Router {
@@ -220,7 +221,7 @@ public final class RegionHandler implements Router {
} }
// Log the request to the console. // Log the request to the console.
Grasscutter.getLogger() Grasscutter.getLogger()
.info(String.format("[Dispatch] Client %s request: query_region_list", ctx.ip())); .info(String.format("[Dispatch] Client %s request: query_region_list", Utils.address(ctx)));
} }
/** /**
@@ -280,8 +281,8 @@ public final class RegionHandler implements Router {
Grasscutter.getLogger() Grasscutter.getLogger()
.info( .info(
String.format( String.format(
"Connection denied for %s due to %s", "Connection denied for %s due to %s.",
ctx.ip(), updateClient ? "outdated client!" : "outdated server!")); Utils.address(ctx), updateClient ? "outdated client!" : "outdated server!"));
ctx.json(Crypto.encryptAndSignRegionData(rsp.toByteArray(), key_id)); ctx.json(Crypto.encryptAndSignRegionData(rsp.toByteArray(), key_id));
return; return;
@@ -313,7 +314,7 @@ public final class RegionHandler implements Router {
} }
// Log to console. // Log to console.
Grasscutter.getLogger() Grasscutter.getLogger()
.info(String.format("Client %s request: query_cur_region/%s", ctx.ip(), regionName)); .info(String.format("Client %s request: query_cur_region/%s", Utils.address(ctx), regionName));
} }
/** Region data container. */ /** Region data container. */

View File

@@ -1,15 +1,17 @@
package emu.grasscutter.server.http.objects; package emu.grasscutter.server.http.objects;
import static emu.grasscutter.config.Configuration.DISPATCH_INFO;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerDebugMode; import emu.grasscutter.Grasscutter.ServerDebugMode;
import emu.grasscutter.utils.Utils;
import io.javalin.http.Context; import io.javalin.http.Context;
import io.javalin.http.Handler; import io.javalin.http.Handler;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import static emu.grasscutter.config.Configuration.DISPATCH_INFO;
import static emu.grasscutter.utils.lang.Language.translate;
public final class HttpJsonResponse implements Handler { public final class HttpJsonResponse implements Handler {
private final String response; private final String response;
@@ -42,7 +44,7 @@ public final class HttpJsonResponse implements Handler {
.info( .info(
translate( translate(
"messages.dispatch.request", "messages.dispatch.request",
ctx.ip(), Utils.address(ctx),
ctx.method(), ctx.method(),
ctx.endpointHandlerPath()) ctx.endpointHandlerPath())
+ (DISPATCH_INFO.logRequests == ServerDebugMode.MISSING ? "(MISSING)" : "")); + (DISPATCH_INFO.logRequests == ServerDebugMode.MISSING ? "(MISSING)" : ""));

View File

@@ -1,17 +1,18 @@
package emu.grasscutter.utils; package emu.grasscutter.utils;
import static emu.grasscutter.utils.FileUtils.getResourcePath;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.config.ConfigContainer; import emu.grasscutter.config.ConfigContainer;
import emu.grasscutter.data.DataLoader; import emu.grasscutter.data.DataLoader;
import emu.grasscutter.game.world.Position; import emu.grasscutter.game.world.Position;
import io.javalin.http.Context;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import org.slf4j.Logger;
import javax.annotation.Nullable;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
@@ -23,8 +24,9 @@ import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalAdjusters;
import java.util.*; import java.util.*;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nullable;
import org.slf4j.Logger; import static emu.grasscutter.utils.FileUtils.getResourcePath;
import static emu.grasscutter.utils.lang.Language.translate;
@SuppressWarnings({"UnusedReturnValue", "BooleanMethodIsAlwaysInverted"}) @SuppressWarnings({"UnusedReturnValue", "BooleanMethodIsAlwaysInverted"})
public final class Utils { public final class Utils {
@@ -463,4 +465,25 @@ public final class Utils {
if (start < input.length()) output.add(input.substring(start)); if (start < input.length()) output.add(input.substring(start));
return output; return output;
} }
/**
* Fetches the IP address of a web request.
*
* @param ctx The context of the request.
* @return The IP address of the request.
*/
public static String address(Context ctx) {
// Check headers.
var address = ctx.header("CF-Connecting-IP");
if (address != null) return address;
address = ctx.header("X-Forwarded-For");
if (address != null) return address;
address = ctx.header("X-Real-IP");
if (address != null) return address;
// Return the request IP.
return ctx.ip();
}
} }