Use real ip

This commit is contained in:
Braydon 2023-05-31 22:58:39 -04:00
parent 2685bed581
commit 98b67aba4f
2 changed files with 93 additions and 1 deletions

@ -0,0 +1,86 @@
package me.braydon.license.common;
import jakarta.servlet.http.HttpServletRequest;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
/**
* @author Braydon
*/
@UtilityClass
public final class IPUtils {
/**
* The regex expression for validating IPv4 addresses.
*/
public static final String IPV4_REGEX = "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$";
/**
* The regex expression for validating IPv6 addresses.
*/
public static final String IPV6_REGEX = "^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^(([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4})?::(([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4})?$";
private static final String[] IP_HEADERS = new String[] {
"CF-Connecting-IP",
"X-Forwarded-For"
};
/**
* Get the real IP from the given request.
*
* @param request the request
* @return the real IP
*/
@NonNull
public static String getRealIp(@NonNull HttpServletRequest request) {
String ip = request.getRemoteAddr();
for (String headerName : IP_HEADERS) {
String header = request.getHeader(headerName);
if (header == null) {
continue;
}
if (!header.contains(",")) { // Handle single IP
ip = header;
break;
}
// Handle multiple IPs
String[] ips = header.split(",");
for (String ipHeader : ips) {
ip = ipHeader;
break;
}
}
return ip;
}
/**
* Get the IP type of the given input.
*
* @param input the input
* @return the IP type, -1 if invalid
*/
public static int getIpType(@NonNull String input) {
return isIpV4(input) ? 4 : isIpV6(input) ? 6 : -1;
}
/**
* Check if the given input is
* a valid IPv4 address.
*
* @param input the input
* @return true if IPv4, otherwise false
*/
public static boolean isIpV4(@NonNull String input) {
return input.matches(IPV4_REGEX);
}
/**
* Check if the given input is
* a valid IPv6 address.
*
* @param input the input
* @return true if IPv6, otherwise false
*/
public static boolean isIpV6(@NonNull String input) {
return input.matches(IPV6_REGEX);
}
}

@ -5,6 +5,7 @@ import com.google.gson.JsonObject;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.NonNull; import lombok.NonNull;
import me.braydon.license.LicenseServer; import me.braydon.license.LicenseServer;
import me.braydon.license.common.IPUtils;
import me.braydon.license.dto.LicenseDTO; import me.braydon.license.dto.LicenseDTO;
import me.braydon.license.exception.APIException; import me.braydon.license.exception.APIException;
import me.braydon.license.model.License; import me.braydon.license.model.License;
@ -45,7 +46,7 @@ public final class LicenseController {
@ResponseBody @ResponseBody
public ResponseEntity<?> check(@NonNull HttpServletRequest request, @RequestBody @NonNull String body) { public ResponseEntity<?> check(@NonNull HttpServletRequest request, @RequestBody @NonNull String body) {
try { // Attempt to check the license try { // Attempt to check the license
String ip = request.getRemoteAddr(); // The IP of the requester String ip = IPUtils.getRealIp(request); // The IP of the requester
JsonObject jsonObject = LicenseServer.GSON.fromJson(body, JsonObject.class); JsonObject jsonObject = LicenseServer.GSON.fromJson(body, JsonObject.class);
JsonElement key = jsonObject.get("key"); // Get the key JsonElement key = jsonObject.get("key"); // Get the key
@ -56,6 +57,11 @@ public final class LicenseController {
if (key.isJsonNull() || product.isJsonNull() || hwid.isJsonNull()) { if (key.isJsonNull() || product.isJsonNull() || hwid.isJsonNull()) {
throw new APIException(HttpStatus.BAD_REQUEST, "Invalid request body"); throw new APIException(HttpStatus.BAD_REQUEST, "Invalid request body");
} }
// Ensure the IP is valid
if (IPUtils.getIpType(ip) == -1) {
throw new APIException(HttpStatus.BAD_REQUEST, "Invalid IP address");
}
// Check the license // Check the license
License license = service.check( License license = service.check(
key.getAsString(), key.getAsString(),