From efc58872e16313ca4fe40ed964827614617511fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 15 Aug 2018 19:18:11 +0200 Subject: [PATCH] Fix tripple connect and add test for it --- .../authentication/authenticationprocess.cpp | 4 +- libnymea-remoteproxy/proxyserver.cpp | 5 +- server/main.cpp | 13 +-- .../nymea-remoteproxy-tests-offline.cpp | 80 +++++++++++++++++++ .../nymea-remoteproxy-tests-offline.h | 1 + 5 files changed, 95 insertions(+), 8 deletions(-) diff --git a/libnymea-remoteproxy/authentication/authenticationprocess.cpp b/libnymea-remoteproxy/authentication/authenticationprocess.cpp index 8a32ae1..b9707db 100644 --- a/libnymea-remoteproxy/authentication/authenticationprocess.cpp +++ b/libnymea-remoteproxy/authentication/authenticationprocess.cpp @@ -40,22 +40,22 @@ void AuthenticationProcess::startVerificationProcess() QVariantMap request; request.insert("token", m_token); + // Set environment QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("AWS_DEFAULT_REGION", "eu-west-1"); - if (m_dynamicCredentials) { qCDebug(dcAuthenticationProcess()) << "Using dynamic credentials" << m_awsAccessKeyId << m_awsSecretAccessKey << m_awsSessionToken; env.insert("AWS_ACCESS_KEY_ID", m_awsAccessKeyId); env.insert("AWS_SECRET_ACCESS_KEY", m_awsSecretAccessKey); env.insert("AWS_SESSION_TOKEN", m_awsSessionToken); } + m_process->setProcessEnvironment(env); // FIXME: check how to clean this up properly m_resultFileName = "/tmp/" + QUuid::createUuid().toString().remove("{").remove("}").remove("-") + ".json"; qCDebug(dcAuthentication()) << "Start authenticator process and store result in" << m_resultFileName; m_processTimer.start(); - m_process->setProcessEnvironment(env); m_process->start("aws", { "lambda", "invoke", "--function-name", "system-services-authorizer-dev-checkToken", "--invocation-type", "RequestResponse", diff --git a/libnymea-remoteproxy/proxyserver.cpp b/libnymea-remoteproxy/proxyserver.cpp index 3a33b91..891cee9 100644 --- a/libnymea-remoteproxy/proxyserver.cpp +++ b/libnymea-remoteproxy/proxyserver.cpp @@ -145,7 +145,7 @@ void ProxyServer::onClientDisconnected(const QUuid &clientId) if (m_tunnels.contains(proxyClient->token())) { // There is a tunnel connection for this client, remove the tunnel and disconnect also the other client ProxyClient *remoteClient = getRemoteClient(proxyClient); - m_tunnels.remove(remoteClient->token()); + m_tunnels.remove(proxyClient->token()); if (remoteClient) { remoteClient->interface()->killClientConnection(remoteClient->clientId(), "Tunnel client disconnected"); } @@ -212,6 +212,9 @@ void ProxyServer::onProxyClientAuthenticated() if (m_tunnels.contains(proxyClient->token())) { qCWarning(dcProxyServer()) << "There is already a tunnel connection for this token. A third client is not allowed."; + // Note: remove the authenticated token, so the current tunnel will not interrupted. + proxyClient->setToken(QString()); + proxyClient->setAuthenticated(false); proxyClient->interface()->killClientConnection(proxyClient->clientId(), "There is already an established tunnel with this token."); return; } diff --git a/server/main.cpp b/server/main.cpp index 5913c69..30fecae 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -95,13 +95,15 @@ int main(int argc, char *argv[]) s_loggingFilters.insert("Application", true); s_loggingFilters.insert("Engine", true); s_loggingFilters.insert("JsonRpc", true); - s_loggingFilters.insert("JsonRpcTraffic", false); s_loggingFilters.insert("WebSocketServer", true); - s_loggingFilters.insert("WebSocketServerTraffic", false); s_loggingFilters.insert("Authentication", true); - s_loggingFilters.insert("AuthenticationProcess", true); s_loggingFilters.insert("ProxyServer", true); + + // Only with verbose enabled + s_loggingFilters.insert("JsonRpcTraffic", false); s_loggingFilters.insert("ProxyServerTraffic", false); + s_loggingFilters.insert("AuthenticationProcess", false); + s_loggingFilters.insert("WebSocketServerTraffic", false); QString configFile = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/nymea/nymea-remoteproxy.conf"; @@ -140,9 +142,9 @@ int main(int argc, char *argv[]) // Create a default configuration ProxyConfiguration *configuration = new ProxyConfiguration(nullptr); - if (parser.isSet(configOption)) { + if (parser.isSet(configOption)) configFile = parser.value(configOption); - } + qCDebug(dcApplication()) << "Loading configuration file from" << configFile; if (!configuration->loadConfiguration(parser.value(configOption))) { qCCritical(dcApplication()) << "Invalid configuration file passed" << parser.value(configOption); @@ -152,6 +154,7 @@ int main(int argc, char *argv[]) if (parser.isSet(verboseOption)) { s_loggingFilters["JsonRpcTraffic"] = true; s_loggingFilters["ProxyServerTraffic"] = true; + s_loggingFilters["AuthenticationProcess"] = true; s_loggingFilters["WebSocketServerTraffic"] = true; } diff --git a/tests/test-offline/nymea-remoteproxy-tests-offline.cpp b/tests/test-offline/nymea-remoteproxy-tests-offline.cpp index 02a2e4c..4188ce3 100644 --- a/tests/test-offline/nymea-remoteproxy-tests-offline.cpp +++ b/tests/test-offline/nymea-remoteproxy-tests-offline.cpp @@ -334,6 +334,86 @@ void RemoteProxyOfflineTests::remoteConnection() stopServer(); } +void RemoteProxyOfflineTests::trippleConnection() +{ + // Start the server + startServer(); + + // Configure moch authenticator + m_mockAuthenticator->setTimeoutDuration(100); + m_mockAuthenticator->setExpectedAuthenticationError(); + + // Create two connection + RemoteProxyConnection *connectionOne = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", this); + connectionOne->setInsecureConnection(true); + + RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(QUuid::createUuid(), "Test client two", this); + connectionTwo->setInsecureConnection(true); + + RemoteProxyConnection *connectionThree = new RemoteProxyConnection(QUuid::createUuid(), "Token thief ^w^", this); + connectionThree->setInsecureConnection(true); + + // Connect one + QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); + QVERIFY(connectionOne->connectServer(QHostAddress::LocalHost, m_port)); + connectionOneReadySpy.wait(); + QVERIFY(connectionOneReadySpy.count() == 1); + QVERIFY(connectionOne->isConnected()); + + // Connect two + QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); + QVERIFY(connectionTwo->connectServer(QHostAddress::LocalHost, m_port)); + connectionTwoReadySpy.wait(); + QVERIFY(connectionTwoReadySpy.count() == 1); + QVERIFY(connectionTwo->isConnected()); + + // Connect two + QSignalSpy connectionThreeReadySpy(connectionThree, &RemoteProxyConnection::ready); + QVERIFY(connectionThree->connectServer(QHostAddress::LocalHost, m_port)); + connectionThreeReadySpy.wait(); + QVERIFY(connectionThreeReadySpy.count() == 1); + QVERIFY(connectionThree->isConnected()); + + + // Authenticate one + QSignalSpy connectionOneAuthenticatedSpy(connectionOne, &RemoteProxyConnection::authenticated); + QVERIFY(connectionOne->authenticate(m_testToken)); + connectionOneAuthenticatedSpy.wait(); + QVERIFY(connectionOneAuthenticatedSpy.count() == 1); + QVERIFY(connectionOne->isConnected()); + QVERIFY(connectionOne->isAuthenticated()); + QVERIFY(connectionOne->state() == RemoteProxyConnection::StateWaitTunnel); + + QSignalSpy remoteConnectionEstablishedOne(connectionOne, &RemoteProxyConnection::remoteConnectionEstablished); + + // Authenticate two + QSignalSpy remoteConnectionEstablishedTwo(connectionTwo, &RemoteProxyConnection::remoteConnectionEstablished); + QSignalSpy connectionTwoAuthenticatedSpy(connectionTwo, &RemoteProxyConnection::authenticated); + QVERIFY(connectionTwo->authenticate(m_testToken)); + connectionTwoAuthenticatedSpy.wait(); + QVERIFY(connectionTwoAuthenticatedSpy.count() == 1); + QVERIFY(connectionTwo->isConnected()); + QVERIFY(connectionTwo->isAuthenticated()); + + // Wait for both to be connected + remoteConnectionEstablishedOne.wait(500); + + // Now connect a third connection and make sure it gets disconnected + + // Authenticate three + QSignalSpy connectionThreeDisconnectSpy(connectionThree, &RemoteProxyConnection::disconnected); + QVERIFY(connectionThree->authenticate(m_testToken)); + connectionThreeDisconnectSpy.wait(); + + QVERIFY(connectionOneAuthenticatedSpy.count() == 1); + QVERIFY(!connectionThree->isConnected()); + QVERIFY(!connectionThree->isAuthenticated()); + QVERIFY(connectionThree->state() == RemoteProxyConnection::StateDisconnected); + + // Clean up + stopServer(); +} + void RemoteProxyOfflineTests::sslConfigurations() { // Start the server diff --git a/tests/test-offline/nymea-remoteproxy-tests-offline.h b/tests/test-offline/nymea-remoteproxy-tests-offline.h index b2a0c90..cd3914a 100644 --- a/tests/test-offline/nymea-remoteproxy-tests-offline.h +++ b/tests/test-offline/nymea-remoteproxy-tests-offline.h @@ -42,6 +42,7 @@ private slots: // Client lib void clientConnection(); void remoteConnection(); + void trippleConnection(); void sslConfigurations(); void timeout();