diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index ff876596b0..d8383ccd48 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -39,8 +39,6 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) { - DTLSClientSession::globalInit(); - setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("assignment-client"); @@ -106,10 +104,6 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : this, &AssignmentClient::handleAuthenticationRequest); } -AssignmentClient::~AssignmentClient() { - DTLSClientSession::globalDeinit(); -} - void AssignmentClient::sendAssignmentRequest() { if (!_currentAssignment) { NodeList::getInstance()->sendAssignment(_requestAssignment); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 2df9f4ca40..9834402dbf 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -21,7 +21,6 @@ class AssignmentClient : public QCoreApplication { public: AssignmentClient(int &argc, char **argv); static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; } - ~AssignmentClient(); private slots: void sendAssignmentRequest(); void readPendingDatagrams(); diff --git a/domain-server/src/DTLSServerSession.cpp b/domain-server/src/DTLSServerSession.cpp deleted file mode 100644 index a80c54ee02..0000000000 --- a/domain-server/src/DTLSServerSession.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// -// DTLSServerSession.cpp -// domain-server/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 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 "DTLSServerSession.h" - -DTLSServerSession::DTLSServerSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : - DTLSSession(GNUTLS_SERVER, dtlsSocket, destinationSocket) -{ - -} \ No newline at end of file diff --git a/domain-server/src/DTLSServerSession.h b/domain-server/src/DTLSServerSession.h deleted file mode 100644 index 5fdc602df7..0000000000 --- a/domain-server/src/DTLSServerSession.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// DTLSServerSession.h -// domain-server/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 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_DTLSServerSession_h -#define hifi_DTLSServerSession_h - -#include - -#include - -class DTLSServerSession : public DTLSSession { -public: - DTLSServerSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); -}; - -#endif // hifi_DTLSServerSession_h diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d9927f3833..fa8a26b259 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -28,7 +28,6 @@ #include #include "DomainServerNodeData.h" -#include "DummyDTLSSession.h" #include "DomainServer.h" @@ -39,18 +38,12 @@ DomainServer::DomainServer(int argc, char* argv[]) : _allAssignments(), _unfulfilledAssignments(), _isUsingDTLS(false), - _x509Credentials(NULL), - _dhParams(NULL), - _priorityCache(NULL), - _dtlsSessions(), _oauthProviderURL(), _oauthClientID(), _hostname(), _networkReplyUUIDMap(), _sessionAuthenticationHash() { - gnutls_global_init(); - setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("domain-server"); @@ -64,31 +57,10 @@ DomainServer::DomainServer(int argc, char* argv[]) : qDebug() << "Setting up LimitedNodeList and assignments."; setupNodeListAndAssignments(); - if (_isUsingDTLS) { - LimitedNodeList* nodeList = LimitedNodeList::getInstance(); - - // connect our socket to read datagrams received on the DTLS socket - connect(&nodeList->getDTLSSocket(), &QUdpSocket::readyRead, this, &DomainServer::readAvailableDTLSDatagrams); - } - _networkAccessManager = new QNetworkAccessManager(this); } } -DomainServer::~DomainServer() { - if (_x509Credentials) { - gnutls_certificate_free_credentials(*_x509Credentials); - gnutls_priority_deinit(*_priorityCache); - gnutls_dh_params_deinit(*_dhParams); - - delete _x509Credentials; - delete _priorityCache; - delete _dhParams; - delete _cookieKey; - } - gnutls_global_deinit(); -} - bool DomainServer::optionallyReadX509KeyAndCertificate() { const QString X509_CERTIFICATE_OPTION = "cert"; const QString X509_PRIVATE_KEY_OPTION = "key"; @@ -100,28 +72,28 @@ bool DomainServer::optionallyReadX509KeyAndCertificate() { if (!certPath.isEmpty() && !keyPath.isEmpty()) { // the user wants to use DTLS to encrypt communication with nodes // let's make sure we can load the key and certificate - _x509Credentials = new gnutls_certificate_credentials_t; - 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); qDebug() << "Reading certificate file at" << certPath << "for DTLS."; qDebug() << "Reading key file at" << keyPath << "for DTLS."; - int gnutlsReturn = gnutls_certificate_set_x509_key_file2(*_x509Credentials, - certPath.toLocal8Bit().constData(), - keyPath.toLocal8Bit().constData(), - GNUTLS_X509_FMT_PEM, - keyPassphraseString.toLocal8Bit().constData(), - 0); +// int gnutlsReturn = gnutls_certificate_set_x509_key_file2(*_x509Credentials, +// certPath.toLocal8Bit().constData(), +// keyPath.toLocal8Bit().constData(), +// GNUTLS_X509_FMT_PEM, +// keyPassphraseString.toLocal8Bit().constData(), +// 0); +// +// if (gnutlsReturn < 0) { +// qDebug() << "Unable to load certificate or key file." << "Error" << gnutlsReturn << "- domain-server will now quit."; +// QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); +// return false; +// } - if (gnutlsReturn < 0) { - qDebug() << "Unable to load certificate or key file." << "Error" << gnutlsReturn << "- domain-server will now quit."; - QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); - return false; - } - - qDebug() << "Successfully read certificate and private key."; +// qDebug() << "Successfully read certificate and private key."; // we need to also pass this certificate and private key to the HTTPS manager // this is used for Oauth callbacks when authorizing users against a data server @@ -176,39 +148,6 @@ bool DomainServer::optionallySetupOAuth() { return true; } -bool DomainServer::optionallySetupDTLS() { - if (_x509Credentials) { - 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); - - // setup the key used for cookie verification - _cookieKey = new gnutls_datum_t; - gnutls_key_generate(_cookieKey, GNUTLS_COOKIE_KEY_SIZE); - - _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; -} - void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { const QString CUSTOM_PORT_OPTION = "port"; @@ -552,8 +491,8 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif if (nodeInterestList.size() > 0) { - DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL; - int dataMTU = dtlsSession ? (int)gnutls_dtls_get_data_mtu(*dtlsSession->getGnuTLSSession()) : MAX_PACKET_SIZE; +// DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL; + int dataMTU = MAX_PACKET_SIZE; if (nodeData->isAuthenticated()) { // if this authenticated node has any interest types, send back those nodes as well @@ -589,11 +528,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif // we need to break here and start a new packet // so send the current one - if (!dtlsSession) { - nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); - } else { - dtlsSession->writeDatagram(broadcastPacket); - } + nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); // reset the broadcastPacket structure broadcastPacket.resize(numBroadcastPacketLeadBytes); @@ -607,11 +542,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif } // always write the last broadcastPacket - if (!dtlsSession) { - nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); - } else { - dtlsSession->writeDatagram(broadcastPacket); - } + nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); } } @@ -689,86 +620,6 @@ void DomainServer::readAvailableDatagrams() { } } -void DomainServer::readAvailableDTLSDatagrams() { - LimitedNodeList* nodeList = LimitedNodeList::getInstance(); - - QUdpSocket& dtlsSocket = nodeList->getDTLSSocket(); - - static sockaddr senderSockAddr; - static socklen_t sockAddrSize = sizeof(senderSockAddr); - - while (dtlsSocket.hasPendingDatagrams()) { - // check if we have an active DTLS session for this sender - QByteArray peekDatagram(dtlsSocket.pendingDatagramSize(), 0); - - recvfrom(dtlsSocket.socketDescriptor(), peekDatagram.data(), dtlsSocket.pendingDatagramSize(), - MSG_PEEK, &senderSockAddr, &sockAddrSize); - - HifiSockAddr senderHifiSockAddr(&senderSockAddr); - DTLSServerSession* existingSession = _dtlsSessions.value(senderHifiSockAddr); - - if (existingSession) { - if (!existingSession->completedHandshake()) { - // check if we have completed handshake with this user - int handshakeReturn = gnutls_handshake(*existingSession->getGnuTLSSession()); - - if (handshakeReturn == 0) { - existingSession->setCompletedHandshake(true); - } else if (gnutls_error_is_fatal(handshakeReturn)) { - // this was a fatal error handshaking, so remove this session - qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) << "- during DTLS handshake with" - << senderHifiSockAddr; - _dtlsSessions.remove(senderHifiSockAddr); - } - } else { - // pull the data from this user off the stack and process it - int receivedBytes = gnutls_record_recv(*existingSession->getGnuTLSSession(), - peekDatagram.data(), peekDatagram.size()); - if (receivedBytes > 0) { - processDatagram(peekDatagram.left(receivedBytes), senderHifiSockAddr); - } else if (gnutls_error_is_fatal(receivedBytes)) { - qDebug() << "Fatal error -" << gnutls_strerror(receivedBytes) << "- during DTLS handshake with" - << senderHifiSockAddr; - } - } - } else { - // first we verify the cookie - // see http://gnutls.org/manual/html_node/DTLS-sessions.html for why this is required - gnutls_dtls_prestate_st prestate; - memset(&prestate, 0, sizeof(prestate)); - int cookieValid = gnutls_dtls_cookie_verify(_cookieKey, &senderSockAddr, sizeof(senderSockAddr), - peekDatagram.data(), peekDatagram.size(), &prestate); - - if (cookieValid < 0) { - // the cookie sent by the client was not valid - // send a valid one - DummyDTLSSession tempServerSession(LimitedNodeList::getInstance()->getDTLSSocket(), senderHifiSockAddr); - - gnutls_dtls_cookie_send(_cookieKey, &senderSockAddr, sizeof(senderSockAddr), &prestate, - &tempServerSession, DTLSSession::socketPush); - - // acutally pull the peeked data off the network stack so that it gets discarded - dtlsSocket.readDatagram(peekDatagram.data(), peekDatagram.size()); - } else { - // cookie valid but no existing session - set up a new session now - DTLSServerSession* newServerSession = new DTLSServerSession(LimitedNodeList::getInstance()->getDTLSSocket(), - senderHifiSockAddr); - gnutls_session_t* gnutlsSession = newServerSession->getGnuTLSSession(); - - gnutls_priority_set(*gnutlsSession, *_priorityCache); - gnutls_credentials_set(*gnutlsSession, GNUTLS_CRD_CERTIFICATE, *_x509Credentials); - gnutls_dtls_prestate_set(*gnutlsSession, &prestate); - - // handshake to begin the session - gnutls_handshake(*gnutlsSession); - - qDebug() << "Beginning DTLS session with node at" << senderHifiSockAddr; - _dtlsSessions[senderHifiSockAddr] = newServerSession; - } - } - } -} - void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { LimitedNodeList* nodeList = LimitedNodeList::getInstance(); @@ -1210,14 +1061,6 @@ void DomainServer::nodeKilled(SharedNodePointer node) { reinterpret_cast(otherNode->getLinkedData())->getSessionSecretHash().remove(node->getUUID()); } } - - if (_isUsingDTLS) { - // check if we need to remove a DTLS session from our in-memory hash - DTLSServerSession* existingSession = _dtlsSessions.take(nodeData->getSendingSockAddr()); - if (existingSession) { - delete existingSession; - } - } } } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 4c0f9447ea..32d53281f1 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -26,15 +26,12 @@ #include #include -#include "DTLSServerSession.h" - typedef QSharedPointer SharedAssignmentPointer; class DomainServer : public QCoreApplication, public HTTPSRequestHandler { Q_OBJECT public: DomainServer(int argc, char* argv[]); - ~DomainServer(); bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url); bool handleHTTPSRequest(HTTPSConnection* connection, const QUrl& url); @@ -50,11 +47,9 @@ public slots: private slots: void readAvailableDatagrams(); - void readAvailableDTLSDatagrams(); private: void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid()); bool optionallySetupOAuth(); - bool optionallySetupDTLS(); bool optionallyReadX509KeyAndCertificate(); void processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); @@ -96,12 +91,6 @@ private: QVariantMap _argumentVariantMap; bool _isUsingDTLS; - gnutls_certificate_credentials_t* _x509Credentials; - gnutls_dh_params_t* _dhParams; - gnutls_datum_t* _cookieKey; - gnutls_priority_t* _priorityCache; - - QHash _dtlsSessions; QNetworkAccessManager* _networkAccessManager; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 487965b3ec..47ad9af638 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -173,10 +173,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _previousScriptLocation(), _runningScriptsWidget(new RunningScriptsWidget(_window)), _runningScriptsWidgetWasVisible(false) -{ - // init GnuTLS for DTLS with domain-servers - DTLSClientSession::globalInit(); - +{ // read the ApplicationInfo.ini file for Name/Version/Domain information QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat); @@ -431,8 +428,6 @@ Application::~Application() { delete _glWidget; AccountManager::getInstance().destroy(); - - DTLSClientSession::globalDeinit(); } void Application::saveSettings() { diff --git a/interface/src/ui/OAuthWebViewHandler.cpp b/interface/src/ui/OAuthWebViewHandler.cpp index 83d900cd5c..e93321212c 100644 --- a/interface/src/ui/OAuthWebViewHandler.cpp +++ b/interface/src/ui/OAuthWebViewHandler.cpp @@ -28,12 +28,35 @@ OAuthWebViewHandler::OAuthWebViewHandler() : } +const char HIGH_FIDELITY_CA[] = "-----BEGIN CERTIFICATE-----\n" + "MIID6TCCA1KgAwIBAgIJANlfRkRD9A8bMA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\n" + "VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j\n" + "aXNjbzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVy\n" + "YXRpb25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEW\n" + "E29wc0BoaWdoZmlkZWxpdHkuaW8wHhcNMTQwMzI4MjIzMzM1WhcNMjQwMzI1MjIz\n" + "MzM1WjCBqjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNV\n" + "BAcTDVNhbiBGcmFuY2lzY28xGzAZBgNVBAoTEkhpZ2ggRmlkZWxpdHksIEluYzET\n" + "MBEGA1UECxMKT3BlcmF0aW9uczEYMBYGA1UEAxMPaGlnaGZpZGVsaXR5LmlvMSIw\n" + "IAYJKoZIhvcNAQkBFhNvcHNAaGlnaGZpZGVsaXR5LmlvMIGfMA0GCSqGSIb3DQEB\n" + "AQUAA4GNADCBiQKBgQDyo1euYiPPEdnvDZnIjWrrP230qUKMSj8SWoIkbTJF2hE8\n" + "2eP3YOgbgSGBzZ8EJBxIOuNmj9g9Eg6691hIKFqy5W0BXO38P04Gg+pVBvpHFGBi\n" + "wpqGbfsjaUDuYmBeJRcMO0XYkLCRQG+lAQNHoFDdItWAJfC3FwtP3OCDnz8cNwID\n" + "AQABo4IBEzCCAQ8wHQYDVR0OBBYEFCSv2kmiGg6VFMnxXzLDNP304cPAMIHfBgNV\n" + "HSMEgdcwgdSAFCSv2kmiGg6VFMnxXzLDNP304cPAoYGwpIGtMIGqMQswCQYDVQQG\n" + "EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj\n" + "bzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVyYXRp\n" + "b25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEWE29w\n" + "c0BoaWdoZmlkZWxpdHkuaW+CCQDZX0ZEQ/QPGzAMBgNVHRMEBTADAQH/MA0GCSqG\n" + "SIb3DQEBBQUAA4GBAEkQl3p+lH5vuoCNgyfa67nL0MsBEt+5RSBOgjwCjjASjzou\n" + "FTv5w0he2OypgMQb8i/BYtS1lJSFqjPJcSM1Salzrm3xDOK5pOXJ7h6SQLPDVEyf\n" + "Hy2/9d/to+99+SOUlvfzfgycgjOc+s/AV7Y+GBd7uzGxUdrN4egCZW1F6/mH\n" + "-----END CERTIFICATE-----\n"; + void OAuthWebViewHandler::addHighFidelityRootCAToSSLConfig() { QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration(); // add the High Fidelity root CA to the list of trusted CA certificates - QByteArray highFidelityCACertificate(reinterpret_cast(DTLSSession::highFidelityCADatum()->data), - DTLSSession::highFidelityCADatum()->size); + QByteArray highFidelityCACertificate(HIGH_FIDELITY_CA, sizeof(HIGH_FIDELITY_CA)); sslConfig.setCaCertificates(sslConfig.caCertificates() + QSslCertificate::fromData(highFidelityCACertificate)); // set the modified configuration diff --git a/libraries/networking/src/DTLSClientSession.cpp b/libraries/networking/src/DTLSClientSession.cpp deleted file mode 100644 index 72384fbd10..0000000000 --- a/libraries/networking/src/DTLSClientSession.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// -// DTLSClientSession.cpp -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 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 "DomainHandler.h" - -#include "DTLSClientSession.h" - -gnutls_certificate_credentials_t DTLSClientSession::_x509CACredentials; - -void DTLSClientSession::globalInit() { - static bool initialized = false; - - if (!initialized) { - gnutls_global_init(); - gnutls_certificate_allocate_credentials(&_x509CACredentials); - - gnutls_certificate_set_x509_trust_mem(_x509CACredentials, DTLSSession::highFidelityCADatum(), GNUTLS_X509_FMT_PEM); - gnutls_certificate_set_verify_function(_x509CACredentials, DTLSClientSession::verifyServerCertificate); - } -} - -void DTLSClientSession::globalDeinit() { - gnutls_certificate_free_credentials(_x509CACredentials); - - gnutls_global_deinit(); -} - -int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { - unsigned int verifyStatus = 0; - - // 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; - } - - gnutls_certificate_type_t typeReturn = gnutls_certificate_type_get(session); - - gnutls_datum_t printOut; - - certReturn = gnutls_certificate_verification_status_print(verifyStatus, typeReturn, &printOut, 0); - - if (certReturn < 0) { - return GNUTLS_E_CERTIFICATE_ERROR; - } - - qDebug() << "Gnutls certificate verification status:" << reinterpret_cast(printOut.data); - -#ifdef WIN32 - free(printOut.data); -#else - gnutls_free(printOut.data); -#endif - - if (verifyStatus != 0) { - qDebug() << "Server provided certificate for DTLS is not trusted. Can not complete handshake."; - return GNUTLS_E_CERTIFICATE_ERROR; - } else { - // certificate is valid, continue handshaking as normal - return 0; - } -} - -DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : - DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) -{ - gnutls_priority_set_direct(_gnutlsSession, "PERFORMANCE", NULL); - gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, _x509CACredentials); -} \ No newline at end of file diff --git a/libraries/networking/src/DTLSClientSession.h b/libraries/networking/src/DTLSClientSession.h deleted file mode 100644 index eeca1aaa68..0000000000 --- a/libraries/networking/src/DTLSClientSession.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// DTLSClientSession.h -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 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_DTLSClientSession_h -#define hifi_DTLSClientSession_h - -#include "DTLSSession.h" - -class DTLSClientSession : public DTLSSession { -public: - DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); - - static void globalInit(); - static void globalDeinit(); - - static int verifyServerCertificate(gnutls_session_t session); - - static gnutls_certificate_credentials_t _x509CACredentials; - static bool _wasGloballyInitialized; -}; - -#endif // hifi_DTLSClientSession_h diff --git a/libraries/networking/src/DTLSSession.cpp b/libraries/networking/src/DTLSSession.cpp deleted file mode 100644 index f0649e4fc8..0000000000 --- a/libraries/networking/src/DTLSSession.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// DTLSSession.cpp -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 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 - -#include "NodeList.h" -#include "DTLSSession.h" - -int DTLSSession::socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { - DTLSSession* session = static_cast(ptr); - QUdpSocket& dtlsSocket = session->_dtlsSocket; - - if (dtlsSocket.hasPendingDatagrams()) { - // peek the data on stack to see if it belongs to this session - static sockaddr senderSockAddr; - static socklen_t sockAddrSize = sizeof(senderSockAddr); - - QByteArray peekDatagram(dtlsSocket.pendingDatagramSize(), 0); - - recvfrom(dtlsSocket.socketDescriptor(), peekDatagram.data(), dtlsSocket.pendingDatagramSize(), - MSG_PEEK, &senderSockAddr, &sockAddrSize); - - if (HifiSockAddr(&senderSockAddr) == session->_destinationSocket) { - // there is data for this session ready to be read - return 1; - } else { - // the next data from the dtlsSocket is not for this session - return 0; - } - } else { - // no data available on the dtlsSocket - return 0; - } -} - -ssize_t DTLSSession::socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size) { - DTLSSession* session = static_cast(ptr); - QUdpSocket& dtlsSocket = session->_dtlsSocket; - - HifiSockAddr pulledSockAddr; - qint64 bytesReceived = dtlsSocket.readDatagram(reinterpret_cast(buffer), size, - pulledSockAddr.getAddressPointer(), pulledSockAddr.getPortPointer()); - if (bytesReceived == -1) { - // no data to pull, return -1 -#if DTLS_VERBOSE_DEBUG - qDebug() << "Received no data on call to readDatagram"; -#endif - return bytesReceived; - } - - if (pulledSockAddr == session->_destinationSocket) { - // bytes received from the correct sender, return number of bytes received - -#if DTLS_VERBOSE_DEBUG - qDebug() << "Received" << bytesReceived << "on DTLS socket from" << pulledSockAddr; -#endif - - return bytesReceived; - } - - // we pulled a packet not matching this session, so output that - qDebug() << "Denied connection from" << pulledSockAddr; - - gnutls_transport_set_errno(session->_gnutlsSession, GNUTLS_E_AGAIN); - return -1; -} - -gnutls_datum_t* DTLSSession::highFidelityCADatum() { - static gnutls_datum_t hifiCADatum; - static bool datumInitialized = false; - - static unsigned char HIGHFIDELITY_ROOT_CA_CERT[] = - "-----BEGIN CERTIFICATE-----\n" - "MIID6TCCA1KgAwIBAgIJANlfRkRD9A8bMA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\n" - "VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j\n" - "aXNjbzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVy\n" - "YXRpb25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEW\n" - "E29wc0BoaWdoZmlkZWxpdHkuaW8wHhcNMTQwMzI4MjIzMzM1WhcNMjQwMzI1MjIz\n" - "MzM1WjCBqjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNV\n" - "BAcTDVNhbiBGcmFuY2lzY28xGzAZBgNVBAoTEkhpZ2ggRmlkZWxpdHksIEluYzET\n" - "MBEGA1UECxMKT3BlcmF0aW9uczEYMBYGA1UEAxMPaGlnaGZpZGVsaXR5LmlvMSIw\n" - "IAYJKoZIhvcNAQkBFhNvcHNAaGlnaGZpZGVsaXR5LmlvMIGfMA0GCSqGSIb3DQEB\n" - "AQUAA4GNADCBiQKBgQDyo1euYiPPEdnvDZnIjWrrP230qUKMSj8SWoIkbTJF2hE8\n" - "2eP3YOgbgSGBzZ8EJBxIOuNmj9g9Eg6691hIKFqy5W0BXO38P04Gg+pVBvpHFGBi\n" - "wpqGbfsjaUDuYmBeJRcMO0XYkLCRQG+lAQNHoFDdItWAJfC3FwtP3OCDnz8cNwID\n" - "AQABo4IBEzCCAQ8wHQYDVR0OBBYEFCSv2kmiGg6VFMnxXzLDNP304cPAMIHfBgNV\n" - "HSMEgdcwgdSAFCSv2kmiGg6VFMnxXzLDNP304cPAoYGwpIGtMIGqMQswCQYDVQQG\n" - "EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj\n" - "bzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVyYXRp\n" - "b25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEWE29w\n" - "c0BoaWdoZmlkZWxpdHkuaW+CCQDZX0ZEQ/QPGzAMBgNVHRMEBTADAQH/MA0GCSqG\n" - "SIb3DQEBBQUAA4GBAEkQl3p+lH5vuoCNgyfa67nL0MsBEt+5RSBOgjwCjjASjzou\n" - "FTv5w0he2OypgMQb8i/BYtS1lJSFqjPJcSM1Salzrm3xDOK5pOXJ7h6SQLPDVEyf\n" - "Hy2/9d/to+99+SOUlvfzfgycgjOc+s/AV7Y+GBd7uzGxUdrN4egCZW1F6/mH\n" - "-----END CERTIFICATE-----\n"; - - if (!datumInitialized) { - hifiCADatum.data = HIGHFIDELITY_ROOT_CA_CERT; - hifiCADatum.size = sizeof(HIGHFIDELITY_ROOT_CA_CERT); - } - - return &hifiCADatum; -} - -DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : - DummyDTLSSession(dtlsSocket, destinationSocket), - _completedHandshake(false) -{ - gnutls_init(&_gnutlsSession, end | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK); - - // see http://gnutls.org/manual/html_node/Datagram-TLS-API.html#gnutls_005fdtls_005fset_005fmtu - const unsigned int DTLS_MAX_MTU = 1452; - gnutls_dtls_set_mtu(_gnutlsSession, DTLS_MAX_MTU); - - const unsigned int DTLS_HANDSHAKE_RETRANSMISSION_TIMEOUT = DOMAIN_SERVER_CHECK_IN_MSECS; - const unsigned int DTLS_TOTAL_CONNECTION_TIMEOUT = 2 * NODE_SILENCE_THRESHOLD_MSECS; - gnutls_dtls_set_timeouts(_gnutlsSession, DTLS_HANDSHAKE_RETRANSMISSION_TIMEOUT, DTLS_TOTAL_CONNECTION_TIMEOUT); - - gnutls_transport_set_ptr(_gnutlsSession, this); - gnutls_transport_set_push_function(_gnutlsSession, DummyDTLSSession::socketPush); - gnutls_transport_set_pull_function(_gnutlsSession, socketPull); - gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); -} - -DTLSSession::~DTLSSession() { - gnutls_deinit(_gnutlsSession); -} - -void DTLSSession::setCompletedHandshake(bool completedHandshake) { - _completedHandshake = completedHandshake; - qDebug() << "Completed DTLS handshake with" << _destinationSocket; -} - -qint64 DTLSSession::writeDatagram(const QByteArray& datagram) { - // we don't need to put a hash in this packet, so just send it off - return gnutls_record_send(_gnutlsSession, datagram.data(), datagram.size()); -} \ No newline at end of file diff --git a/libraries/networking/src/DTLSSession.h b/libraries/networking/src/DTLSSession.h deleted file mode 100644 index 9e9542e147..0000000000 --- a/libraries/networking/src/DTLSSession.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// DTLSSession.h -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 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_DTLSSession_h -#define hifi_DTLSSession_h - -#include - -#include - -#include "DummyDTLSSession.h" -#include "HifiSockAddr.h" - -class DTLSSession : public DummyDTLSSession { - Q_OBJECT -public: - DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); - ~DTLSSession(); - - static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); - static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); - - static gnutls_datum_t* highFidelityCADatum(); - - qint64 writeDatagram(const QByteArray& datagram); - - gnutls_session_t* getGnuTLSSession() { return &_gnutlsSession; } - - bool completedHandshake() const { return _completedHandshake; } - void setCompletedHandshake(bool completedHandshake); -protected: - gnutls_session_t _gnutlsSession; - bool _completedHandshake; -}; - -#endif // hifi_DTLSSession_h diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 6c2fb0274a..859af50070 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -22,16 +22,11 @@ DomainHandler::DomainHandler(QObject* parent) : _sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _assignmentUUID(), _isConnected(false), - _dtlsSession(NULL), _handshakeTimer(NULL) { } -DomainHandler::~DomainHandler() { - delete _dtlsSession; -} - void DomainHandler::clearConnectionInfo() { _uuid = QUuid(); _isConnected = false; @@ -41,38 +36,12 @@ void DomainHandler::clearConnectionInfo() { delete _handshakeTimer; _handshakeTimer = NULL; } - - delete _dtlsSession; - _dtlsSession = NULL; } void DomainHandler::reset() { clearConnectionInfo(); _hostname = QString(); _sockAddr.setAddress(QHostAddress::Null); - - delete _dtlsSession; - _dtlsSession = NULL; -} - -const unsigned int DTLS_HANDSHAKE_INTERVAL_MSECS = 100; - -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); - - // start the handshake right now - completeDTLSHandshake(); - - // start the timer to finish off the handshake - _handshakeTimer->start(DTLS_HANDSHAKE_INTERVAL_MSECS); - } } void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname) { @@ -120,30 +89,6 @@ void DomainHandler::setHostname(const QString& hostname) { } } -void DomainHandler::completeDTLSHandshake() { - int handshakeReturn = gnutls_handshake(*_dtlsSession->getGnuTLSSession()); - - if (handshakeReturn == 0) { - // we've shaken hands, so we're good to go now - _dtlsSession->setCompletedHandshake(true); - - _handshakeTimer->stop(); - delete _handshakeTimer; - _handshakeTimer = NULL; - - // emit a signal so NodeList can handle incoming DTLS packets - emit completedDTLSHandshake(); - - } else if (gnutls_error_is_fatal(handshakeReturn)) { - // this was a fatal error handshaking, so remove this session - qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) - << "- during DTLS handshake with DS at" - << qPrintable((_hostname.isEmpty() ? _sockAddr.getAddress().toString() : _hostname)); - - clearConnectionInfo(); - } -} - void DomainHandler::completedHostnameLookup(const QHostInfo& hostInfo) { for (int i = 0; i < hostInfo.addresses().size(); i++) { if (hostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) { @@ -179,5 +124,5 @@ void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirement _sockAddr.setPort(dtlsPort); - initializeDTLSSession(); +// initializeDTLSSession(); } \ No newline at end of file diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 599f6d4a0f..782332f06a 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -18,7 +18,6 @@ #include #include -#include "DTLSClientSession.h" #include "HifiSockAddr.h" const QString DEFAULT_DOMAIN_HOSTNAME = "sandbox.highfidelity.io"; @@ -32,7 +31,6 @@ class DomainHandler : public QObject { Q_OBJECT public: DomainHandler(QObject* parent = 0); - ~DomainHandler(); void clearConnectionInfo(); @@ -56,29 +54,22 @@ public: bool isConnected() const { return _isConnected; } void setIsConnected(bool isConnected); - DTLSClientSession* getDTLSSession() { return _dtlsSession; } - void parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket); private slots: - void completeDTLSHandshake(); void completedHostnameLookup(const QHostInfo& hostInfo); signals: void hostnameChanged(const QString& hostname); void connectedToDomain(const QString& hostname); - void completedDTLSHandshake(); - void DTLSConnectionLost(); private: void reset(); - void initializeDTLSSession(); QUuid _uuid; QString _hostname; HifiSockAddr _sockAddr; QUuid _assignmentUUID; bool _isConnected; - DTLSClientSession* _dtlsSession; QTimer* _handshakeTimer; }; diff --git a/libraries/networking/src/DummyDTLSSession.cpp b/libraries/networking/src/DummyDTLSSession.cpp deleted file mode 100644 index a42e3f1599..0000000000 --- a/libraries/networking/src/DummyDTLSSession.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -// DummyDTLSSession.cpp -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-04. -// Copyright 2014 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 "DummyDTLSSession.h" - -ssize_t DummyDTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size) { - DummyDTLSSession* session = static_cast(ptr); - QUdpSocket& dtlsSocket = session->_dtlsSocket; - -#if DTLS_VERBOSE_DEBUG - qDebug() << "Pushing a message of size" << size << "to" << session->_destinationSocket; -#endif - - return dtlsSocket.writeDatagram(reinterpret_cast(buffer), size, - session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); -} - -DummyDTLSSession::DummyDTLSSession(QUdpSocket& dtlsSocket, const HifiSockAddr& destinationSocket) : - _dtlsSocket(dtlsSocket), - _destinationSocket(destinationSocket) -{ - -} \ No newline at end of file diff --git a/libraries/networking/src/DummyDTLSSession.h b/libraries/networking/src/DummyDTLSSession.h deleted file mode 100644 index 352b2c23e2..0000000000 --- a/libraries/networking/src/DummyDTLSSession.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// DummyDTLSSession.h -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-04. -// Copyright 2014 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_DummyDTLSSession_h -#define hifi_DummyDTLSSession_h - -#include - -#include - -#include "HifiSockAddr.h" - -#define DTLS_VERBOSE_DEBUG 0 - -class DummyDTLSSession : public QObject { - Q_OBJECT -public: - DummyDTLSSession(QUdpSocket& dtlsSocket, const HifiSockAddr& destinationSocket); - - static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); -protected: - QUdpSocket& _dtlsSocket; - HifiSockAddr _destinationSocket; -}; - -#endif // hifi_DummyDTLSSession_h diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index e3d113a1b5..eea9845f16 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -68,9 +68,6 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned // clear our NodeList when logout is requested connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset); - - // perform a function when DTLS handshake is completed - connect(&_domainHandler, &DomainHandler::completedDTLSHandshake, this, &NodeList::completedDTLSHandshake); } qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { @@ -117,30 +114,6 @@ void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& } } -void NodeList::completedDTLSHandshake() { - // at this point, we've got a DTLS socket - // make this NodeList the handler of DTLS packets - connect(_dtlsSocket, &QUdpSocket::readyRead, this, &NodeList::processAvailableDTLSDatagrams); -} - -void NodeList::processAvailableDTLSDatagrams() { - while (_dtlsSocket->hasPendingDatagrams()) { - QByteArray dtlsPacket(_dtlsSocket->pendingDatagramSize(), 0); - - // pull the data from this user off the stack and process it - int receivedBytes = gnutls_record_recv(*_domainHandler.getDTLSSession()->getGnuTLSSession(), - dtlsPacket.data(), dtlsPacket.size()); - if (receivedBytes > 0) { - // successful data receive, hand this off to processNodeData - processNodeData(_domainHandler.getSockAddr(), dtlsPacket.left(receivedBytes)); - } else if (gnutls_error_is_fatal(receivedBytes)) { - qDebug() << "Fatal error -" << gnutls_strerror(receivedBytes) << "- receiving DTLS packet from domain-server."; - } else { - qDebug() << "non fatal receive" << receivedBytes; - } - } -} - void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) { switch (packetTypeForPacket(packet)) { case PacketTypeDomainList: { @@ -365,19 +338,9 @@ void NodeList::sendDomainServerCheckIn() { // send a STUN request to figure it out sendSTUNRequest(); } else if (!_domainHandler.getIP().isNull()) { - - DTLSClientSession* dtlsSession = _domainHandler.getDTLSSession(); + bool isUsingDTLS = false; - if (dtlsSession) { - if (!dtlsSession->completedHandshake()) { - // if the handshake process is not complete then we can't check in, so return - return; - } else { - isUsingDTLS = true; - } - } - PacketType domainPacketType = !_domainHandler.isConnected() ? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest; @@ -405,8 +368,6 @@ void NodeList::sendDomainServerCheckIn() { if (!isUsingDTLS) { writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid()); - } else { - dtlsSession->writeDatagram(domainServerPacket); } const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index c55f08e7f0..c1d5189c6d 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -83,8 +83,6 @@ public slots: void reset(); void sendDomainServerCheckIn(); void pingInactiveNodes(); - void completedDTLSHandshake(); - void processAvailableDTLSDatagrams(); signals: void limitOfSilentDomainCheckInsReached(); private: