Hash IP addresses
This commit is contained in:
parent
a5a154610e
commit
3412668ec1
@ -7,6 +7,7 @@ import lombok.ToString;
|
|||||||
import me.braydon.license.exception.APIException;
|
import me.braydon.license.exception.APIException;
|
||||||
import me.braydon.license.exception.LicenseHwidLimitExceededException;
|
import me.braydon.license.exception.LicenseHwidLimitExceededException;
|
||||||
import me.braydon.license.exception.LicenseIpLimitExceededException;
|
import me.braydon.license.exception.LicenseIpLimitExceededException;
|
||||||
|
import org.mindrot.jbcrypt.BCrypt;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
import org.springframework.data.mongodb.core.mapping.Document;
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
|
||||||
@ -45,9 +46,6 @@ public class License {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The IPs used on this license.
|
* The IPs used on this license.
|
||||||
* <p>
|
|
||||||
* These IPs are encrypted using AES-256.
|
|
||||||
* </p>
|
|
||||||
*/
|
*/
|
||||||
private Set<String> ips;
|
private Set<String> ips;
|
||||||
|
|
||||||
@ -79,19 +77,24 @@ public class License {
|
|||||||
/**
|
/**
|
||||||
* Invoked when this license is used.
|
* Invoked when this license is used.
|
||||||
*
|
*
|
||||||
* @param ip the ip used
|
* @param ip the ip used
|
||||||
* @param hwid the hardware id used
|
* @param ipSalt the IP salt to use
|
||||||
|
* @param hwid the hardware id used
|
||||||
*/
|
*/
|
||||||
public void use(@NonNull String ip, @NonNull String hwid) throws APIException {
|
public void use(@NonNull String ip, @NonNull String ipSalt, @NonNull String hwid) throws APIException {
|
||||||
if (!ips.contains(ip) && ips.size() >= ipLimit) { // IP limit has been exceeded
|
String hashedIp = BCrypt.hashpw(ip, ipSalt); // Hash the IP
|
||||||
|
|
||||||
|
// IP limit has been exceeded
|
||||||
|
if (!ips.contains(hashedIp) && ips.size() >= ipLimit) {
|
||||||
throw new LicenseIpLimitExceededException();
|
throw new LicenseIpLimitExceededException();
|
||||||
}
|
}
|
||||||
if (!hwids.contains(hwid) && hwids.size() >= hwidLimit) { // HWID limit has been exceeded
|
// HWID limit has been exceeded
|
||||||
|
if (!hwids.contains(hwid) && hwids.size() >= hwidLimit) {
|
||||||
throw new LicenseHwidLimitExceededException();
|
throw new LicenseHwidLimitExceededException();
|
||||||
}
|
}
|
||||||
// The license was used
|
// The license was used
|
||||||
uses++; // Increment uses
|
uses++; // Increment uses
|
||||||
ips.add(ip); // Add the used IP
|
ips.add(hashedIp); // Add the used IP
|
||||||
hwids.add(hwid); // Add the used HWID
|
hwids.add(hwid); // Add the used HWID
|
||||||
lastUsed = new Date(); // Last used now
|
lastUsed = new Date(); // Last used now
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package me.braydon.license.service;
|
|||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.braydon.license.common.RandomUtils;
|
|
||||||
import me.braydon.license.exception.APIException;
|
import me.braydon.license.exception.APIException;
|
||||||
import me.braydon.license.exception.LicenseNotFoundException;
|
import me.braydon.license.exception.LicenseNotFoundException;
|
||||||
import me.braydon.license.model.License;
|
import me.braydon.license.model.License;
|
||||||
@ -33,8 +32,14 @@ public final class LicenseService {
|
|||||||
/**
|
/**
|
||||||
* The salt to use for hashing license keys.
|
* The salt to use for hashing license keys.
|
||||||
*/
|
*/
|
||||||
@Value("${key-salt}")
|
@Value("${salts.licenses}")
|
||||||
@NonNull private String keySalt;
|
@NonNull private String licensesSalt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The salt to use for hashing IP addresses.
|
||||||
|
*/
|
||||||
|
@Value("${salts.ips}")
|
||||||
|
@NonNull private String ipsSalt;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LicenseService(@NonNull LicenseRepository repository) {
|
public LicenseService(@NonNull LicenseRepository repository) {
|
||||||
@ -68,7 +73,7 @@ public final class LicenseService {
|
|||||||
String description, int ipLimit, int hwidLimit) {
|
String description, int ipLimit, int hwidLimit) {
|
||||||
// Create the new license
|
// Create the new license
|
||||||
License license = new License();
|
License license = new License();
|
||||||
license.setKey(BCrypt.hashpw(key, keySalt)); // Hash the key
|
license.setKey(BCrypt.hashpw(key, licensesSalt)); // Hash the key
|
||||||
license.setProduct(product); // Use the given product
|
license.setProduct(product); // Use the given product
|
||||||
license.setDescription(description); // Use the given description, if any
|
license.setDescription(description); // Use the given description, if any
|
||||||
license.setIps(new HashSet<>());
|
license.setIps(new HashSet<>());
|
||||||
@ -92,13 +97,13 @@ public final class LicenseService {
|
|||||||
*/
|
*/
|
||||||
public void check(@NonNull String key, @NonNull String product,
|
public void check(@NonNull String key, @NonNull String product,
|
||||||
@NonNull String ip, @NonNull String hwid) throws APIException {
|
@NonNull String ip, @NonNull String hwid) throws APIException {
|
||||||
Optional<License> optionalLicense = repository.getLicense(BCrypt.hashpw(key, keySalt), product); // Get the license
|
Optional<License> optionalLicense = repository.getLicense(BCrypt.hashpw(key, licensesSalt), product); // Get the license
|
||||||
if (optionalLicense.isEmpty()) { // License key not found
|
if (optionalLicense.isEmpty()) { // License key not found
|
||||||
log.error("License key {} for product {} not found", key, product); // Log the error
|
log.error("License key {} for product {} not found", key, product); // Log the error
|
||||||
throw new LicenseNotFoundException();
|
throw new LicenseNotFoundException();
|
||||||
}
|
}
|
||||||
License license = optionalLicense.get(); // The license found
|
License license = optionalLicense.get(); // The license found
|
||||||
license.use(ip, hwid); // Use the license
|
license.use(ip, ipsSalt, hwid); // Use the license
|
||||||
repository.save(license); // Save the used license
|
repository.save(license); // Save the used license
|
||||||
log.info("License key {} for product {} was used by {} ({})", key, product, ip, hwid);
|
log.info("License key {} for product {} was used by {} ({})", key, product, ip, hwid);
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,11 @@ server:
|
|||||||
address: 0.0.0.0
|
address: 0.0.0.0
|
||||||
port: 7500
|
port: 7500
|
||||||
|
|
||||||
# The salt to use when hashing license keys.
|
# The salt to use when hashing license keys and IP addresses.
|
||||||
# This salt should be changed from the default.
|
# These salts should be changed from the default.
|
||||||
key-salt: "$2a$10$/nQyzQDMkCf97ZlJLLWa3O"
|
salts:
|
||||||
|
licenses: "$2a$10$/nQyzQDMkCf97ZlJLLWa3O"
|
||||||
|
ips: "$2a$10$Xus.AHTCas97Ofx0tFs85O"
|
||||||
|
|
||||||
# Log Configuration
|
# Log Configuration
|
||||||
logging:
|
logging:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user