mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 08:16:21 +02:00
Revert "Merge pull request #12981 from birarda/bug/revert-hmac"
This reverts commit91b93db0c5
, reversing changes made to6062f21da1
.
This commit is contained in:
parent
91b93db0c5
commit
3233cc43ac
9 changed files with 186 additions and 39 deletions
94
libraries/networking/src/HMACAuth.cpp
Normal file
94
libraries/networking/src/HMACAuth.cpp
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
//
|
||||||
|
// HMACAuth.cpp
|
||||||
|
// libraries/networking/src
|
||||||
|
//
|
||||||
|
// Created by Simon Walton on 3/19/2018.
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <openssl/opensslv.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
|
#include "HMACAuth.h"
|
||||||
|
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
||||||
|
HMACAuth::HMACAuth(AuthMethod authMethod)
|
||||||
|
: _hmacContext(HMAC_CTX_new())
|
||||||
|
, _authMethod(authMethod) { }
|
||||||
|
|
||||||
|
HMACAuth::~HMACAuth()
|
||||||
|
{
|
||||||
|
HMAC_CTX_free(_hmacContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
HMACAuth::HMACAuth(AuthMethod authMethod)
|
||||||
|
: _hmacContext(new HMAC_CTX())
|
||||||
|
, _authMethod(authMethod) {
|
||||||
|
HMAC_CTX_init(_hmacContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
HMACAuth::~HMACAuth() {
|
||||||
|
HMAC_CTX_cleanup(_hmacContext);
|
||||||
|
delete _hmacContext;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool HMACAuth::setKey(const char* keyValue, int keyLen) {
|
||||||
|
const EVP_MD* sslStruct = nullptr;
|
||||||
|
|
||||||
|
switch (_authMethod) {
|
||||||
|
case MD5:
|
||||||
|
sslStruct = EVP_md5();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHA1:
|
||||||
|
sslStruct = EVP_sha1();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHA224:
|
||||||
|
sslStruct = EVP_sha224();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHA256:
|
||||||
|
sslStruct = EVP_sha256();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIPEMD160:
|
||||||
|
sslStruct = EVP_ripemd160();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMutexLocker lock(&_lock);
|
||||||
|
return (bool) HMAC_Init_ex(_hmacContext, keyValue, keyLen, sslStruct, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HMACAuth::setKey(const QUuid& uidKey) {
|
||||||
|
const QByteArray rfcBytes(uidKey.toRfc4122());
|
||||||
|
return setKey(rfcBytes.constData(), rfcBytes.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HMACAuth::addData(const char* data, int dataLen) {
|
||||||
|
QMutexLocker lock(&_lock);
|
||||||
|
return (bool) HMAC_Update(_hmacContext, reinterpret_cast<const unsigned char*>(data), dataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
HMACAuth::HMACHash HMACAuth::result() {
|
||||||
|
HMACHash hashValue(EVP_MAX_MD_SIZE);
|
||||||
|
unsigned int hashLen;
|
||||||
|
QMutexLocker lock(&_lock);
|
||||||
|
HMAC_Final(_hmacContext, &hashValue[0], &hashLen);
|
||||||
|
hashValue.resize((size_t) hashLen);
|
||||||
|
// Clear state for possible reuse.
|
||||||
|
HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr);
|
||||||
|
return hashValue;
|
||||||
|
}
|
40
libraries/networking/src/HMACAuth.h
Normal file
40
libraries/networking/src/HMACAuth.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// HMACAuth.h
|
||||||
|
// libraries/networking/src
|
||||||
|
//
|
||||||
|
// Created by Simon Walton on 3/19/2018.
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_HMACAuth_h
|
||||||
|
#define hifi_HMACAuth_h
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include <QtCore/QMutex>
|
||||||
|
|
||||||
|
class QUuid;
|
||||||
|
|
||||||
|
class HMACAuth {
|
||||||
|
public:
|
||||||
|
enum AuthMethod { MD5, SHA1, SHA224, SHA256, RIPEMD160 };
|
||||||
|
using HMACHash = std::vector<unsigned char>;
|
||||||
|
|
||||||
|
explicit HMACAuth(AuthMethod authMethod = MD5);
|
||||||
|
~HMACAuth();
|
||||||
|
|
||||||
|
bool setKey(const char* keyValue, int keyLen);
|
||||||
|
bool setKey(const QUuid& uidKey);
|
||||||
|
bool addData(const char* data, int dataLen);
|
||||||
|
HMACHash result();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMutex _lock;
|
||||||
|
struct hmac_ctx_st* _hmacContext;
|
||||||
|
AuthMethod _authMethod;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_HMACAuth_h
|
|
@ -36,6 +36,7 @@
|
||||||
#include "HifiSockAddr.h"
|
#include "HifiSockAddr.h"
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
#include "udt/Packet.h"
|
#include "udt/Packet.h"
|
||||||
|
#include "HMACAuth.h"
|
||||||
|
|
||||||
static Setting::Handle<quint16> LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0);
|
static Setting::Handle<quint16> LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0);
|
||||||
|
|
||||||
|
@ -330,7 +331,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe
|
||||||
if (verifiedPacket && !ignoreVerification) {
|
if (verifiedPacket && !ignoreVerification) {
|
||||||
|
|
||||||
QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet);
|
QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet);
|
||||||
QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, sourceNode->getConnectionSecret());
|
QByteArray expectedHash = NLPacket::hashForPacketAndHMAC(packet, sourceNode->getAuthenticateHash());
|
||||||
|
|
||||||
// check if the md5 hash in the header matches the hash we would expect
|
// check if the md5 hash in the header matches the hash we would expect
|
||||||
if (packetHeaderHash != expectedHash) {
|
if (packetHeaderHash != expectedHash) {
|
||||||
|
@ -370,15 +371,15 @@ void LimitedNodeList::collectPacketStats(const NLPacket& packet) {
|
||||||
_numCollectedBytes += packet.getDataSize();
|
_numCollectedBytes += packet.getDataSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimitedNodeList::fillPacketHeader(const NLPacket& packet, const QUuid& connectionSecret) {
|
void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth) {
|
||||||
if (!PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())) {
|
if (!PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())) {
|
||||||
packet.writeSourceID(getSessionLocalID());
|
packet.writeSourceID(getSessionLocalID());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!connectionSecret.isNull()
|
if (hmacAuth
|
||||||
&& !PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())
|
&& !PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())
|
||||||
&& !PacketTypeEnum::getNonVerifiedPackets().contains(packet.getType())) {
|
&& !PacketTypeEnum::getNonVerifiedPackets().contains(packet.getType())) {
|
||||||
packet.writeVerificationHashGivenSecret(connectionSecret);
|
packet.writeVerificationHash(*hmacAuth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,17 +395,17 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node&
|
||||||
emit dataSent(destinationNode.getType(), packet.getDataSize());
|
emit dataSent(destinationNode.getType(), packet.getDataSize());
|
||||||
destinationNode.recordBytesSent(packet.getDataSize());
|
destinationNode.recordBytesSent(packet.getDataSize());
|
||||||
|
|
||||||
return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), destinationNode.getConnectionSecret());
|
return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), &destinationNode.getAuthenticateHash());
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr,
|
qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr,
|
||||||
const QUuid& connectionSecret) {
|
HMACAuth* hmacAuth) {
|
||||||
Q_ASSERT(!packet.isPartOfMessage());
|
Q_ASSERT(!packet.isPartOfMessage());
|
||||||
Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket",
|
Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket",
|
||||||
"Trying to send a reliable packet unreliably.");
|
"Trying to send a reliable packet unreliably.");
|
||||||
|
|
||||||
collectPacketStats(packet);
|
collectPacketStats(packet);
|
||||||
fillPacketHeader(packet, connectionSecret);
|
fillPacketHeader(packet, hmacAuth);
|
||||||
|
|
||||||
return _nodeSocket.writePacket(packet, sockAddr);
|
return _nodeSocket.writePacket(packet, sockAddr);
|
||||||
}
|
}
|
||||||
|
@ -417,7 +418,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const Node&
|
||||||
emit dataSent(destinationNode.getType(), packet->getDataSize());
|
emit dataSent(destinationNode.getType(), packet->getDataSize());
|
||||||
destinationNode.recordBytesSent(packet->getDataSize());
|
destinationNode.recordBytesSent(packet->getDataSize());
|
||||||
|
|
||||||
return sendPacket(std::move(packet), *activeSocket, destinationNode.getConnectionSecret());
|
return sendPacket(std::move(packet), *activeSocket, &destinationNode.getAuthenticateHash());
|
||||||
} else {
|
} else {
|
||||||
qCDebug(networking) << "LimitedNodeList::sendPacket called without active socket for node" << destinationNode << "- not sending";
|
qCDebug(networking) << "LimitedNodeList::sendPacket called without active socket for node" << destinationNode << "- not sending";
|
||||||
return ERROR_SENDING_PACKET_BYTES;
|
return ERROR_SENDING_PACKET_BYTES;
|
||||||
|
@ -425,18 +426,18 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const Node&
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const HifiSockAddr& sockAddr,
|
qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const HifiSockAddr& sockAddr,
|
||||||
const QUuid& connectionSecret) {
|
HMACAuth* hmacAuth) {
|
||||||
Q_ASSERT(!packet->isPartOfMessage());
|
Q_ASSERT(!packet->isPartOfMessage());
|
||||||
if (packet->isReliable()) {
|
if (packet->isReliable()) {
|
||||||
collectPacketStats(*packet);
|
collectPacketStats(*packet);
|
||||||
fillPacketHeader(*packet, connectionSecret);
|
fillPacketHeader(*packet, hmacAuth);
|
||||||
|
|
||||||
auto size = packet->getDataSize();
|
auto size = packet->getDataSize();
|
||||||
_nodeSocket.writePacket(std::move(packet), sockAddr);
|
_nodeSocket.writePacket(std::move(packet), sockAddr);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
} else {
|
} else {
|
||||||
return sendUnreliablePacket(*packet, sockAddr, connectionSecret);
|
return sendUnreliablePacket(*packet, sockAddr, hmacAuth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,13 +446,14 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi
|
||||||
|
|
||||||
if (activeSocket) {
|
if (activeSocket) {
|
||||||
qint64 bytesSent = 0;
|
qint64 bytesSent = 0;
|
||||||
auto connectionSecret = destinationNode.getConnectionSecret();
|
auto& connectionHash = destinationNode.getAuthenticateHash();
|
||||||
|
|
||||||
// close the last packet in the list
|
// close the last packet in the list
|
||||||
packetList.closeCurrentPacket();
|
packetList.closeCurrentPacket();
|
||||||
|
|
||||||
while (!packetList._packets.empty()) {
|
while (!packetList._packets.empty()) {
|
||||||
bytesSent += sendPacket(packetList.takeFront<NLPacket>(), *activeSocket, connectionSecret);
|
bytesSent += sendPacket(packetList.takeFront<NLPacket>(), *activeSocket,
|
||||||
|
&connectionHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit dataSent(destinationNode.getType(), bytesSent);
|
emit dataSent(destinationNode.getType(), bytesSent);
|
||||||
|
@ -464,14 +466,14 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr,
|
qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr,
|
||||||
const QUuid& connectionSecret) {
|
HMACAuth* hmacAuth) {
|
||||||
qint64 bytesSent = 0;
|
qint64 bytesSent = 0;
|
||||||
|
|
||||||
// close the last packet in the list
|
// close the last packet in the list
|
||||||
packetList.closeCurrentPacket();
|
packetList.closeCurrentPacket();
|
||||||
|
|
||||||
while (!packetList._packets.empty()) {
|
while (!packetList._packets.empty()) {
|
||||||
bytesSent += sendPacket(packetList.takeFront<NLPacket>(), sockAddr, connectionSecret);
|
bytesSent += sendPacket(packetList.takeFront<NLPacket>(), sockAddr, hmacAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytesSent;
|
return bytesSent;
|
||||||
|
@ -499,7 +501,7 @@ qint64 LimitedNodeList::sendPacketList(std::unique_ptr<NLPacketList> packetList,
|
||||||
for (std::unique_ptr<udt::Packet>& packet : packetList->_packets) {
|
for (std::unique_ptr<udt::Packet>& packet : packetList->_packets) {
|
||||||
NLPacket* nlPacket = static_cast<NLPacket*>(packet.get());
|
NLPacket* nlPacket = static_cast<NLPacket*>(packet.get());
|
||||||
collectPacketStats(*nlPacket);
|
collectPacketStats(*nlPacket);
|
||||||
fillPacketHeader(*nlPacket, destinationNode.getConnectionSecret());
|
fillPacketHeader(*nlPacket, &destinationNode.getAuthenticateHash());
|
||||||
}
|
}
|
||||||
|
|
||||||
return _nodeSocket.writePacketList(std::move(packetList), *activeSocket);
|
return _nodeSocket.writePacketList(std::move(packetList), *activeSocket);
|
||||||
|
@ -522,7 +524,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const Node&
|
||||||
auto& destinationSockAddr = (overridenSockAddr.isNull()) ? *destinationNode.getActiveSocket()
|
auto& destinationSockAddr = (overridenSockAddr.isNull()) ? *destinationNode.getActiveSocket()
|
||||||
: overridenSockAddr;
|
: overridenSockAddr;
|
||||||
|
|
||||||
return sendPacket(std::move(packet), destinationSockAddr, destinationNode.getConnectionSecret());
|
return sendPacket(std::move(packet), destinationSockAddr, &destinationNode.getAuthenticateHash());
|
||||||
}
|
}
|
||||||
|
|
||||||
int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||||
|
|
|
@ -138,19 +138,17 @@ public:
|
||||||
// use sendUnreliablePacket to send an unreliable packet (that you do not need to move)
|
// use sendUnreliablePacket to send an unreliable packet (that you do not need to move)
|
||||||
// either to a node (via its active socket) or to a manual sockaddr
|
// either to a node (via its active socket) or to a manual sockaddr
|
||||||
qint64 sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode);
|
qint64 sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode);
|
||||||
qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr,
|
qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, HMACAuth* hmacAuth = nullptr);
|
||||||
const QUuid& connectionSecret = QUuid());
|
|
||||||
|
|
||||||
// use sendPacket to send a moved unreliable or reliable NL packet to a node's active socket or manual sockaddr
|
// use sendPacket to send a moved unreliable or reliable NL packet to a node's active socket or manual sockaddr
|
||||||
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode);
|
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode);
|
||||||
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const HifiSockAddr& sockAddr,
|
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const HifiSockAddr& sockAddr, HMACAuth* hmacAuth = nullptr);
|
||||||
const QUuid& connectionSecret = QUuid());
|
|
||||||
|
|
||||||
// use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list
|
// use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list
|
||||||
// either to a node's active socket or to a manual sockaddr
|
// either to a node's active socket or to a manual sockaddr
|
||||||
qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode);
|
qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode);
|
||||||
qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr,
|
qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr,
|
||||||
const QUuid& connectionSecret = QUuid());
|
HMACAuth* hmacAuth = nullptr);
|
||||||
|
|
||||||
// use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket
|
// use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket
|
||||||
// or to a manual sock addr
|
// or to a manual sock addr
|
||||||
|
@ -372,7 +370,7 @@ protected:
|
||||||
qint64 writePacket(const NLPacket& packet, const HifiSockAddr& destinationSockAddr,
|
qint64 writePacket(const NLPacket& packet, const HifiSockAddr& destinationSockAddr,
|
||||||
const QUuid& connectionSecret = QUuid());
|
const QUuid& connectionSecret = QUuid());
|
||||||
void collectPacketStats(const NLPacket& packet);
|
void collectPacketStats(const NLPacket& packet);
|
||||||
void fillPacketHeader(const NLPacket& packet, const QUuid& connectionSecret = QUuid());
|
void fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth = nullptr);
|
||||||
|
|
||||||
void setLocalSocket(const HifiSockAddr& sockAddr);
|
void setLocalSocket(const HifiSockAddr& sockAddr);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include "NLPacket.h"
|
#include "NLPacket.h"
|
||||||
|
|
||||||
|
#include "HMACAuth.h"
|
||||||
|
|
||||||
int NLPacket::localHeaderSize(PacketType type) {
|
int NLPacket::localHeaderSize(PacketType type) {
|
||||||
bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type);
|
bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type);
|
||||||
bool nonVerified = PacketTypeEnum::getNonVerifiedPackets().contains(type);
|
bool nonVerified = PacketTypeEnum::getNonVerifiedPackets().contains(type);
|
||||||
|
@ -150,18 +152,14 @@ QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) {
|
||||||
return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH);
|
return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret) {
|
QByteArray NLPacket::hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash) {
|
||||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
|
||||||
|
|
||||||
int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion)
|
int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion)
|
||||||
+ NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH;
|
+ NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH;
|
||||||
|
|
||||||
// add the packet payload and the connection UUID
|
// add the packet payload and the connection UUID
|
||||||
hash.addData(packet.getData() + offset, packet.getDataSize() - offset);
|
hash.addData(packet.getData() + offset, packet.getDataSize() - offset);
|
||||||
hash.addData(connectionSecret.toRfc4122());
|
auto hashResult { hash.result() };
|
||||||
|
return QByteArray((const char*) hashResult.data(), (int) hashResult.size());
|
||||||
// return the hash
|
|
||||||
return hash.result();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NLPacket::writeTypeAndVersion() {
|
void NLPacket::writeTypeAndVersion() {
|
||||||
|
@ -214,14 +212,14 @@ void NLPacket::writeSourceID(LocalID sourceID) const {
|
||||||
_sourceID = sourceID;
|
_sourceID = sourceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NLPacket::writeVerificationHashGivenSecret(const QUuid& connectionSecret) const {
|
void NLPacket::writeVerificationHash(HMACAuth& hmacAuth) const {
|
||||||
Q_ASSERT(!PacketTypeEnum::getNonSourcedPackets().contains(_type) &&
|
Q_ASSERT(!PacketTypeEnum::getNonSourcedPackets().contains(_type) &&
|
||||||
!PacketTypeEnum::getNonVerifiedPackets().contains(_type));
|
!PacketTypeEnum::getNonVerifiedPackets().contains(_type));
|
||||||
|
|
||||||
auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion)
|
auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion)
|
||||||
+ NUM_BYTES_LOCALID;
|
+ NUM_BYTES_LOCALID;
|
||||||
|
|
||||||
QByteArray verificationHash = hashForPacketAndSecret(*this, connectionSecret);
|
QByteArray verificationHash = hashForPacketAndHMAC(*this, hmacAuth);
|
||||||
|
|
||||||
memcpy(_packet.get() + offset, verificationHash.data(), verificationHash.size());
|
memcpy(_packet.get() + offset, verificationHash.data(), verificationHash.size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#include "udt/Packet.h"
|
#include "udt/Packet.h"
|
||||||
|
|
||||||
|
class HMACAuth;
|
||||||
|
|
||||||
class NLPacket : public udt::Packet {
|
class NLPacket : public udt::Packet {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -69,7 +71,7 @@ public:
|
||||||
|
|
||||||
static LocalID sourceIDInHeader(const udt::Packet& packet);
|
static LocalID sourceIDInHeader(const udt::Packet& packet);
|
||||||
static QByteArray verificationHashInHeader(const udt::Packet& packet);
|
static QByteArray verificationHashInHeader(const udt::Packet& packet);
|
||||||
static QByteArray hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret);
|
static QByteArray hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash);
|
||||||
|
|
||||||
PacketType getType() const { return _type; }
|
PacketType getType() const { return _type; }
|
||||||
void setType(PacketType type);
|
void setType(PacketType type);
|
||||||
|
@ -78,9 +80,9 @@ public:
|
||||||
void setVersion(PacketVersion version);
|
void setVersion(PacketVersion version);
|
||||||
|
|
||||||
LocalID getSourceID() const { return _sourceID; }
|
LocalID getSourceID() const { return _sourceID; }
|
||||||
|
|
||||||
void writeSourceID(LocalID sourceID) const;
|
void writeSourceID(LocalID sourceID) const;
|
||||||
void writeVerificationHashGivenSecret(const QUuid& connectionSecret) const;
|
void writeVerificationHash(HMACAuth& hmacAuth) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -86,10 +86,10 @@ NodeType_t NodeType::fromString(QString type) {
|
||||||
|
|
||||||
|
|
||||||
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
||||||
const HifiSockAddr& localSocket, QObject* parent) :
|
const HifiSockAddr& localSocket, QObject* parent) :
|
||||||
NetworkPeer(uuid, publicSocket, localSocket, parent),
|
NetworkPeer(uuid, publicSocket, localSocket, parent),
|
||||||
_type(type),
|
_type(type),
|
||||||
_pingMs(-1), // "Uninitialized"
|
_authenticateHash(new HMACAuth), _pingMs(-1), // "Uninitialized"
|
||||||
_clockSkewUsec(0),
|
_clockSkewUsec(0),
|
||||||
_mutex(),
|
_mutex(),
|
||||||
_clockSkewMovingPercentile(30, 0.8f) // moving 80th percentile of 30 samples
|
_clockSkewMovingPercentile(30, 0.8f) // moving 80th percentile of 30 samples
|
||||||
|
@ -108,6 +108,7 @@ void Node::setType(char type) {
|
||||||
_symmetricSocket.setObjectName(typeString);
|
_symmetricSocket.setObjectName(typeString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Node::updateClockSkewUsec(qint64 clockSkewSample) {
|
void Node::updateClockSkewUsec(qint64 clockSkewSample) {
|
||||||
_clockSkewMovingPercentile.updatePercentile(clockSkewSample);
|
_clockSkewMovingPercentile.updatePercentile(clockSkewSample);
|
||||||
_clockSkewUsec = (quint64)_clockSkewMovingPercentile.getValueAtPercentile();
|
_clockSkewUsec = (quint64)_clockSkewMovingPercentile.getValueAtPercentile();
|
||||||
|
@ -194,3 +195,12 @@ QDebug operator<<(QDebug debug, const Node& node) {
|
||||||
debug.nospace() << node.getPublicSocket() << "/" << node.getLocalSocket();
|
debug.nospace() << node.getPublicSocket() << "/" << node.getLocalSocket();
|
||||||
return debug.nospace();
|
return debug.nospace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::setConnectionSecret(const QUuid& connectionSecret) {
|
||||||
|
if (_connectionSecret == connectionSecret) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_connectionSecret = connectionSecret;
|
||||||
|
_authenticateHash->setKey(_connectionSecret);
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "SimpleMovingAverage.h"
|
#include "SimpleMovingAverage.h"
|
||||||
#include "MovingPercentile.h"
|
#include "MovingPercentile.h"
|
||||||
#include "NodePermissions.h"
|
#include "NodePermissions.h"
|
||||||
|
#include "HMACAuth.h"
|
||||||
|
|
||||||
class Node : public NetworkPeer {
|
class Node : public NetworkPeer {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -55,7 +56,8 @@ public:
|
||||||
void setIsUpstream(bool isUpstream) { _isUpstream = isUpstream; }
|
void setIsUpstream(bool isUpstream) { _isUpstream = isUpstream; }
|
||||||
|
|
||||||
const QUuid& getConnectionSecret() const { return _connectionSecret; }
|
const QUuid& getConnectionSecret() const { return _connectionSecret; }
|
||||||
void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; }
|
void setConnectionSecret(const QUuid& connectionSecret);
|
||||||
|
HMACAuth& getAuthenticateHash() const { return *_authenticateHash; }
|
||||||
|
|
||||||
NodeData* getLinkedData() const { return _linkedData.get(); }
|
NodeData* getLinkedData() const { return _linkedData.get(); }
|
||||||
void setLinkedData(std::unique_ptr<NodeData> linkedData) { _linkedData = std::move(linkedData); }
|
void setLinkedData(std::unique_ptr<NodeData> linkedData) { _linkedData = std::move(linkedData); }
|
||||||
|
@ -97,6 +99,7 @@ private:
|
||||||
NodeType_t _type;
|
NodeType_t _type;
|
||||||
|
|
||||||
QUuid _connectionSecret;
|
QUuid _connectionSecret;
|
||||||
|
std::unique_ptr<HMACAuth> _authenticateHash;
|
||||||
std::unique_ptr<NodeData> _linkedData;
|
std::unique_ptr<NodeData> _linkedData;
|
||||||
bool _isReplicated { false };
|
bool _isReplicated { false };
|
||||||
int _pingMs;
|
int _pingMs;
|
||||||
|
|
|
@ -91,7 +91,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
||||||
case PacketType::Ping:
|
case PacketType::Ping:
|
||||||
return static_cast<PacketVersion>(PingVersion::IncludeConnectionID);
|
return static_cast<PacketVersion>(PingVersion::IncludeConnectionID);
|
||||||
default:
|
default:
|
||||||
return 20;
|
return 19;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue