mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 22:10:25 +02:00
complete inital DTLS setup in domain-server
This commit is contained in:
parent
dc38b27485
commit
da30d21f6e
4 changed files with 90 additions and 10 deletions
|
@ -35,7 +35,10 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
_HTTPManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this),
|
_HTTPManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this),
|
||||||
_staticAssignmentHash(),
|
_staticAssignmentHash(),
|
||||||
_assignmentQueue(),
|
_assignmentQueue(),
|
||||||
_x509Credentials()
|
_isUsingDTLS(false),
|
||||||
|
_x509Credentials(NULL),
|
||||||
|
_dhParams(NULL),
|
||||||
|
_priorityCache(NULL)
|
||||||
{
|
{
|
||||||
setOrganizationName("High Fidelity");
|
setOrganizationName("High Fidelity");
|
||||||
setOrganizationDomain("highfidelity.io");
|
setOrganizationDomain("highfidelity.io");
|
||||||
|
@ -44,29 +47,85 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
|
|
||||||
_argumentList = arguments();
|
_argumentList = arguments();
|
||||||
|
|
||||||
if (readCertificateAndPrivateKey()) {
|
if (optionallySetupDTLS()) {
|
||||||
// we either read a certificate and private key or were not passed one, good to load assignments
|
// we either read a certificate and private key or were not passed one, good to load assignments
|
||||||
// and set up the node list
|
// and set up the node list
|
||||||
|
qDebug() << "Setting up NodeList and assignments.";
|
||||||
setupNodeListAndAssignments();
|
setupNodeListAndAssignments();
|
||||||
|
|
||||||
|
if (_isUsingDTLS) {
|
||||||
|
// we're using DTLS and our NodeList socket is good to go, so make the required DTLS changes
|
||||||
|
// DTLS requires that IP_DONTFRAG be set
|
||||||
|
// This is not accessible on some platforms (OS X) so we need to make sure DTLS still works without it
|
||||||
|
|
||||||
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
#if defined(IP_DONTFRAG) || defined(IP_MTU_DISCOVER)
|
||||||
|
qDebug() << "Making required DTLS changes to NodeList DTLS socket.";
|
||||||
|
|
||||||
|
int socketHandle = NodeList::getInstance()->getDTLSSocket().socketDescriptor();
|
||||||
|
#if defined(IP_DONTFRAG)
|
||||||
|
int optValue = 1;yea
|
||||||
|
setsockopt(socketHandle, IPPROTO_IP, IP_DONTFRAG, (const void*) optValue, sizeof(optValue));
|
||||||
|
#elif defined(IP_MTU_DISCOVER)
|
||||||
|
int optValue = 1;
|
||||||
|
setsockopt(socketHandle, IPPROTO_IP, IP_MTU_DISCOVER, (const void*) optValue, sizeof(optValue));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
// connect our socket to read datagrams received on the DTLS socket
|
||||||
|
connect(&nodeList->getDTLSSocket(), &QUdpSocket::readyRead, this, &DomainServer::readAvailableDTLSDatagrams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DomainServer::readCertificateAndPrivateKey() {
|
bool DomainServer::optionallySetupDTLS() {
|
||||||
|
if (readX509KeyAndCertificate()) {
|
||||||
|
qDebug() << "Generating Diffie-Hellman parameters.";
|
||||||
|
|
||||||
|
// generate Diffie-Hellman parameters
|
||||||
|
// When short bit length is used, it might be wise to regenerate parameters often.
|
||||||
|
int dhBits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY);
|
||||||
|
|
||||||
|
_dhParams = new gnutls_dh_params_t;
|
||||||
|
gnutls_dh_params_init(_dhParams);
|
||||||
|
gnutls_dh_params_generate2(*_dhParams, dhBits);
|
||||||
|
|
||||||
|
qDebug() << "Successfully generated Diffie-Hellman parameters.";
|
||||||
|
|
||||||
|
// set the D-H paramters on the X509 credentials
|
||||||
|
gnutls_certificate_set_dh_params(*_x509Credentials, *_dhParams);
|
||||||
|
|
||||||
|
_priorityCache = new gnutls_priority_t;
|
||||||
|
const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.2:%SERVER_PRECEDENCE";
|
||||||
|
gnutls_priority_init(_priorityCache, DTLS_PRIORITY_STRING, NULL);
|
||||||
|
|
||||||
|
_isUsingDTLS = true;
|
||||||
|
|
||||||
|
qDebug() << "Initial DTLS setup complete.";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DomainServer::readX509KeyAndCertificate() {
|
||||||
const QString X509_CERTIFICATE_OPTION = "--cert";
|
const QString X509_CERTIFICATE_OPTION = "--cert";
|
||||||
const QString X509_PRIVATE_KEY_OPTION = "--key";
|
const QString X509_PRIVATE_KEY_OPTION = "--key";
|
||||||
const QString X509_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE";
|
const QString X509_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE";
|
||||||
|
|
||||||
int certIndex = _argumentList.indexOf(X509_CERTIFICATE_OPTION);
|
int certIndex = _argumentList.indexOf(X509_CERTIFICATE_OPTION);
|
||||||
int keyIndex = _argumentList.indexOf(X509_PRIVATE_KEY_OPTION);
|
int keyIndex = _argumentList.indexOf(X509_PRIVATE_KEY_OPTION);
|
||||||
|
|
||||||
if (certIndex != -1 && keyIndex != -1) {
|
if (certIndex != -1 && keyIndex != -1) {
|
||||||
// the user wants to use DTLS to encrypt communication with nodes
|
// the user wants to use DTLS to encrypt communication with nodes
|
||||||
// let's make sure we can load the ey
|
// let's make sure we can load the key and certificate
|
||||||
gnutls_certificate_allocate_credentials(&_x509Credentials);
|
_x509Credentials = new gnutls_certificate_credentials_t;
|
||||||
|
gnutls_certificate_allocate_credentials(_x509Credentials);
|
||||||
|
|
||||||
QString keyPassphraseString = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV);
|
QString keyPassphraseString = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV);
|
||||||
|
|
||||||
int gnutlsReturn = gnutls_certificate_set_x509_key_file2(_x509Credentials,
|
int gnutlsReturn = gnutls_certificate_set_x509_key_file2(*_x509Credentials,
|
||||||
_argumentList[certIndex + 1].toLocal8Bit().constData(),
|
_argumentList[certIndex + 1].toLocal8Bit().constData(),
|
||||||
_argumentList[keyIndex + 1].toLocal8Bit().constData(),
|
_argumentList[keyIndex + 1].toLocal8Bit().constData(),
|
||||||
GNUTLS_X509_FMT_PEM,
|
GNUTLS_X509_FMT_PEM,
|
||||||
|
@ -79,7 +138,8 @@ bool DomainServer::readCertificateAndPrivateKey() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Successfully read certificate and private key. Using DTLS for node communication.";
|
qDebug() << "Successfully read certificate and private key.";
|
||||||
|
|
||||||
} else if (certIndex != -1 || keyIndex != -1) {
|
} else if (certIndex != -1 || keyIndex != -1) {
|
||||||
qDebug() << "Missing certificate or private key. domain-server will now quit.";
|
qDebug() << "Missing certificate or private key. domain-server will now quit.";
|
||||||
QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
|
||||||
|
@ -552,6 +612,10 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DomainServer::readAvailableDTLSDatagrams() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QJsonObject DomainServer::jsonForSocket(const HifiSockAddr& socket) {
|
QJsonObject DomainServer::jsonForSocket(const HifiSockAddr& socket) {
|
||||||
QJsonObject socketJSON;
|
QJsonObject socketJSON;
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,11 @@ private slots:
|
||||||
void processCreateResponseFromDataServer(const QJsonObject& jsonObject);
|
void processCreateResponseFromDataServer(const QJsonObject& jsonObject);
|
||||||
|
|
||||||
void readAvailableDatagrams();
|
void readAvailableDatagrams();
|
||||||
|
void readAvailableDTLSDatagrams();
|
||||||
private:
|
private:
|
||||||
void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid());
|
void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid());
|
||||||
bool readCertificateAndPrivateKey();
|
bool optionallySetupDTLS();
|
||||||
|
bool readX509KeyAndCertificate();
|
||||||
|
|
||||||
void requestAuthenticationFromPotentialNode(const HifiSockAddr& senderSockAddr);
|
void requestAuthenticationFromPotentialNode(const HifiSockAddr& senderSockAddr);
|
||||||
void addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr,
|
void addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr,
|
||||||
|
@ -81,7 +83,10 @@ private:
|
||||||
|
|
||||||
QStringList _argumentList;
|
QStringList _argumentList;
|
||||||
|
|
||||||
gnutls_certificate_credentials_t _x509Credentials;
|
bool _isUsingDTLS;
|
||||||
|
gnutls_certificate_credentials_t* _x509Credentials;
|
||||||
|
gnutls_dh_params_t* _dhParams;
|
||||||
|
gnutls_priority_t* _priorityCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__DomainServer__) */
|
#endif /* defined(__hifi__DomainServer__) */
|
||||||
|
|
|
@ -89,6 +89,15 @@ NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
|
||||||
_packetStatTimer.start();
|
_packetStatTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QUdpSocket& NodeList::getDTLSSocket() {
|
||||||
|
if (_dtlsSocket.state() == QAbstractSocket::UnconnectedState) {
|
||||||
|
_dtlsSocket.bind(QHostAddress::AnyIPv4);
|
||||||
|
qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket.localPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _dtlsSocket;
|
||||||
|
}
|
||||||
|
|
||||||
void NodeList::changeSendSocketBufferSize(int numSendBytes) {
|
void NodeList::changeSendSocketBufferSize(int numSendBytes) {
|
||||||
// change the socket send buffer size to be 1MB
|
// change the socket send buffer size to be 1MB
|
||||||
int oldBufferSize = 0;
|
int oldBufferSize = 0;
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
void setSessionUUID(const QUuid& sessionUUID);
|
void setSessionUUID(const QUuid& sessionUUID);
|
||||||
|
|
||||||
QUdpSocket& getNodeSocket() { return _nodeSocket; }
|
QUdpSocket& getNodeSocket() { return _nodeSocket; }
|
||||||
|
QUdpSocket& getDTLSSocket();
|
||||||
|
|
||||||
bool packetVersionAndHashMatch(const QByteArray& packet);
|
bool packetVersionAndHashMatch(const QByteArray& packet);
|
||||||
|
|
||||||
|
@ -165,6 +166,7 @@ private:
|
||||||
NodeHash _nodeHash;
|
NodeHash _nodeHash;
|
||||||
QMutex _nodeHashMutex;
|
QMutex _nodeHashMutex;
|
||||||
QUdpSocket _nodeSocket;
|
QUdpSocket _nodeSocket;
|
||||||
|
QUdpSocket _dtlsSocket;
|
||||||
NodeType_t _ownerType;
|
NodeType_t _ownerType;
|
||||||
NodeSet _nodeTypesOfInterest;
|
NodeSet _nodeTypesOfInterest;
|
||||||
DomainInfo _domainInfo;
|
DomainInfo _domainInfo;
|
||||||
|
|
Loading…
Reference in a new issue