Merge branch 'hwid' into 'master'

HWID

See merge request sheepitrenderfarm/client!95
This commit is contained in:
Sheepit Renderfarm
2022-01-04 17:25:42 +00:00
5 changed files with 161 additions and 0 deletions

View File

@@ -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" ?>

View File

@@ -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());

View File

@@ -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();
}

View 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";
}
}
}

View File

@@ -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);
}
}