Merge pull request #1092 from daleglass/implement_linux_fingerprint

Implement Linux machine fingerprints
This commit is contained in:
daleglass 2021-03-20 19:16:07 +01:00 committed by GitHub
commit 7086412d1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

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