From 02e2135a2ecda70ee2855c4210fc4405634de177 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 7 Apr 2014 12:52:26 -0700 Subject: [PATCH] allow setting of expected DTLS cert hostname from AC --- assignment-client/src/AssignmentClient.cpp | 58 ++++++++++------------ assignment-client/src/AssignmentClient.h | 1 + libraries/shared/src/DTLSClientSession.cpp | 11 +++- libraries/shared/src/DomainHandler.cpp | 7 ++- libraries/shared/src/DomainHandler.h | 2 +- 5 files changed, 43 insertions(+), 36 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 222cb0ce9a..d5d6beaead 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -31,7 +31,8 @@ int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), - _currentAssignment() + _currentAssignment(), + _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) { DTLSClientSession::globalInit(); @@ -40,57 +41,48 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : setApplicationName("assignment-client"); QSettings::setDefaultFormat(QSettings::IniFormat); + QStringList argumentList = arguments(); + // register meta type is required for queued invoke method on Assignment subclasses // set the logging target to the the CHILD_TARGET_NAME Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); - const char ASSIGNMENT_TYPE_OVVERIDE_OPTION[] = "-t"; - const char* assignmentTypeString = getCmdOption(argc, (const char**)argv, ASSIGNMENT_TYPE_OVVERIDE_OPTION); + const QString ASSIGNMENT_TYPE_OVVERIDE_OPTION = "-t"; + int argumentIndex = argumentList.indexOf(ASSIGNMENT_TYPE_OVVERIDE_OPTION); Assignment::Type requestAssignmentType = Assignment::AllTypes; - if (assignmentTypeString) { - // the user is asking to only be assigned to a particular type of assignment - // so set that as the ::overridenAssignmentType to be used in requests - requestAssignmentType = (Assignment::Type) atoi(assignmentTypeString); + if (argumentIndex != -1) { + requestAssignmentType = (Assignment::Type) argumentList[argumentIndex + 1].toInt(); } - const char ASSIGNMENT_POOL_OPTION[] = "--pool"; - const char* requestAssignmentPool = getCmdOption(argc, (const char**) argv, ASSIGNMENT_POOL_OPTION); + const QString ASSIGNMENT_POOL_OPTION = "--pool"; + argumentIndex = argumentList.indexOf(ASSIGNMENT_POOL_OPTION); + QString assignmentPool; + + if (argumentIndex != -1) { + assignmentPool = argumentList[argumentIndex + 1]; + } // setup our _requestAssignment member variable from the passed arguments - _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, requestAssignmentPool); + _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool); // create a NodeList as an unassigned client NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned); - const char CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION[] = "-a"; - const char CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION[] = "-p"; + // check for an overriden assignment server hostname + const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "-a"; - // grab the overriden assignment-server hostname from argv, if it exists - const char* customAssignmentServerHostname = getCmdOption(argc, (const char**)argv, CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION); - const char* customAssignmentServerPortString = getCmdOption(argc,(const char**)argv, CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION); + argumentIndex = argumentList.indexOf(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION); - HifiSockAddr customAssignmentSocket; - - if (customAssignmentServerHostname || customAssignmentServerPortString) { + if (argumentIndex != -1) { + _assignmentServerHostname = argumentList[argumentIndex + 1]; - // set the custom port or default if it wasn't passed - unsigned short assignmentServerPort = customAssignmentServerPortString - ? atoi(customAssignmentServerPortString) : DEFAULT_DOMAIN_SERVER_PORT; + // set the custom assignment socket on our NodeList + HifiSockAddr customAssignmentSocket = HifiSockAddr(_assignmentServerHostname, DEFAULT_DOMAIN_SERVER_PORT); - // set the custom hostname or default if it wasn't passed - if (!customAssignmentServerHostname) { - customAssignmentServerHostname = DEFAULT_ASSIGNMENT_SERVER_HOSTNAME; - } - - customAssignmentSocket = HifiSockAddr(customAssignmentServerHostname, assignmentServerPort); - } - - // set the custom assignment socket if we have it - if (!customAssignmentSocket.isNull()) { nodeList->setAssignmentServerSocket(customAssignmentSocket); } @@ -138,9 +130,9 @@ void AssignmentClient::readPendingDatagrams() { if (_currentAssignment) { qDebug() << "Received an assignment -" << *_currentAssignment; - // switch our nodelist domain IP and port to whoever sent us the assignment + // switch our DomainHandler hostname and port to whoever sent us the assignment - nodeList->getDomainHandler().setSockAddr(senderSockAddr); + nodeList->getDomainHandler().setSockAddr(senderSockAddr, _assignmentServerHostname); nodeList->getDomainHandler().setAssignmentUUID(_currentAssignment->getUUID()); qDebug() << "Destination IP for assignment is" << nodeList->getDomainHandler().getIP().toString(); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 939d06b14f..33b1dd70e9 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -26,6 +26,7 @@ private slots: private: Assignment _requestAssignment; SharedAssignmentPointer _currentAssignment; + QString _assignmentServerHostname; }; #endif /* defined(__hifi__AssignmentClient__) */ diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 0ebb282f29..ec8e121013 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -6,6 +6,8 @@ // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. // +#include "DomainHandler.h" + #include "DTLSClientSession.h" gnutls_certificate_credentials_t DTLSClientSession::_x509CACredentials; @@ -30,7 +32,14 @@ void DTLSClientSession::globalDeinit() { int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { unsigned int verifyStatus = 0; - int certReturn = gnutls_certificate_verify_peers3(session, NULL, &verifyStatus); + + // grab the hostname from the domain handler that this session is associated with + DomainHandler* domainHandler = reinterpret_cast(gnutls_session_get_ptr(session)); + qDebug() << "Checking for" << domainHandler->getHostname() << "from cert."; + + int certReturn = gnutls_certificate_verify_peers3(session, + domainHandler->getHostname().toLocal8Bit().constData(), + &verifyStatus); if (certReturn < 0) { return GNUTLS_E_CERTIFICATE_ERROR; diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index 380a9a4b7b..4773a368a4 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -58,6 +58,8 @@ void DomainHandler::initializeDTLSSession() { if (!_dtlsSession) { _dtlsSession = new DTLSClientSession(NodeList::getInstance()->getDTLSSocket(), _sockAddr); + gnutls_session_set_ptr(*_dtlsSession->getGnuTLSSession(), this); + // start a timer to complete the handshake process _handshakeTimer = new QTimer(this); connect(_handshakeTimer, &QTimer::timeout, this, &DomainHandler::completeDTLSHandshake); @@ -70,13 +72,16 @@ void DomainHandler::initializeDTLSSession() { } } -void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr) { +void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname) { if (_sockAddr != sockAddr) { // we should reset on a sockAddr change reset(); // change the sockAddr _sockAddr = sockAddr; } + + // some callers may pass a hostname, this is not to be used for lookup but for DTLS certificate verification + _hostname = hostname; } void DomainHandler::setHostname(const QString& hostname) { diff --git a/libraries/shared/src/DomainHandler.h b/libraries/shared/src/DomainHandler.h index c34321cf87..106eff67f1 100644 --- a/libraries/shared/src/DomainHandler.h +++ b/libraries/shared/src/DomainHandler.h @@ -40,7 +40,7 @@ public: void setIPToLocalhost() { _sockAddr.setAddress(QHostAddress(QHostAddress::LocalHost)); } const HifiSockAddr& getSockAddr() { return _sockAddr; } - void setSockAddr(const HifiSockAddr& sockAddr); + void setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname); unsigned short getPort() const { return _sockAddr.getPort(); }