Merge branch 'hwid' into 'master'
HWID See merge request sheepitrenderfarm/client!95
This commit is contained in:
@@ -18,6 +18,7 @@ Parameters as GET:
|
|||||||
* hostname (optional): Hostname of the machine, useful for distinguishing multiple machines with the same hardware configuration. Only used for display on the website.
|
* hostname (optional): Hostname of the machine, useful for distinguishing multiple machines with the same hardware configuration. Only used for display on the website.
|
||||||
* ui (optional): User interface used by the client, useful for statistics
|
* ui (optional): User interface used by the client, useful for statistics
|
||||||
* headless: Is the machine is running headless (Eevee is not compatible with headless)
|
* headless: Is the machine is running headless (Eevee is not compatible with headless)
|
||||||
|
* hwid: a pseudonymous hardware hash
|
||||||
|
|
||||||
Answer in case of error:
|
Answer in case of error:
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import java.util.stream.Collectors;
|
|||||||
import com.sheepit.client.datamodel.SpeedTestTarget;
|
import com.sheepit.client.datamodel.SpeedTestTarget;
|
||||||
import com.sheepit.client.datamodel.SpeedTestResult;
|
import com.sheepit.client.datamodel.SpeedTestResult;
|
||||||
import com.sheepit.client.datamodel.SpeedTestTargetResult;
|
import com.sheepit.client.datamodel.SpeedTestTargetResult;
|
||||||
|
import com.sheepit.client.hardware.hwid.HWIdentifier;
|
||||||
import com.sheepit.client.os.Windows;
|
import com.sheepit.client.os.Windows;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.simpleframework.xml.core.Persister;
|
import org.simpleframework.xml.core.Persister;
|
||||||
@@ -213,6 +214,7 @@ public class Server extends Thread {
|
|||||||
.add("ui", client.getGui().getClass().getSimpleName())
|
.add("ui", client.getGui().getClass().getSimpleName())
|
||||||
.add("extras", user_config.getExtras())
|
.add("extras", user_config.getExtras())
|
||||||
.add("headless", java.awt.GraphicsEnvironment.isHeadless() ? "1" : (user_config.isHeadless() ? "1" : "0"))
|
.add("headless", java.awt.GraphicsEnvironment.isHeadless() ? "1" : (user_config.isHeadless() ? "1" : "0"))
|
||||||
|
.add("hwid", new HWIdentifier(log).getHardwareHash())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.log.debug("Server::getConfiguration url " + remoteURL.build().toString());
|
this.log.debug("Server::getConfiguration url " + remoteURL.build().toString());
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.sheepit.client.hardware.hwid;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface BasicHWInfoStrategy {
|
||||||
|
|
||||||
|
Optional<String> getHarddriveID();
|
||||||
|
Optional<String> getMAC();
|
||||||
|
Optional<String> getProcessorName();
|
||||||
|
}
|
||||||
74
src/com/sheepit/client/hardware/hwid/HWIdentifier.java
Normal file
74
src/com/sheepit/client/hardware/hwid/HWIdentifier.java
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package com.sheepit.client.hardware.hwid;
|
||||||
|
|
||||||
|
import com.sheepit.client.Log;
|
||||||
|
import com.sheepit.client.hardware.hwid.impl.BaseHWInfoImpl;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
|
public class HWIdentifier {
|
||||||
|
private final BasicHWInfoStrategy strategy;
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
public HWIdentifier(Log log) {
|
||||||
|
strategy = new BaseHWInfoImpl();
|
||||||
|
this.log = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMAC() {
|
||||||
|
return strategy.getMAC().orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHarddriveSerial() {
|
||||||
|
return strategy.getHarddriveID().orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProcessorName() {
|
||||||
|
return strategy.getProcessorName().orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHardwareHash() {
|
||||||
|
byte[] hash;
|
||||||
|
String mac;
|
||||||
|
String cpuName;
|
||||||
|
String hdSerial;
|
||||||
|
|
||||||
|
try {
|
||||||
|
MessageDigest digest = MessageDigest.getInstance("md5");
|
||||||
|
if ((hdSerial = getHarddriveSerial()).length() > 0) {
|
||||||
|
hash = digest.digest(hdSerial.getBytes(StandardCharsets.UTF_8));
|
||||||
|
log.debug("HWIdentifier::getHardwareHash found hdd hash");
|
||||||
|
}
|
||||||
|
else if ((mac = getMAC()).length() > 0) {
|
||||||
|
hash = digest.digest(mac.getBytes(StandardCharsets.UTF_8));
|
||||||
|
log.debug("HWIdentifier::getHardwareHash found MAC hash");
|
||||||
|
}
|
||||||
|
else { //Fallback: computing a hash out of homepath+jarFileLocation+cpuName
|
||||||
|
log.debug("HWIdentifier::getHardwareHash using fallback method");
|
||||||
|
cpuName = getProcessorName();
|
||||||
|
if (cpuName.isEmpty()) {
|
||||||
|
log.error("HWIdentifier::getHardwareHash failed to retrieve CPU name. Can't create hardware hash");
|
||||||
|
throw new UnsupportedOperationException("Unable to create hash!");
|
||||||
|
}
|
||||||
|
|
||||||
|
String homeDir = System.getProperty("user.home"); //get home path
|
||||||
|
URL clientURL = getClass().getProtectionDomain().getCodeSource().getLocation();
|
||||||
|
String clientPath = new File(clientURL.toString()).getParent(); //get jar file location
|
||||||
|
|
||||||
|
hash = digest.digest((homeDir + clientPath + cpuName).getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger num = new BigInteger(1, hash);
|
||||||
|
return num.toString(16);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error("HWIdentifier::getHardwareHash could not retrieve hash: " + e);
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package com.sheepit.client.hardware.hwid.impl;
|
||||||
|
|
||||||
|
import com.sheepit.client.hardware.hwid.BasicHWInfoStrategy;
|
||||||
|
import com.sun.jna.Platform;
|
||||||
|
import oshi.SystemInfo;
|
||||||
|
import oshi.hardware.HWDiskStore;
|
||||||
|
import oshi.hardware.HardwareAbstractionLayer;
|
||||||
|
import oshi.hardware.NetworkIF;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class BaseHWInfoImpl implements BasicHWInfoStrategy {
|
||||||
|
protected HardwareAbstractionLayer hardware;
|
||||||
|
|
||||||
|
public BaseHWInfoImpl() {
|
||||||
|
hardware = new SystemInfo().getHardware();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getMAC() {
|
||||||
|
List<String> macs = new ArrayList<>();
|
||||||
|
List<NetworkIF> nics = hardware.getNetworkIFs();
|
||||||
|
for (NetworkIF nic : nics) {
|
||||||
|
macs.add(nic.getMacaddr());
|
||||||
|
}
|
||||||
|
Collections.sort(macs);
|
||||||
|
return Optional.of(String.join(" ", macs));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getProcessorName() {
|
||||||
|
return Optional.of(hardware.getProcessor().getProcessorIdentifier().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> getHarddriveID() {
|
||||||
|
String rootMountpoint;
|
||||||
|
if (Platform.isWindows()) {
|
||||||
|
rootMountpoint = "C:";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rootMountpoint = "/";
|
||||||
|
}
|
||||||
|
return getHarddriveID(rootMountpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to find the root partition and returns that hard drives serial
|
||||||
|
* @param rootMountpoint
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Optional<String> getHarddriveID(String rootMountpoint) {
|
||||||
|
var drives = hardware.getDiskStores();
|
||||||
|
|
||||||
|
String hddSerial = "";
|
||||||
|
boolean rootFound = false;
|
||||||
|
Iterator<HWDiskStore> iterator = drives.iterator();
|
||||||
|
|
||||||
|
while (rootFound == false && iterator.hasNext()) {
|
||||||
|
var drive = iterator.next();
|
||||||
|
for (var partition : drive.getPartitions()) {
|
||||||
|
if (partition.getMountPoint().equals(rootMountpoint)) {
|
||||||
|
hddSerial = drive.getSerial();
|
||||||
|
rootFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hddSerial.isEmpty() ? Optional.empty() : Optional.of(hddSerial);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user