mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 11:02:24 +02:00
Implement Linux machine fingerprints
We do this by using either /etc/machine-id, or hashing the MACs of all non-virtual networking devices. We make this fingerpint unique to our platform by adding our own string to the hash, and add some stretching for good measure. This way Vircadia's fingerprint isn't going to match the system's ID or anything another application generates.
This commit is contained in:
parent
5e2cc4c4bf
commit
1ed767df41
1 changed files with 77 additions and 2 deletions
|
@ -17,6 +17,9 @@
|
|||
#include <SettingHandle.h>
|
||||
#include <SettingManager.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <QFile>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDirIterator>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <Windows.h>
|
||||
|
@ -36,8 +39,80 @@ QUuid FingerprintUtils::_machineFingerprint { QUuid() };
|
|||
QString FingerprintUtils::getMachineFingerprintString() {
|
||||
QString uuidString;
|
||||
#ifdef Q_OS_LINUX
|
||||
// sadly need to be root to get smbios guid from linux, so
|
||||
// for now lets do nothing.
|
||||
// As per the documentation:
|
||||
// https://man7.org/linux/man-pages/man5/machine-id.5.html
|
||||
//
|
||||
// we use the machine id as a base, but add an application-specific key to it.
|
||||
// If machine-id isn't available, we try hardware networking devices instead.
|
||||
|
||||
QCryptographicHash hash(QCryptographicHash::Keccak_256);
|
||||
|
||||
QFile machineIdFile("/etc/machine-id");
|
||||
if (!machineIdFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
// No machine ID, probably no systemd.
|
||||
qCWarning(networking) << "Failed to open /etc/machine-id";
|
||||
|
||||
QDir netDevicesDir("/sys/class/net");
|
||||
QFileInfoList netDevicesInfo = netDevicesDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
|
||||
|
||||
if (netDevicesInfo.empty()) {
|
||||
// Let getMachineFingerprint handle this contingency
|
||||
qCWarning(networking) << "Failed to find any hardware networking devices";
|
||||
return "";
|
||||
}
|
||||
|
||||
for(auto& fileInfo : netDevicesInfo) {
|
||||
|
||||
if (fileInfo.isSymLink() && fileInfo.symLinkTarget().contains("virtual")) {
|
||||
// symlink points to something like:
|
||||
// ../../devices/virtual/net/lo
|
||||
// these are not real devices and have random IDs, so we
|
||||
// don't care about them.
|
||||
continue;
|
||||
}
|
||||
|
||||
QFile addressFile(fileInfo.filePath() + "/address");
|
||||
if (addressFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qCDebug(networking) << "Adding contents of " << addressFile.fileName();
|
||||
hash.addData(addressFile.readAll());
|
||||
} else {
|
||||
qCWarning(networking) << "Failed to read " << addressFile.fileName();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QByteArray data = machineIdFile.readAll();
|
||||
hash.addData(data);
|
||||
}
|
||||
|
||||
// Makes this hash unique to us
|
||||
hash.addData("Vircadia");
|
||||
|
||||
// Stretching
|
||||
for (int i=0; i < 65535; i++) {
|
||||
hash.addData(hash.result());
|
||||
}
|
||||
|
||||
QByteArray result = hash.result();
|
||||
result.resize(128 / 8); // GUIDs are 128 bit numbers
|
||||
|
||||
// Set UUID version to 4, ensuring it's a valid UUID
|
||||
result[6] = (result[6] & 0x0F) | 0x40;
|
||||
|
||||
// Of course, Qt couldn't be nice and just parse something like:
|
||||
// 1b1b9d6d45c2473bac13dc3011ff58d6
|
||||
//
|
||||
// So we have to turn it into:
|
||||
// {1b1b9d6d-45c2-473b-ac13-dc3011ff58d6}
|
||||
|
||||
uuidString = result.toHex();
|
||||
uuidString.insert(20, '-');
|
||||
uuidString.insert(16, '-');
|
||||
uuidString.insert(12, '-');
|
||||
uuidString.insert(8, '-');
|
||||
uuidString.prepend("{");
|
||||
uuidString.append("}");
|
||||
|
||||
qCDebug(networking) << "Linux machine fingerprint:" << uuidString;
|
||||
#endif //Q_OS_LINUX
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
|
Loading…
Reference in a new issue