inital cut, passing fingerprint in

does permissions same as mac address, more or less.  Not exposed
yet, just a beginning.
This commit is contained in:
David Kelly 2016-12-14 14:51:35 -08:00
parent 1aec8c5a65
commit cb14b0e3e0
11 changed files with 94 additions and 13 deletions

View file

@ -120,19 +120,21 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
nodeData->setPlaceName(nodeConnection.placeName);
qDebug() << "Allowed connection from node" << uuidStringWithoutCurlyBraces(node->getUUID())
<< "on" << message->getSenderSockAddr() << "with MAC" << nodeConnection.hardwareAddress;
<< "on" << message->getSenderSockAddr() << "with MAC" << nodeConnection.hardwareAddress
<< " and machine fingerprint " << nodeConnection.machineFingerprint;
// signal that we just connected a node so the DomainServer can get it a list
// and broadcast its presence right away
emit connectedNode(node);
} else {
qDebug() << "Refusing connection from node at" << message->getSenderSockAddr()
<< "with hardware address" << nodeConnection.hardwareAddress;
<< "with hardware address" << nodeConnection.hardwareAddress
<< " and machine fingerprint " << nodeConnection.machineFingerprint;
}
}
NodePermissions DomainGatekeeper::setPermissionsForUser(bool isLocalUser, QString verifiedUsername,
const QHostAddress& senderAddress, const QString& hardwareAddress) {
NodePermissions DomainGatekeeper::setPermissionsForUser(bool isLocalUser, QString verifiedUsername, const QHostAddress& senderAddress,
const QString& hardwareAddress, const QUuid& machineFingerprint) {
NodePermissions userPerms;
userPerms.setAll(false);
@ -155,6 +157,11 @@ NodePermissions DomainGatekeeper::setPermissionsForUser(bool isLocalUser, QStrin
#ifdef WANT_DEBUG
qDebug() << "| user-permissions: specific MAC matches, so:" << userPerms;
#endif
} else if (_server->_settingsManager.hasPermissionsForMachineFingerprint(machineFingerprint)) {
userPerms = _server->_settingsManager.getPermissionsForMachineFingerprint(machineFingerprint);
#ifdef WANT_DEBUG
qDebug(() << "| user-permissions: specific Machine Fingerprint matches, so: " << userPerms;
#endif
} else if (_server->_settingsManager.hasPermissionsForIP(senderAddress)) {
// this user comes from an IP we have in our permissions table, apply those permissions
@ -274,13 +281,15 @@ void DomainGatekeeper::updateNodePermissions() {
HifiSockAddr connectingAddr = node->getActiveSocket() ? *node->getActiveSocket() : node->getPublicSocket();
QString hardwareAddress;
QUuid machineFingerprint;
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
if (nodeData) {
hardwareAddress = nodeData->getHardwareAddress();
machineFingerprint = nodeData->getMachineFingerprint();
}
userPerms = setPermissionsForUser(isLocalUser, verifiedUsername, connectingAddr.getAddress(), hardwareAddress);
userPerms = setPermissionsForUser(isLocalUser, verifiedUsername, connectingAddr.getAddress(), hardwareAddress, machineFingerprint);
}
node->setPermissions(userPerms);
@ -334,6 +343,8 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo
nodeData->setWalletUUID(it->second.getWalletUUID());
nodeData->setNodeVersion(it->second.getNodeVersion());
nodeData->setHardwareAddress(nodeConnection.hardwareAddress);
nodeData->setMachineFingerprint(nodeConnection.machineFingerprint);
nodeData->setWasAssigned(true);
// cleanup the PendingAssignedNodeData for this assignment now that it's connecting
@ -396,7 +407,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
}
userPerms = setPermissionsForUser(isLocalUser, verifiedUsername, nodeConnection.senderSockAddr.getAddress(),
nodeConnection.hardwareAddress);
nodeConnection.hardwareAddress, nodeConnection.machineFingerprint);
if (!userPerms.can(NodePermissions::Permission::canConnectToDomain)) {
sendConnectionDeniedPacket("You lack the required permissions to connect to this domain.",
@ -455,6 +466,9 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
// set the hardware address passed in the connect request
nodeData->setHardwareAddress(nodeConnection.hardwareAddress);
// set the machine fingerprint passed in the connect request
nodeData->setMachineFingerprint(nodeConnection.machineFingerprint);
// also add an interpolation to DomainServerNodeData so that servers can get username in stats
nodeData->addOverrideForKey(USERNAME_UUID_REPLACEMENT_STATS_KEY,
uuidStringWithoutCurlyBraces(newNode->getUUID()), username);

View file

@ -107,8 +107,8 @@ private:
QSet<QString> _domainOwnerFriends; // keep track of friends of the domain owner
QSet<QString> _inFlightGroupMembershipsRequests; // keep track of which we've already asked for
NodePermissions setPermissionsForUser(bool isLocalUser, QString verifiedUsername,
const QHostAddress& senderAddress, const QString& hardwareAddress);
NodePermissions setPermissionsForUser(bool isLocalUser, QString verifiedUsername, const QHostAddress& senderAddress,
const QString& hardwareAddress, const QUuid& machineFingerprint);
void getGroupMemberships(const QString& username);
// void getIsGroupMember(const QString& username, const QUuid groupID);

View file

@ -56,7 +56,10 @@ public:
void setHardwareAddress(const QString& hardwareAddress) { _hardwareAddress = hardwareAddress; }
const QString& getHardwareAddress() { return _hardwareAddress; }
void setMachineFingerprint(const QUuid& machineFingerprint) { _machineFingerprint = machineFingerprint; }
const QUuid& getMachineFingerprint() { return _machineFingerprint; }
void addOverrideForKey(const QString& key, const QString& value, const QString& overrideValue);
void removeOverrideForKey(const QString& key, const QString& value);
@ -85,6 +88,7 @@ private:
NodeSet _nodeInterestSet;
QString _nodeVersion;
QString _hardwareAddress;
QUuid _machineFingerprint;
QString _placeName;

View file

@ -444,6 +444,9 @@ void DomainServerSettingsManager::packPermissions() {
// save settings for MAC addresses
packPermissionsForMap("permissions", _macPermissions, MAC_PERMISSIONS_KEYPATH);
// save settings for Machine Fingerprint
packPermissionsForMap("permissions", _machineFingerprintPermissions, MACHINE_FINGERPRINT_PERMISSIONS_KEYPATH);
// save settings for groups
packPermissionsForMap("permissions", _groupPermissions, GROUP_PERMISSIONS_KEYPATH);
@ -522,6 +525,18 @@ void DomainServerSettingsManager::unpackPermissions() {
}
});
needPack |= unpackPermissionsForKeypath(MACHINE_FINGERPRINT_PERMISSIONS_KEYPATH, &_machineFingerprintPermissions,
[&](NodePermissionsPointer perms){
// make sure that this permission row has valid machine fingerprint
if (QUuid(perms->getKey().first) == QUuid()) {
_machineFingerprintPermissions.remove(perms->getKey());
// we removed a row, so we'll need a re-pack
needPack = true;
}
});
needPack |= unpackPermissionsForKeypath(GROUP_PERMISSIONS_KEYPATH, &_groupPermissions,
[&](NodePermissionsPointer perms){
@ -575,7 +590,9 @@ void DomainServerSettingsManager::unpackPermissions() {
QList<QHash<NodePermissionsKey, NodePermissionsPointer>> permissionsSets;
permissionsSets << _standardAgentPermissions.get() << _agentPermissions.get()
<< _groupPermissions.get() << _groupForbiddens.get()
<< _ipPermissions.get() << _macPermissions.get();
<< _ipPermissions.get() << _macPermissions.get()
<< _machineFingerprintPermissions.get();
foreach (auto permissionSet, permissionsSets) {
QHashIterator<NodePermissionsKey, NodePermissionsPointer> i(permissionSet);
while (i.hasNext()) {
@ -707,9 +724,10 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer<Re
ipPermissions->clear(NodePermissions::Permission::canConnectToDomain);
}
// potentially remove connect permissions for the MAC address
// potentially remove connect permissions for the MAC address and machine fingerprint
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(matchingNode->getLinkedData());
if (nodeData) {
// mac address first
NodePermissionsKey macAddressKey(nodeData->getHardwareAddress(), 0);
bool hadMACPermissions = hasPermissionsForMAC(nodeData->getHardwareAddress());
@ -721,6 +739,18 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer<Re
macPermissions->clear(NodePermissions::Permission::canConnectToDomain);
}
// now for machine fingerprint
NodePermissionsKey machineFingerprintKey(nodeData->getMachineFingerprint().toString(), 0);
bool hadFingerprintPermissions = hasPermissionsForMachineFingerprint(nodeData->getMachineFingerprint());
auto fingerprintPermissions = _machineFingerprintPermissions[machineFingerprintKey];
if (!hadFingerprintPermissions || fingerprintPermissions->can(NodePermissions::Permission::canConnectToDomain)) {
newPermissions = true;
fingerprintPermissions->clear(NodePermissions::Permission::canConnectToDomain);
}
}
}
@ -795,6 +825,16 @@ NodePermissions DomainServerSettingsManager::getPermissionsForMAC(const QString&
return nullPermissions;
}
NodePermissions DomainServerSettingsManager::getPermissionsForMachineFingerprint(const QUuid& machineFingerprint) const {
NodePermissionsKey fingerprintKey = NodePermissionsKey(machineFingerprint.toString(), 0);
if (_machineFingerprintPermissions.contains(fingerprintKey)) {
return *(_machineFingerprintPermissions[fingerprintKey].get());
}
NodePermissions nullPermissions;
nullPermissions.setAll(false);
return nullPermissions;
}
NodePermissions DomainServerSettingsManager::getPermissionsForGroup(const QString& groupName, QUuid rankID) const {
NodePermissionsKey groupRankKey = NodePermissionsKey(groupName, rankID);
if (_groupPermissions.contains(groupRankKey)) {

View file

@ -29,6 +29,7 @@ const QString AGENT_STANDARD_PERMISSIONS_KEYPATH = "security.standard_permission
const QString AGENT_PERMISSIONS_KEYPATH = "security.permissions";
const QString IP_PERMISSIONS_KEYPATH = "security.ip_permissions";
const QString MAC_PERMISSIONS_KEYPATH = "security.mac_permissions";
const QString MACHINE_FINGERPRINT_PERMISSIONS_KEYPATH = "security.machine_fingerprint_permissions";
const QString GROUP_PERMISSIONS_KEYPATH = "security.group_permissions";
const QString GROUP_FORBIDDENS_KEYPATH = "security.group_forbiddens";
@ -67,6 +68,10 @@ public:
bool hasPermissionsForMAC(const QString& macAddress) const { return _macPermissions.contains(macAddress, 0); }
NodePermissions getPermissionsForMAC(const QString& macAddress) const;
// these give access to permissions for specific machine fingerprints from the domain-server settings page
bool hasPermissionsForMachineFingerprint(const QUuid& machineFingerprint) { return _machineFingerprintPermissions.contains(machineFingerprint.toString(), 0); }
NodePermissions getPermissionsForMachineFingerprint(const QUuid& machineFingerprint) const;
// these give access to permissions for specific groups from the domain-server settings page
bool havePermissionsForGroup(const QString& groupName, QUuid rankID) const {
return _groupPermissions.contains(groupName, rankID);
@ -148,6 +153,7 @@ private:
NodePermissionsMap _ipPermissions; // permissions granted by node IP address
NodePermissionsMap _macPermissions; // permissions granted by node MAC address
NodePermissionsMap _machineFingerprintPermissions; // permissions granted by Machine Fingerprint
NodePermissionsMap _groupPermissions; // permissions granted by membership to specific groups
NodePermissionsMap _groupForbiddens; // permissions denied due to membership in a specific group

View file

@ -32,6 +32,9 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c
// read the hardware address sent by the client
dataStream >> newHeader.hardwareAddress;
// now the machine fingerprint
dataStream >> newHeader.machineFingerprint;
}
dataStream >> newHeader.nodeType

View file

@ -29,6 +29,7 @@ public:
QList<NodeType_t> interestList;
QString placeName;
QString hardwareAddress;
QUuid machineFingerprint;
QByteArray protocolVersion;
};

View file

@ -45,6 +45,13 @@ QString FingerprintUtils::getMachineFingerprintString() {
IWbemLocator *pLoc = NULL;
// initialize com
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) {
qDebug() << "Failed to initialize COM library!";
return uuidString;
}
// initialize WbemLocator
hres = CoCreateInstance(
CLSID_WbemLocator,
0,

View file

@ -27,6 +27,7 @@
#include "AddressManager.h"
#include "Assignment.h"
#include "HifiSockAddr.h"
#include "FingerprintUtils.h"
#include "NetworkLogging.h"
#include "udt/PacketHeaders.h"
@ -369,6 +370,10 @@ void NodeList::sendDomainServerCheckIn() {
}
packetStream << hardwareAddress;
// add in machine fingerprint
QUuid machineFingerprint = FingerprintUtils::getMachineFingerprint();
packetStream << machineFingerprint;
}
// pack our data to send to the domain-server including

View file

@ -67,7 +67,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
return static_cast<PacketVersion>(DomainConnectionDeniedVersion::IncludesExtraInfo);
case PacketType::DomainConnectRequest:
return static_cast<PacketVersion>(DomainConnectRequestVersion::HasMACAddress);
return static_cast<PacketVersion>(DomainConnectRequestVersion::HasMachineFingerprint);
case PacketType::DomainServerAddedNode:
return static_cast<PacketVersion>(DomainServerAddedNodeVersion::PermissionsGrid);

View file

@ -210,7 +210,8 @@ enum class DomainConnectRequestVersion : PacketVersion {
NoHostname = 17,
HasHostname,
HasProtocolVersions,
HasMACAddress
HasMACAddress,
HasMachineFingerprint
};
enum class DomainConnectionDeniedVersion : PacketVersion {