uLicense/uLicense-1.2.6/ULicense.java

357 lines
12 KiB
Java

package dev.license.ulicense;
import org.bukkit.plugin.Plugin;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.Base64;
import java.util.Enumeration;
import java.util.Scanner;
public class ULicense {
private Plugin plugin;
private String productKey;
private String server;
private String authorization;
private static final String UNKNOWN = "unknown";
private static String OS = System.getProperty("os.name").toLowerCase();
public ULicense(Plugin plugin, String licenseKey, String validationServer, String authorization) {
this.plugin = plugin;
this.productKey = licenseKey;
this.server = validationServer;
this.authorization = authorization;
}
public boolean verify() {
System.out.println("--------------------> Login <--------------------");
System.out.println(" |- Verifying your license...");
System.out.println(" ");
String[] respo = isValid();
System.out.println(respo[0]);
if (respo[0].equals("2")) {
System.out.println(" |- Your license is valid.");
System.out.println("-------------------------------------------------");
return true;
} else if (respo[0].equals("3")) {
System.out.println(" |- Your license is valid, but version is outdated.");
System.out.println(" ");
System.out.println(" |- Your version: " + plugin.getDescription().getVersion());
System.out.println(" |- Latest version: " + respo[1].split("#")[1]);
System.out.println("-------------------------------------------------");
return true;
} else {
System.out.println(" |- Your license is invalid.");
System.out.println(" ");
System.out.println(" |- Reason: " + respo[1]);
System.out.println("-------------------------------------------------");
return false;
}
}
private String requestServer(String productKey) throws IOException {
URL url = new URL(server);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "uLicense");
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
String hwid = getMac();
String outString = "{\"hwid\":\"password\",\"license\":\"key\",\"plugin\":\"NiceCar\",\"version\":\"dogpoop\"}";
//Align HWID again here if someone tries to spoof it
outString = outString
.replaceAll("password", getHWID())
.replaceAll("key", productKey)
.replaceAll("NiceCar", plugin.getName())
.replaceAll("dogpoop", plugin.getDescription().getVersion());
byte[] out = outString.getBytes(StandardCharsets.UTF_8);
int length = out.length;
con.setFixedLengthStreamingMode(length);
con.setRequestProperty("Authorization", this.authorization);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.connect();
try(OutputStream os = con.getOutputStream()) {
os.write(out);
}
if(!url.getHost().equals(con.getURL().getHost())) return "successful_authentication";
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
return response.toString();
}
}
private String requestServerHTTPS(String productKey) throws IOException {
URL url = new URL(server);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "uLicense");
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
String hwid = getMac();
String outString = "{\"hwid\":\"password\",\"license\":\"key\",\"plugin\":\"NiceCar\",\"version\":\"dogpoop\"}";
//Align HWID again here if someone tries to spoof it
outString = outString
.replaceAll("password", getHWID())
.replaceAll("key", productKey)
.replaceAll("NiceCar", plugin.getName())
.replaceAll("dogpoop", plugin.getDescription().getVersion());
byte[] out = outString.getBytes(StandardCharsets.UTF_8);
int length = out.length;
con.setFixedLengthStreamingMode(length);
con.setRequestProperty("Authorization", this.authorization);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.connect();
try(OutputStream os = con.getOutputStream()) {
os.write(out);
}
if(!url.getHost().equals(con.getURL().getHost())) return "successful_authentication";
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
return response.toString();
}
}
public String[] isValid() {
try {
String response;
if(server.contains("http")) {
response = requestServer(productKey);
} else {
response = requestServerHTTPS(productKey);
}
if(!response.contains("{")) {
return new String[]{"1", "ODD_RESULT"};
}
int respLength = response.length();
String hash = null;
String version = null;
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(response);
String neekeri = json.get("msg").toString();
String status = json.get("status").toString();
if(status.contains("success")) {
hash = json.get("neekeri").toString();
version = json.get("version").toString();
}
if(version != null && !version.equals(plugin.getDescription().getVersion())) {
return new String[]{"3", "OUTDATED_VERSION#" + version};
}
if(hash != null && version != null) {
String[] aa = hash.split("694201337");
String hashed = aa[0];
String decoded = new String(Base64.getDecoder().decode(hashed));
if(!decoded.equals(productKey.substring(0, 2) + productKey.substring(productKey.length() - 2) + authorization.substring(0, 2))) {
return new String[]{"1", "FAILED_AUTHENTICATION"};
}
String time = String.valueOf(Instant.now().getEpochSecond());
String unix = time.substring(0, time.length() - 2);
long t = Long.parseLong(unix);
long hashT = Long.parseLong(aa[1]);
if(Math.abs(t - hashT) > 1) {
return new String[]{"1", "FAILED_AUTHENTICATION"};
}
}
int statusLength = status.length();
if(!isValidLength(statusLength)) {
return new String[]{"1", neekeri};
}
final boolean valid = status.contains("success") && response.contains("success") && String.valueOf(statusLength).equals("7");
return new String[]{valid ? "2" : "1", neekeri};
} catch (IOException | ParseException ex) {
ex.printStackTrace();
return new String[]{"1", "ERROR"};
}
}
public boolean isValidLength(int reps) {
return reps == 7;
}
//Spoofed methods to trick cracker
public boolean isValidLength22(int reps) {
return reps == 11;
}
public boolean isValidLength222(int reps) {
return reps == 44;
}
public boolean isValidLength2222(int reps) {
return reps == 48;
}
public String getMac() throws SocketException {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
StringBuilder sb = new StringBuilder();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface ni = networkInterfaces.nextElement();
byte[] hardwareAddress = ni.getHardwareAddress();
if (hardwareAddress != null) {
for (byte address : hardwareAddress) {
sb.append(String.format("%02X", address));
}
return sb.toString();
}
}
return null;
}
public static String getHWID() {
try {
if (isWindows()) {
return getWindowsIdentifier();
} else if (isMac()) {
return getMacOsIdentifier();
} else if (isLinux()) {
return getLinuxMacAddress();
} else {
return UNKNOWN;
}
} catch (Exception e) {
return UNKNOWN;
}
}
private static boolean isWindows() {
return (OS.contains("win"));
}
private static boolean isMac() {
return (OS.contains("mac"));
}
private static boolean isLinux() {
return (OS.contains("inux"));
}
private static String getLinuxMacAddress() throws FileNotFoundException, NoSuchAlgorithmException {
File machineId = new File("/var/lib/dbus/machine-id");
if (!machineId.exists()) {
machineId = new File("/etc/machine-id");
}
if (!machineId.exists()) {
return UNKNOWN;
}
Scanner scanner = null;
try {
scanner = new Scanner(machineId);
String id = scanner.useDelimiter("\\A").next();
return hexStringify(sha256Hash(id.getBytes()));
} finally {
if (scanner != null) {
scanner.close();
}
}
}
private static String getMacOsIdentifier() throws SocketException, NoSuchAlgorithmException {
NetworkInterface networkInterface = NetworkInterface.getByName("en0");
byte[] hardwareAddress = networkInterface.getHardwareAddress();
return hexStringify(sha256Hash(hardwareAddress));
}
private static String getWindowsIdentifier() throws IOException, NoSuchAlgorithmException {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(new String[]{"wmic", "csproduct", "get", "UUID"});
String result = null;
InputStream is = process.getInputStream();
Scanner sc = new Scanner(process.getInputStream());
try {
while (sc.hasNext()) {
String next = sc.next();
if (next.contains("UUID")) {
result = sc.next().trim();
break;
}
}
} finally {
is.close();
}
return result == null ? UNKNOWN : hexStringify(sha256Hash(result.getBytes()));
}
/**
* Compute the SHA-256 hash of the given byte array
*
* @param data the byte array to hash
* @return the hashed byte array
* @throws NoSuchAlgorithmException
*/
public static byte[] sha256Hash(byte[] data) throws NoSuchAlgorithmException {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
return messageDigest.digest(data);
}
/**
* Convert a byte array to its hex-string
*
* @param data the byte array to convert
* @return the hex-string of the byte array
*/
public static String hexStringify(byte[] data) {
StringBuilder stringBuilder = new StringBuilder();
for (byte singleByte : data) {
stringBuilder.append(Integer.toString((singleByte & 0xff) + 0x100, 16).substring(1));
}
return stringBuilder.toString();
}
}