diff --git a/README.md b/README.md index 12b207e..95ccf12 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,7 @@ The nymea remote proxy server is the meeting point of nymea servers and nymea cl In order to build the proxy server you need to install the qt default package. - apt install qt5-default - + apt install qtbase5-dev qtbase5-dev-tools libqt5websockets5-dev libncurses5-dev dpkg-dev debhelper ## Build from source Change into the source directory and run following commands @@ -27,18 +26,12 @@ If you want to start the proxy server from the build directory, you need to expo $ ./server/nymea-remoteproxy -c ../nymea-remoteproxy/nymea-remoteproxy.conf -## Build debian package - - $ apt install crossbuilder - $ cd nymea-remoteproxy - $ crossbuilder - # Install ## From repository There is a public version available in the nymea repository. - $ apt install nymea-remoteproxy nymea-remoteproxy-client nymea-remoteproxy-monitor + $ apt install nymea-remoteproxy nymea-remoteproxy-tunnelclient nymea-remoteproxy-monitor This will install a systemd service called `nymea-remoteproxy.service` and the client application for testing. @@ -51,7 +44,7 @@ Simply run following command in the build dir: # Configure The package will deliver a default configuration file with following content (`/etc/nymea/nymea-remoteproxy.conf`): - + [ProxyServer] name=nymea-remoteproxy writeLogs=false @@ -59,357 +52,37 @@ The package will deliver a default configuration file with following content (`/ logEngineEnabled=false monitorSocket=/tmp/nymea-remoteproxy-monitor.sock jsonRpcTimeout=10000 - authenticationTimeout=8000 inactiveTimeout=8000 - aloneTimeout=8000 - - [AWS] - region=eu-west-1 - authorizerLambdaFunction=system-services-authorizer-dev-checkToken - awsCredentialsUrl=http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2-Remote-Connection-Proxy-Role [SSL] + enabled=false certificate=/etc/ssl/certs/ssl-cert-snakeoil.pem certificateKey=/etc/ssl/private/ssl-cert-snakeoil.key certificateChain= - [WebSocketServer] - host=127.0.0.1 - port=443 + [UnixSocketServerTunnelProxy] + unixSocketFileName=/run/nymea-remoteproxy.socket - [TcpServer] + [WebSocketServerTunnelProxy] host=127.0.0.1 - port=80 - - -# Test - -In order to run the test, you can call `make check` in the build directory or run the resulting executable: - - $ nymea-remoteproxy-tests-offline - $ nymea-remoteproxy-tests-online - + port=2212 + + [TcpServerTunnelProxy] + host=127.0.0.1 + port=2213 + ## Test coverage report If you want to create a line coverage report from the tests simply run following command in the source directory: +> Note: run `qmake` with the argument `CONFIG+=converage` in order to generate coverage data for the tests. Then run the tests before creating the coverage report. + $ apt install lcov gcovr $ ./create-coverage-html.sh The resulting coverage report will be place in the `coverage-html` directory. -# Server usage - -In order to get information about the server you can start the command with the `--help` parameter. - - $ nymea-remoteproxy --help - - Usage: nymea-remoteproxy [options] - - The nymea remote proxy server. This server allowes nymea-cloud users and registered nymea deamons to establish a tunnel connection. - - Version: 0.1.5 - API version: 0.3 - - Copyright © 2018 Simon Stürz - - - Options: - -h, --help Displays this help. - -v, --version Displays version information. - -l, --logging Write log file to the given logfile. - -d, --development Enable the development mode. This - enabled the server assumes there are - static AWS credentials provided to - aws-cli. - -m, --mock-authenticator Start the server using a mock - authenticator which returns always true. - -c, --configuration The path to the proxy server - configuration file. The default is - ~/.config/nymea/nymea-remoteproxy.conf - --verbose Print more verbose. - - -# Proxy server API - -Once a client connects to the proxy server, he must authenticate him self by passing the token received from the nymea-cloud mqtt connection request. - -## Basic flow - -#### First client - -1. Connect to the proxy server -2. Say hello, in order to know the version, name and API version of the server -3. Authenticate with a token -4. Wait for the tunnel established notification - -#### Second client - -1. Connect to the proxy server -2. Say hello, in order to know the version, name and API version of the server -3. Authenticate with a token (this has to be the same token as the first client showed) -4. Wait for the tunnel established notification - - -Once both clients are authenticated, the proxy server will send the `RemoteProxy.TunnelEstablished` notification containing the information of the other tunnel participent. Any traffic coming from he socket is from the remote partner, and any messge sent to the socket will go to the remote partner. - -If anything goes wrong, or the tunnel partner disconnects from the proxy, the server will close the other client connection. If any data will be sent between `Authenticate` method and `TunnelEstablished` notification, the server will close the socket. - - - -## Message format - -#### Request - - { - "id": integer, - "method": "Namespace.Method", - "o:params" { } - } - -#### Response - - { - "id": integer, - "status": "string", - "o:params" { }, - "o:error": "string" - } - -#### Notification - - { - "id": integer, - "notification": "Namespace.Notification", - "o:params" { } - } - -## Say Hello - -#### Request - - { - "id": 0, - "method": "RemoteProxy.Hello" - } - - -#### Response - - { - "id": 0, - "params": { - "apiVersion": "0.2", - "name": "community-server", - "server": "nymea-remoteproxy", - "version": "0.1.2" - }, - "status": "success" - } - - -# Proxy server - -## Authenticate the connection - -The first data a client **must** send to the proxy server is the authentication request. This request contains the `token` which will be verified agains the nymea-cloud infrastructure and a `nonce` which has to be uniq for each connection attempt and shared between the 2 clients. The `uuid` should be a persistant uuid for this client and the name should make clear which type of connection this is and which client is connecting. The name and uuid will be sent to the tunnel partner during the tunnel establishmend. - -#### Request - - { - "id": 1, - "method": "Authentication.Authenticate", - "params": { - "uuid": "string", - "name": "string", - "token": "tokenstring" - "nonce": "nonce" - } - } - -#### Response - -* **On Success**: If the token was authenticated successfully, the response will look like this: - - { - "id": 1, - "status": "success" - } - -* **On Failure** If the token was invalid, the response will look like this and the server will close the connection immediatly: - - { - "id": 1, - "status": "error", - "error": "Invalid token. You are not allowed to use this server." - } - -#### Tunnel established - -Once the other client is here and ready, the server will send a notification to the clients indicating that the tunnel has been established successfully. This message is the last data comming from the proxy server. - -> **Important:** Any data traffic following after this notification comes from the tunnel endpoint, __not__ from the __proxy server__ any more. - - { - "id": "0", - "notification": "RemoteProxy.TunnelEstablished", - "params": { - "name": "String", - "uuid": "String" - } - } - - -## Introspect the API - - -#### Request - - { - "id": 0, - "method": "RemoteProxy.Introspect" - } - -#### Response - - { - "id": 1, - "params": { - "methods": { - "Authentication.Authenticate": { - "description": "Authenticate this connection. The returned AuthenticationError informs about the result. If the authentication was not successfull, the server will close the connection immediatly after sending the error response. The given id should be a unique id the other tunnel client can understand. Once the authentication was successfull, you can wait for the RemoteProxy.TunnelEstablished notification. If you send any data before getting this notification, the server will close the connection. If the tunnel client does not show up within 10 seconds, the server will close the connection.", - "params": { - "name": "String", - "o:nonce": "String", - "token": "String", - "uuid": "String" - }, - "returns": { - "authenticationError": "$ref:AuthenticationError" - } - }, - "RemoteProxy.Hello": { - "description": "Once connected to this server, a client can get information about the server by saying Hello. The response informs the client about this proxy server.", - "params": { - }, - "returns": { - "apiVersion": "String", - "name": "String", - "server": "String", - "version": "String" - } - }, - "RemoteProxy.Introspect": { - "description": "Introspect this API.", - "params": { - }, - "returns": { - "methods": "Object", - "notifications": "Object", - "types": "Object" - } - } - }, - "notifications": { - "RemoteProxy.TunnelEstablished": { - "description": "Emitted whenever the tunnel has been established successfully. This is the last message from the remote proxy server! Any following data will be from the other tunnel client until the connection will be closed. The parameter contain some information about the other tunnel client.", - "params": { - "name": "String", - "uuid": "String" - } - } - }, - "types": { - "AuthenticationError": [ - "AuthenticationErrorNoError", - "AuthenticationErrorUnknown", - "AuthenticationErrorTimeout", - "AuthenticationErrorAborted", - "AuthenticationErrorAuthenticationFailed", - "AuthenticationErrorProxyError" - ], - "BasicType": [ - "Uuid", - "String", - "Int", - "UInt", - "Double", - "Bool", - "Variant", - "Object" - ] - } - }, - "status": "success" - } - - -# Proxy server - - - -# Server monitor - -The server provides a live monitor interface on a local socket server. You can follow the monitor data with: - - $ sudo socat - UNIX-CONNECT:/tmp/nymea-remoteproxy-monitor.sock - -There is also the package `nymea-remoteproxy-monitor` package and application which gives you a nice overview about whats going on on the proxy server. - - - $ nymea-remoteproxy-monitor --help - - Usage: nymea-remoteproxy-monitor [options] - - The nymea remote proxy monitor allowes to monitor the live server activity on the a local instance. - - Server version: 0.1.5 - API version: 0.3 - - Copyright © 2018 Simon Stürz - - - Options: - -h, --help Displays this help. - -v, --version Displays version information. - -s, --socket The socket descriptor for the nymea-remoteproxy - monitor socket. Default is - /tmp/nymea-remoteproxy-monitor.sock - - - -# Client usage - -The client allowes you to test the proxy server and create a dummy client for testing the connection. - - - $ nymea-remoteproxy-client --help - - Usage: nymea-remoteproxy-client [options] - - The nymea remote proxy client application. This client allowes to test a server application as client perspective. - - Version: 0.1.5 - API version: 0.3 - - Copyright © 2018 Simon Stürz - - - Options: - -h, --help Displays this help. - -v, --version Displays version information. - -u, --url The proxy server url. Default - wss://dev-remoteproxy.nymea.io:443 - -t, --token The AWS token for authentication. - -i, --igore-ssl Ignore SSL certificate errors. - --name The name of the client. Default nymea-remoteproxyclient - --uuid The uuid of the client. If not specified, a new one will - be created - --verbose Print more information about the connection. - --very-verbose Print the complete traffic information from the - connection. - # Testing a local server With following steps you can test a local instance with a self signed certificate. @@ -419,7 +92,7 @@ With following steps you can test a local instance with a self signed certificat In order to test a connection and play with the server API, you can install the proxy server on your machine and try to connect to it. $ sudo apt update - $ sudo apt install nymea-remoteproxy nymea-remoteproxy-client + $ sudo apt install nymea-remoteproxy nymea-remoteproxy-tunnelclient Once installed, the `nymea-remoteproxy` will start automatically using the default configurations shipped in `/etc/nymea/nymea-remoteproxy.conf`. Using this file allowes you to configure the server for your test purposes. @@ -445,27 +118,10 @@ Change following configuration in the `/etc/nymea/nymea-remoteproxy.conf`: Now stop the proxy server and start it manually: - $ sudo systemctl stop nymea-remoteproxy.conf + $ sudo systemctl stop nymea-remoteproxy.service -> *Note*: the `-m` starts the proxy with a dummy authenticator, which allowes to use any token, it will always be authenticated and should be used only on localhost running servers. + $ sudo nymea-remoteproxy -c /etc/nymea/nymea-remoteproxy --verbose - $ sudo nymea-remoteproxy -c /etc/nymea/nymea-remoteproxy -m --verbose - -## Connect two clients - -Once the server is up and running with the dummy authenticator, you can try to connect to the service using the `nymea-remoteproxy-client` in a new terminal. - -> *Note:* assuming you are starting the client on the same system as the server: - - $ nymea-remoteproxy-client -i -u wss://localhost -t "blubtoken" - -Open a second terminal and start the same command again. - -> *Note:* assuming you are starting the client on the same system as the server: - - $ nymea-remoteproxy-client -i -u wss://localhost -t "blubtoken" - -You can follow the connection flow on both sides using the `--very-verbose` option. # License diff --git a/client/client.pro b/client/client.pro deleted file mode 100644 index 4af05f0..0000000 --- a/client/client.pro +++ /dev/null @@ -1,18 +0,0 @@ -include(../nymea-remoteproxy.pri) -include(../libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri) - -TARGET = nymea-remoteproxy-client -TEMPLATE = app - -INCLUDEPATH += ../libnymea-remoteproxy - -LIBS += -L$$top_builddir/libnymea-remoteproxyclient/ -lnymea-remoteproxyclient - -SOURCES += main.cpp \ - proxyclient.cpp - -target.path = $$[QT_INSTALL_PREFIX]/bin -INSTALLS += target - -HEADERS += \ - proxyclient.h diff --git a/client/main.cpp b/client/main.cpp deleted file mode 100644 index 5eb68e4..0000000 --- a/client/main.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include -#include -#include -#include -#include - -#include "proxyclient.h" -#include "../version.h" - -static QHash s_loggingFilters; -static const char *const normal = "\033[0m"; -static const char *const warning = "\e[33m"; -static const char *const error = "\e[31m"; - -static void loggingCategoryFilter(QLoggingCategory *category) -{ - if (s_loggingFilters.contains(category->categoryName())) { - bool debugEnabled = s_loggingFilters.value(category->categoryName()); - category->setEnabled(QtDebugMsg, debugEnabled); - category->setEnabled(QtWarningMsg, debugEnabled || s_loggingFilters.value("Warnings")); - } else { - // Enable default debug output - category->setEnabled(QtDebugMsg, true); - category->setEnabled(QtWarningMsg, s_loggingFilters.value("qml") || s_loggingFilters.value("Warnings")); - } -} - -static void consoleLogHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) -{ - switch (type) { - case QtInfoMsg: - fprintf(stdout, "%s: %s\n", context.category, message.toUtf8().data()); - break; - case QtDebugMsg: - fprintf(stdout, "%s: %s\n", context.category, message.toUtf8().data()); - break; - case QtWarningMsg: - fprintf(stdout, "%s%s: %s%s\n", warning, context.category, message.toUtf8().data(), normal); - break; - case QtCriticalMsg: - fprintf(stdout, "%s%s: %s%s\n", error, context.category, message.toUtf8().data(), normal); - break; - case QtFatalMsg: - fprintf(stdout, "%s%s: %s%s\n", error, context.category, message.toUtf8().data(), normal); - break; - } - fflush(stdout); -} - -int main(int argc, char *argv[]) -{ - qInstallMessageHandler(consoleLogHandler); - - QCoreApplication application(argc, argv); - application.setApplicationName(SERVER_NAME_STRING); - application.setOrganizationName("nymea"); - application.setApplicationVersion(SERVER_VERSION_STRING); - - // Default debug categories - s_loggingFilters.insert("ProxyClient", true); - s_loggingFilters.insert("RemoteProxyClientJsonRpc", false); - s_loggingFilters.insert("RemoteProxyClientWebSocket", false); - s_loggingFilters.insert("RemoteProxyClientConnection", false); - s_loggingFilters.insert("RemoteProxyClientJsonRpcTraffic", false); - s_loggingFilters.insert("RemoteProxyClientConnectionTraffic", false); - - QCommandLineParser parser; - parser.addHelpOption(); - parser.addVersionOption(); - parser.setApplicationDescription(QString("\nThe nymea remote proxy client application. This client allowes to test " - "a server application as client perspective.\n\n" - "Version: %1\n" - "API version: %2\n\n" - "Copyright %3 %4 nymea GmbH \n") - .arg(SERVER_VERSION_STRING) - .arg(API_VERSION_STRING) - .arg(QChar(0xA9)) - .arg(COPYRIGHT_YEAR_STRING)); - - QCommandLineOption urlOption(QStringList() << "u" << "url", "The proxy server url. Default ssl://dev-remoteproxy.nymea.io:4433", "url"); - urlOption.setDefaultValue("ssl://dev-remoteproxy.nymea.io:4433"); - parser.addOption(urlOption); - - QCommandLineOption tokenOption(QStringList() << "t" << "token", "The AWS token for authentication.", "token"); - parser.addOption(tokenOption); - - QCommandLineOption nonceOption(QStringList() << "n" << "nonce", "The shared connection unique nonce for this tunnel.", "nonce"); - parser.addOption(nonceOption); - - QCommandLineOption insecureOption(QStringList() << "i" << "ignore-ssl", "Ignore SSL certificate errors."); - parser.addOption(insecureOption); - - QCommandLineOption pingPongOption(QStringList() << "p" << "pingpong", "Start a ping pong traffic trough the remote connection."); - parser.addOption(pingPongOption); - - - QCommandLineOption nameOption(QStringList() << "name", "The name of the client. Default nymea-remoteproxyclient", "name"); - nameOption.setDefaultValue("nymea-remoteproxyclient"); - parser.addOption(nameOption); - - QCommandLineOption uuidOption(QStringList() << "uuid", "The uuid of the client. If not specified, a new one will be created", "uuid"); - parser.addOption(uuidOption); - - QCommandLineOption wsOption(QStringList() << "ws", "Use web socket as tronsport instead of TCP sockets."); - parser.addOption(wsOption); - - QCommandLineOption verboseOption(QStringList() << "verbose", "Print more information about the connection."); - parser.addOption(verboseOption); - - QCommandLineOption veryVerboseOption(QStringList() << "very-verbose", "Print the complete traffic information from the connection."); - parser.addOption(veryVerboseOption); - - parser.process(application); - - // Enable verbose - if (parser.isSet(verboseOption) || parser.isSet(veryVerboseOption)) { - s_loggingFilters["RemoteProxyClientJsonRpc"] = true; - s_loggingFilters["RemoteProxyClientWebSocket"] = true; - s_loggingFilters["RemoteProxyClientConnection"] = true; - } - - // Enable very verbose - if (parser.isSet(veryVerboseOption)) { - s_loggingFilters["RemoteProxyClientJsonRpcTraffic"] = true; - s_loggingFilters["RemoteProxyClientConnectionTraffic"] = true; - } - QLoggingCategory::installFilter(loggingCategoryFilter); - - if (!parser.isSet(tokenOption)) { - qCCritical(dcProxyClient()) << "Please specify the token for authentication using -t or --token ." << "\n" << "\n"; - parser.showHelp(-1); - } - - QUrl serverUrl(parser.value(urlOption)); - if (!serverUrl.isValid()) { - qCCritical(dcProxyClient()) << "Invalid proxy server url passed." << parser.value(urlOption); - exit(-1); - } - qCDebug(dcProxyClient()) << "Using URL" << serverUrl; - - QUuid uuid(parser.value(uuidOption)); - if (uuid.isNull()) { - uuid = QUuid::createUuid(); - } - - ProxyClient *client = nullptr; - if (parser.isSet(wsOption)) { - qCDebug(dcProxyClient()) << "Using web sockets as transport layer"; - client = new ProxyClient(parser.value(nameOption), uuid, RemoteProxyConnection::ConnectionTypeWebSocket); - client->setInsecure(parser.isSet(insecureOption)); - client->setPingpong(parser.isSet(pingPongOption)); - client->start(serverUrl, parser.value(tokenOption), parser.value(nonceOption)); - } else { - qCDebug(dcProxyClient()) << "Using TCP as transport layer"; - client = new ProxyClient(parser.value(nameOption), uuid, RemoteProxyConnection::ConnectionTypeTcpSocket); - client->setInsecure(parser.isSet(insecureOption)); - client->setPingpong(parser.isSet(pingPongOption)); - client->start(serverUrl, parser.value(tokenOption), parser.value(nonceOption)); - } - - return application.exec(); -} diff --git a/client/proxyclient.cpp b/client/proxyclient.cpp deleted file mode 100644 index ec5564c..0000000 --- a/client/proxyclient.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "proxyclient.h" - -#include - -Q_LOGGING_CATEGORY(dcProxyClient, "ProxyClient") - -ProxyClient::ProxyClient(const QString &name, const QUuid &uuid, RemoteProxyConnection::ConnectionType connectionType, QObject *parent) : - QObject(parent), - m_name(name), - m_uuid(uuid) -{ - m_connection = new RemoteProxyConnection(m_uuid, m_name, connectionType, this); - qCDebug(dcProxyClient()) << "Creating remote proxy connection" << m_name << m_uuid.toString(); - connect(m_connection, &RemoteProxyConnection::ready, this, &ProxyClient::onClientReady); - connect(m_connection, &RemoteProxyConnection::authenticated, this, &ProxyClient::onAuthenticationFinished); - connect(m_connection, &RemoteProxyConnection::remoteConnectionEstablished, this, &ProxyClient::onRemoteConnectionEstablished); - connect(m_connection, &RemoteProxyConnection::dataReady, this, &ProxyClient::onDataReady); - connect(m_connection, &RemoteProxyConnection::errorOccurred, this, &ProxyClient::onErrorOccurred); - connect(m_connection, &RemoteProxyConnection::disconnected, this, &ProxyClient::onClientDisconnected); - connect(m_connection, &RemoteProxyConnection::sslErrors, this, &ProxyClient::onSslErrors); -} - -void ProxyClient::setInsecure(bool insecure) -{ - m_insecure = insecure; -} - -void ProxyClient::setPingpong(bool enable) -{ - m_pingpong = enable; -} - -void ProxyClient::onErrorOccurred(QAbstractSocket::SocketError error) -{ - qCWarning(dcProxyClient()) << "Error occurred" << error; - exit(-1); -} - -void ProxyClient::onClientReady() -{ - qCDebug(dcProxyClient()) << "Connected to proxy server" << m_connection->serverUrl().toString(); - qCDebug(dcProxyClient()) << "Start authentication"; - m_connection->authenticate(m_token, m_nonce); -} - -void ProxyClient::onAuthenticationFinished() -{ - qCDebug(dcProxyClient()) << "Authentication finished successfully."; -} - -void ProxyClient::onRemoteConnectionEstablished() -{ - qCDebug(dcProxyClient()) << "----------------------------------------------------------------------------------"; - qCDebug(dcProxyClient()) << "Remote connection established with" << m_connection->tunnelPartnerName() << m_connection->tunnelPartnerUuid(); - qCDebug(dcProxyClient()) << "----------------------------------------------------------------------------------"; - if (m_pingpong) sendPing(); -} - -void ProxyClient::onDataReady(const QByteArray &data) -{ - qCDebug(dcProxyClient()) << "<--" << qUtf8Printable(data); - if (m_pingpong) { - QTimer::singleShot(1000, this, &ProxyClient::sendPing); - } -} - -void ProxyClient::onClientDisconnected() -{ - qCDebug(dcProxyClient()) << "Disconnected from" << m_connection->serverUrl().toString(); - exit(1); -} - -void ProxyClient::onSslErrors(const QList errors) -{ - if (m_insecure) { - qCDebug(dcProxyClient()) << "SSL errors occurred. Ignoring because explicit specified."; - m_connection->ignoreSslErrors(); - } else { - qCWarning(dcProxyClient()) << "SSL errors occurred:"; - foreach (const QSslError &sslError, errors) { - qCWarning(dcProxyClient()) << " --> " << sslError.errorString(); - } - } -} - -void ProxyClient::sendPing() -{ - QByteArray data(QString("Ping from " + m_name + "!").toUtf8()); - qCDebug(dcProxyClient()) << "-->" << qUtf8Printable(data); - m_connection->sendData(data); -} - -void ProxyClient::start(const QUrl &url, const QString &token, const QString &nonce) -{ - m_token = token; - m_nonce = nonce; - m_connection->connectServer(url); -} diff --git a/client/proxyclient.h b/client/proxyclient.h deleted file mode 100644 index ca2bdad..0000000 --- a/client/proxyclient.h +++ /dev/null @@ -1,75 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef PROXYCLIENT_H -#define PROXYCLIENT_H - -#include -#include - -#include "remoteproxyconnection.h" - -using namespace remoteproxyclient; - -Q_DECLARE_LOGGING_CATEGORY(dcProxyClient) - -class ProxyClient : public QObject -{ - Q_OBJECT -public: - explicit ProxyClient(const QString &name, const QUuid &uuid, RemoteProxyConnection::ConnectionType connectionType, QObject *parent = nullptr); - - void setInsecure(bool insecure); - void setPingpong(bool enable); - -private: - QString m_name; - QUuid m_uuid; - QString m_token; - QString m_nonce; - bool m_insecure = false; - bool m_pingpong = false; - - RemoteProxyConnection *m_connection = nullptr; - -private slots: - void onErrorOccurred(QAbstractSocket::SocketError error); - void onClientReady(); - void onAuthenticationFinished(); - void onRemoteConnectionEstablished(); - void onDataReady(const QByteArray &data); - void onClientDisconnected(); - void onSslErrors(const QList errors); - - void sendPing(); - -public slots: - void start(const QUrl &url, const QString &token, const QString &nonce); - -}; - -#endif // PROXYCLIENT_H diff --git a/debian/control b/debian/control index c71b20b..d0b9a10 100644 --- a/debian/control +++ b/debian/control @@ -20,7 +20,6 @@ Section: net Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends}, - awscli, libnymea-remoteproxy (= ${binary:Version}), Suggests: nymea-remoteproxy-monitor (= ${binary:Version}) Description: The nymea remote proxy server @@ -49,16 +48,6 @@ Description: The nymea remote proxy server lib - development files The nymea remote proxy server lib - development files -Package: nymea-remoteproxy-client -Architecture: any -Section: utils -Multi-Arch: same -Depends: ${shlibs:Depends}, - ${misc:Depends}, -Description: The nymea remote proxy client for testing - The nymea remote proxy client for testing - - Package: nymea-remoteproxy-tunnelclient Architecture: any Section: utils diff --git a/debian/copyright b/debian/copyright index b390f18..3249f09 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,7 +1,7 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: nymea-remoteproxy Upstream-Contact: Simon Stürz -Copyright: 2018 - 2022, nymea GmbH +Copyright: 2018 - 2023, nymea GmbH Download: http://www.github.com/nymea/nymea-remoteproxy Source: https://github.com/nymea/nymea-remoteproxy.git @@ -16,24 +16,20 @@ License: LGPL-3 Files: libnymea-remoteproxyclient/* License: LGPL-3 -Copyright: 2018 - 2022, nymea GmbH +Copyright: 2018 - 2023, nymea GmbH Files: libnymea-remoteproxy/* License: GPL-3 -Copyright: 2018 - 2022, nymea GmbH - -Files: client/* -License: GPL-3 -Copyright: 2018 - 2022, nymea GmbH +Copyright: 2018 - 2023, nymea GmbH Files: monitor/* License: GPL-3 -Copyright: 2018 - 2022, nymea GmbH +Copyright: 2018 - 2023, nymea GmbH Files: server/* License: GPL-3 -Copyright: 2018 - 2022, nymea GmbH +Copyright: 2018 - 2023, nymea GmbH Files: tests/* License: GPL-3 -Copyright: 2018 - 2022, nymea GmbH +Copyright: 2018 - 2023, nymea GmbH diff --git a/debian/nymea-remoteproxy-client.install.in b/debian/nymea-remoteproxy-client.install.in deleted file mode 100644 index ad9aba1..0000000 --- a/debian/nymea-remoteproxy-client.install.in +++ /dev/null @@ -1 +0,0 @@ -usr/bin/nymea-remoteproxy-client diff --git a/debian/nymea-remoteproxy-tests.install b/debian/nymea-remoteproxy-tests.install index bec587f..2ecea73 100644 --- a/debian/nymea-remoteproxy-tests.install +++ b/debian/nymea-remoteproxy-tests.install @@ -1,2 +1 @@ -usr/bin/nymea-remoteproxy-proxy-tests usr/bin/nymea-remoteproxy-tunnelproxy-tests diff --git a/generate-coverage.sh b/generate-coverage.sh index 9fd4ac4..e24442c 100755 --- a/generate-coverage.sh +++ b/generate-coverage.sh @@ -7,6 +7,6 @@ HTML_RESULTS="${COV_DIR}/html" # Build code coverage html report mkdir -p ${HTML_RESULTS} lcov -d "${SRC_DIR}" -c -o "${COV_DIR}/coverage.info" -lcov -r "${COV_DIR}/coverage.info" "*.h" "*/tests/*" "*.moc" "*moc_*.cpp" "*/test/*" "/usr/include/*" "*/build*/*" "*libnymea-remoteproxy/authentication/aws*" -o "${COV_DIR}/coverage-filtered.info" +lcov -r "${COV_DIR}/coverage.info" "*.h" "*/tests/*" "*.moc" "*moc_*.cpp" "*/test/*" "/usr/include/*" "*/build*/*" -o "${COV_DIR}/coverage-filtered.info" genhtml -o "${HTML_RESULTS}" "${COV_DIR}/coverage-filtered.info" lcov -d "${COV_DIR}" -z diff --git a/libnymea-remoteproxy/authentication/authenticationreply.cpp b/libnymea-remoteproxy/authentication/authenticationreply.cpp deleted file mode 100644 index bbbb7af..0000000 --- a/libnymea-remoteproxy/authentication/authenticationreply.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "engine.h" -#include "loggingcategories.h" -#include "authenticationreply.h" -#include "authentication/authenticator.h" - -namespace remoteproxy { - -AuthenticationReply::AuthenticationReply(ProxyClient *proxyClient, QObject *parent) : - QObject(parent) -{ - m_proxyClient = proxyClient; - - m_timer = new QTimer(this); - m_timer->setSingleShot(true); - connect(m_timer, &QTimer::timeout, this, &AuthenticationReply::onTimeout); - qCDebug(dcAuthentication) << "Created authentication reply for" << proxyClient << "Timeout:" << Engine::instance()->configuration()->authenticationTimeout() << "[ms]"; - m_timer->start(Engine::instance()->configuration()->authenticationTimeout()); -} - -AuthenticationReply::~AuthenticationReply() -{ - -} - -QPointer AuthenticationReply::proxyClient() const -{ - return m_proxyClient; -} - -bool AuthenticationReply::isTimedOut() const -{ - return m_timedOut; -} - -bool AuthenticationReply::isFinished() const -{ - return m_finished; -} - -Authenticator::AuthenticationError AuthenticationReply::error() const -{ - return m_error; -} - -void AuthenticationReply::setError(Authenticator::AuthenticationError error) -{ - m_error = error; -} - -void AuthenticationReply::setFinished() -{ - m_timer->stop(); - - // emit in next event loop - QTimer::singleShot(0, this, &AuthenticationReply::finished); -} - -void AuthenticationReply::onTimeout() -{ - m_timedOut = true; - m_error = Authenticator::AuthenticationErrorTimeout; - setFinished(); -} - -void AuthenticationReply::abort() -{ - m_error = Authenticator::AuthenticationErrorAborted; - setFinished(); -} - -} diff --git a/libnymea-remoteproxy/authentication/authenticationreply.h b/libnymea-remoteproxy/authentication/authenticationreply.h deleted file mode 100644 index cf4d82f..0000000 --- a/libnymea-remoteproxy/authentication/authenticationreply.h +++ /dev/null @@ -1,83 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef AUTHENTICATIONREPLY_H -#define AUTHENTICATIONREPLY_H - -#include -#include -#include -#include -#include -#include - -#include "authenticator.h" - -namespace remoteproxy { - -class AuthenticationReply : public QObject -{ - Q_OBJECT -public: - friend class Authenticator; - - QPointer proxyClient() const; - - bool isTimedOut() const; - bool isFinished() const; - - Authenticator::AuthenticationError error() const; - -private: - explicit AuthenticationReply(ProxyClient *proxyClient, QObject *parent = nullptr); - ~AuthenticationReply(); - - QPointer m_proxyClient; - QTimer *m_timer = nullptr; - - bool m_timedOut = false; - bool m_finished = false; - - Authenticator::AuthenticationError m_error = Authenticator::AuthenticationErrorUnknown; - - void setError(Authenticator::AuthenticationError error); - void setFinished(); - -signals: - void finished(); - -private slots: - void onTimeout(); - -public slots: - void abort(); - -}; - -} - -#endif // AUTHENTICATIONREPLY_H diff --git a/libnymea-remoteproxy/authentication/authenticator.cpp b/libnymea-remoteproxy/authentication/authenticator.cpp deleted file mode 100644 index b6b45e1..0000000 --- a/libnymea-remoteproxy/authentication/authenticator.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "proxy/proxyclient.h" -#include "authenticator.h" -#include "authenticationreply.h" - -namespace remoteproxy { - -Authenticator::Authenticator(QObject *parent) : - QObject(parent) -{ - -} - -Authenticator::~Authenticator() -{ - -} - -void Authenticator::setReplyError(AuthenticationReply *reply, Authenticator::AuthenticationError error) -{ - reply->setError(error); -} - -void Authenticator::setReplyFinished(AuthenticationReply *reply) -{ - reply->setFinished(); -} - -AuthenticationReply *Authenticator::createAuthenticationReply(ProxyClient *proxyClient, QObject *parent) -{ - return new AuthenticationReply(proxyClient, parent); -} - -} diff --git a/libnymea-remoteproxy/authentication/authenticator.h b/libnymea-remoteproxy/authentication/authenticator.h deleted file mode 100644 index 55c0c10..0000000 --- a/libnymea-remoteproxy/authentication/authenticator.h +++ /dev/null @@ -1,70 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef AUTHENTICATOR_H -#define AUTHENTICATOR_H - -#include -#include - -namespace remoteproxy { - -class ProxyClient; -class AuthenticationReply; - -class Authenticator : public QObject -{ - Q_OBJECT -public: - enum AuthenticationError { - AuthenticationErrorNoError, - AuthenticationErrorUnknown, - AuthenticationErrorTimeout, - AuthenticationErrorAborted, - AuthenticationErrorAuthenticationFailed, - AuthenticationErrorProxyError - }; - Q_ENUM(AuthenticationError) - - explicit Authenticator(QObject *parent = nullptr); - virtual ~Authenticator() = 0; - - virtual QString name() const = 0; - -public slots: - virtual AuthenticationReply *authenticate(ProxyClient *proxyClient) = 0; - -protected: - void setReplyError(AuthenticationReply *reply, AuthenticationError error); - void setReplyFinished(AuthenticationReply *reply); - - AuthenticationReply *createAuthenticationReply(ProxyClient *proxyClient, QObject *parent = nullptr); -}; - -} - -#endif // AUTHENTICATOR_H diff --git a/libnymea-remoteproxy/authentication/aws/authenticationprocess.cpp b/libnymea-remoteproxy/authentication/aws/authenticationprocess.cpp deleted file mode 100644 index d77a3d5..0000000 --- a/libnymea-remoteproxy/authentication/aws/authenticationprocess.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "authenticationprocess.h" -#include "loggingcategories.h" - -#include -#include -#include -#include - -#include "engine.h" -#include "sigv4utils.h" - -namespace remoteproxy { - -AuthenticationProcess::AuthenticationProcess(QNetworkAccessManager *manager, const QString &accessKey, const QString &secretAccessKey, const QString &sessionToken, QObject *parent) : - QObject(parent), - m_manager(manager), - m_accessKey(accessKey), - m_secretAccessKey(secretAccessKey), - m_sessionToken(sessionToken) -{ - m_process = new QProcess(this); - m_process->setProcessChannelMode(QProcess::MergedChannels); - connect(m_process, static_cast(&QProcess::finished), this, &AuthenticationProcess::onProcessFinished); -} - -void AuthenticationProcess::invokeLambdaFunction() -{ - // Known configurations - QString region = Engine::instance()->configuration()->awsRegion(); - QString lambdaFunctionName = Engine::instance()->configuration()->awsAuthorizerLambdaFunctionName(); - - QString invocationType = "RequestResponse"; - QString service = "lambda"; - - QUrl requestUrl; - requestUrl.setScheme("https"); - requestUrl.setHost(QString("lambda.%1.amazonaws.com").arg(region)); - requestUrl.setPath(QString("/2015-03-31/functions/%1/invocations").arg(lambdaFunctionName)); - - // Create request map - QVariantMap requestMap; - requestMap.insert("token", m_token); - QByteArray payload = QJsonDocument::fromVariant(requestMap).toJson(QJsonDocument::Compact); - - QNetworkRequest request(requestUrl); - //request.setRawHeader("User-Agent", QString("%1/%2 JSON-RPC/%3").arg(SERVER_NAME_STRING).arg(SERVER_VERSION_STRING).arg(API_VERSION_STRING).toUtf8()); - //request.setRawHeader("Content-Type", "application/json"); - request.setRawHeader("host", requestUrl.host().toUtf8()); - SigV4Utils::signRequest(QNetworkAccessManager::PostOperation, request, region, service, invocationType, m_accessKey.toUtf8(), m_secretAccessKey.toUtf8(), m_sessionToken.toUtf8(), payload); - - qCDebug(dcAuthenticationProcess()) << "Invoke lambda function" << lambdaFunctionName; - - qCDebug(dcAuthenticationProcess()) << "--------------------------------------------"; - qCDebug(dcAuthenticationProcess()) << request.url().toString(); - - foreach (const QByteArray &rawHeader, request.rawHeaderList()) { - qDebug(dcAuthenticationProcess()) << rawHeader << request.rawHeader(rawHeader); - } - qCDebug(dcAuthenticationProcess()) << payload; - qCDebug(dcAuthenticationProcess()) << "--------------------------------------------"; - - m_lambdaTimer.start(); - - QNetworkReply *reply = m_manager->post(request, payload); - connect(reply, &QNetworkReply::finished, this, &AuthenticationProcess::onLambdaInvokeFunctionFinished); - -} - -void AuthenticationProcess::startVerificationProcess() -{ - if (m_process->state() != QProcess::NotRunning) { - qCWarning(dcAuthenticationProcess()) << "Authentication process already running. Killing the running process and restart."; - m_process->kill(); - } - - // Create request map - QVariantMap request; - request.insert("token", m_token); - - // Set environment - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - env.insert("AWS_DEFAULT_REGION", "eu-west-1"); - if (m_fallback) { - qCDebug(dcAuthenticationProcess()) << "Using dynamic credentials" << m_accessKey << m_secretAccessKey << m_sessionToken; - env.insert("AWS_ACCESS_KEY_ID", m_accessKey); - env.insert("AWS_SECRET_ACCESS_KEY", m_secretAccessKey); - env.insert("AWS_SESSION_TOKEN", m_sessionToken); - } - - m_process->setProcessEnvironment(env); - - // FIXME: check how to clean this up properly - m_resultFileName = "/tmp/" + QUuid::createUuid().toString().remove("{").remove("}").remove("-") + ".json"; - - QStringList processParams = { "lambda", "invoke", - "--function-name", "system-services-authorizer-dev-checkToken", - "--invocation-type", "RequestResponse", - "--payload", QString::fromUtf8(QJsonDocument::fromVariant(request).toJson()), - m_resultFileName }; - - qCDebug(dcAuthenticationProcess()) << "Process environment" << env.toStringList(); - qCDebug(dcAuthenticationProcess()) << "Process params" << processParams; - - - qCDebug(dcAuthentication()) << "Start authenticator process and store result in" << m_resultFileName; - m_processTimer.start(); - m_process->start("aws", processParams); -} - -void AuthenticationProcess::onLambdaInvokeFunctionFinished() -{ - QNetworkReply *reply = static_cast(sender()); - reply->deleteLater(); - - qCDebug(dcAuthenticationProcess()) << "Lambda invoke request finished (" << m_lambdaTimer.elapsed() << "[ms] )"; - - QByteArray data = reply->readAll(); - - qCDebug(dcAuthenticationProcess()) << "--------------------------------------------"; - qCDebug(dcAuthenticationProcess()) << reply->request().url().toString(); - - foreach (const QByteArray &rawHeader, reply->rawHeaderList()) { - qDebug(dcAuthenticationProcess()) << rawHeader << reply->rawHeader(rawHeader); - } - qCDebug(dcAuthenticationProcess()) << qUtf8Printable(data); - qCDebug(dcAuthenticationProcess()) << "--------------------------------------------"; - - if (reply->error()) { - qCWarning(dcAuthenticationProcess()) << "Lambda invoke reply error: " << reply->errorString(); - m_fallback = true; - return; - } - - qCDebug(dcAuthenticationProcess()) << "Lambda function result ready" << qUtf8Printable(data); - - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); - if(error.error != QJsonParseError::NoError) { - qCWarning(dcAuthenticationProcess()) << "Failed to parse lambda invoke result data" << data << ":" << error.errorString(); - emit authenticationFinished(Authenticator::AuthenticationErrorProxyError); - return; - } - - QVariantMap response = jsonDoc.toVariant().toMap(); - qCDebug(dcAuthenticationProcess()) << "-->" << response; - if (response.isEmpty()) { - qCWarning(dcAuthenticationProcess()) << "Received empty lambda result."; - emit authenticationFinished(Authenticator::AuthenticationErrorProxyError); - return; - } - - bool isValid = response.value("isValid").toBool(); - if (isValid) { - QVariantMap verifiedDataMap = response.value("verifiedData").toMap(); - QString vendorId = verifiedDataMap.value("vendorId").toString(); - QString userPoolId = verifiedDataMap.value("userPoolId").toString(); - QVariantMap verifiedParsedTokenMap = verifiedDataMap.value("verifiedParsedToken").toMap(); - QString email = verifiedParsedTokenMap.value("email").toString(); - QString cognitoUsername = verifiedParsedTokenMap.value("cognito:username").toString(); - - UserInformation userInformation(email, cognitoUsername, vendorId, userPoolId); - - emit authenticationFinished(Authenticator::AuthenticationErrorNoError, userInformation); - } else { - emit authenticationFinished(Authenticator::AuthenticationErrorAuthenticationFailed); - } -} - -void AuthenticationProcess::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) -{ - qCDebug(dcAuthenticationProcess()) << "Authentication process finished (" << m_processTimer.elapsed() << "[ms] )";; - if (exitStatus == QProcess::CrashExit) { - qCWarning(dcAuthenticationProcess()) << "Authentication process crashed:" << "\n" << qUtf8Printable(m_process->readAll()); - emit authenticationFinished(Authenticator::AuthenticationErrorProxyError); - return; - } - - if (exitCode != 0) { - qCWarning(dcAuthenticationProcess()) << "The authentication process finished with error" << exitCode << "\n" << qUtf8Printable(m_process->readAll()); - emit authenticationFinished(Authenticator::AuthenticationErrorProxyError); - return; - } - - QFile resultFile(m_resultFileName); - if (!resultFile.exists()) { - qCWarning(dcAuthenticationProcess()) << "The process output file does not exist."; - emit authenticationFinished(Authenticator::AuthenticationErrorProxyError); - return; - } - - if (!resultFile.open(QIODevice::ReadWrite)) { - qCWarning(dcAuthenticationProcess()) << "Could not open result file from process:" << resultFile.errorString(); - emit authenticationFinished(Authenticator::AuthenticationErrorProxyError); - return; - } - - QByteArray resultData = resultFile.readAll(); - - qCDebug(dcAuthenticationProcess()) << "Lambda function result ready" << qUtf8Printable(resultData); - - resultFile.close(); - if (!resultFile.remove()) { - qCWarning(dcAuthenticationProcess()) << "Could not clean up result file from process:" << resultFile.errorString(); - return; - } - - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(resultData, &error); - if(error.error != QJsonParseError::NoError) { - qCWarning(dcAuthenticationProcess()) << "Failed to parse lambda invoke result data" << resultData << ":" << error.errorString(); - emit authenticationFinished(Authenticator::AuthenticationErrorProxyError); - return; - } - - QVariantMap response = jsonDoc.toVariant().toMap(); - qCDebug(dcAuthenticationProcess()) << "-->" << response; - if (response.isEmpty()) { - qCWarning(dcAuthenticationProcess()) << "Received empty lambda result."; - emit authenticationFinished(Authenticator::AuthenticationErrorProxyError); - return; - } - - bool isValid = response.value("isValid").toBool(); - if (isValid) { - QVariantMap verifiedDataMap = response.value("verifiedData").toMap(); - QString vendorId = verifiedDataMap.value("vendorId").toString(); - QString userPoolId = verifiedDataMap.value("userPoolId").toString(); - QVariantMap verifiedParsedTokenMap = verifiedDataMap.value("verifiedParsedToken").toMap(); - QString email = verifiedParsedTokenMap.value("email").toString(); - QString cognitoUsername = verifiedParsedTokenMap.value("cognito:username").toString(); - - UserInformation userInformation(email, cognitoUsername, vendorId, userPoolId); - - emit authenticationFinished(Authenticator::AuthenticationErrorNoError, userInformation); - } else { - emit authenticationFinished(Authenticator::AuthenticationErrorAuthenticationFailed); - } - -} - -void AuthenticationProcess::authenticate(const QString &token) -{ - qCDebug(dcAuthenticationProcess()) << "Start authentication process for token" << token; - m_token = token; - invokeLambdaFunction(); -} - -} diff --git a/libnymea-remoteproxy/authentication/aws/authenticationprocess.h b/libnymea-remoteproxy/authentication/aws/authenticationprocess.h deleted file mode 100644 index a8131ab..0000000 --- a/libnymea-remoteproxy/authentication/aws/authenticationprocess.h +++ /dev/null @@ -1,81 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef AUTHENTICATIONPROCESS_H -#define AUTHENTICATIONPROCESS_H - -#include -#include -#include -#include - -#include "userinformation.h" -#include "authentication/authenticator.h" - -namespace remoteproxy { - -class AuthenticationProcess : public QObject -{ - Q_OBJECT -public: - explicit AuthenticationProcess(QNetworkAccessManager *manager, const QString &accessKey, const QString &secretAccessKey, const QString &sessionToken, QObject *parent = nullptr); - -private: - QNetworkAccessManager *m_manager = nullptr; - QString m_accessKey; - QString m_secretAccessKey; - QString m_sessionToken; - - QString m_token; - QString m_resultFileName; - - bool m_fallback = false; - - QProcess *m_process = nullptr; - QElapsedTimer m_lambdaTimer; - QElapsedTimer m_processTimer; - - void invokeLambdaFunction(); - void startVerificationProcess(); - - void cleanUp(); - -signals: - void authenticationFinished(Authenticator::AuthenticationError error, const UserInformation &userInformation = UserInformation()); - -private slots: - void onLambdaInvokeFunctionFinished(); - void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); - -public slots: - void authenticate(const QString &token); - -}; - -} - -#endif // AUTHENTICATIONPROCESS_H diff --git a/libnymea-remoteproxy/authentication/aws/awsauthenticator.cpp b/libnymea-remoteproxy/authentication/aws/awsauthenticator.cpp deleted file mode 100644 index ead9bf9..0000000 --- a/libnymea-remoteproxy/authentication/aws/awsauthenticator.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "engine.h" -#include "proxy/proxyclient.h" -#include "awsauthenticator.h" -#include "loggingcategories.h" - -namespace remoteproxy { - -AwsAuthenticator::AwsAuthenticator(const QUrl &awsCredentialsUrl, QObject *parent) : - Authenticator(parent), - m_manager(new QNetworkAccessManager(this)) -{ - m_credentialsProvider = new AwsCredentialProvider(m_manager, awsCredentialsUrl, this); - QMetaObject::invokeMethod(m_credentialsProvider, QString("enable").toLatin1().data(), Qt::QueuedConnection); -} - -AwsAuthenticator::~AwsAuthenticator() -{ - qCDebug(dcAuthentication()) << "Shutting down" << name(); - m_credentialsProvider->disable(); -} - -QString AwsAuthenticator::name() const -{ - return "AWS authenticator"; -} - -AuthenticationReply *AwsAuthenticator::authenticate(ProxyClient *proxyClient) -{ - qCDebug(dcAuthentication()) << name() << "Start authenticating" << proxyClient; - AuthenticationReply *reply = createAuthenticationReply(proxyClient, proxyClient); - if (!m_credentialsProvider->isValid()) { - qCWarning(dcAuthentication()) << name() << "There are no credentials for authenticating."; - setReplyError(reply, AuthenticationErrorProxyError); - setReplyFinished(reply); - return reply; - } - - AuthenticationProcess *process = new AuthenticationProcess(m_manager, - m_credentialsProvider->accessKey(), - m_credentialsProvider->secretAccessKey(), - m_credentialsProvider->sessionToken(), reply); - - connect(process, &AuthenticationProcess::authenticationFinished, proxyClient, [=](Authenticator::AuthenticationError error, const UserInformation &userInformation = UserInformation()){ - if (error == AuthenticationErrorNoError) { - qCDebug(dcAuthentication()) << name() << proxyClient << "finished successfully." << userInformation; - } else { - qCDebug(dcAuthentication()) << name() << proxyClient << "finished with error" << error; - } - - proxyClient->setUserName(userInformation.email()); - - setReplyError(reply, error); - setReplyFinished(reply); - }); - - - // Start authentication process - process->authenticate(proxyClient->token()); - return reply; -} - -} diff --git a/libnymea-remoteproxy/authentication/aws/awsauthenticator.h b/libnymea-remoteproxy/authentication/aws/awsauthenticator.h deleted file mode 100644 index 587d34e..0000000 --- a/libnymea-remoteproxy/authentication/aws/awsauthenticator.h +++ /dev/null @@ -1,61 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef AWSAUTHENTICATOR_H -#define AWSAUTHENTICATOR_H - -#include -#include - -#include "awscredentialprovider.h" -#include "authenticationprocess.h" -#include "authentication/authenticator.h" -#include "authentication/authenticationreply.h" - -namespace remoteproxy { - -class AwsAuthenticator : public Authenticator -{ - Q_OBJECT -public: - explicit AwsAuthenticator(const QUrl &awsCredentialsUrl, QObject *parent = nullptr); - ~AwsAuthenticator() override; - - QString name() const override; - -private: - QNetworkAccessManager *m_manager = nullptr; - AwsCredentialProvider *m_credentialsProvider = nullptr; - -public slots: - AuthenticationReply *authenticate(ProxyClient *proxyClient) override; - -}; - -} - -#endif // AWSAUTHENTICATOR_H diff --git a/libnymea-remoteproxy/authentication/aws/awscredentialprovider.cpp b/libnymea-remoteproxy/authentication/aws/awscredentialprovider.cpp deleted file mode 100644 index ba73434..0000000 --- a/libnymea-remoteproxy/authentication/aws/awscredentialprovider.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "loggingcategories.h" -#include "awscredentialprovider.h" - -#include -#include -#include -#include - -namespace remoteproxy { - -AwsCredentialProvider::AwsCredentialProvider(QNetworkAccessManager *networkManager, const QUrl &awsCredentialsUrl, QObject *parent) : - QObject(parent), - m_networkManager(networkManager), - m_requestUrl(awsCredentialsUrl) -{ - m_timer = new QTimer(this); - m_timer->setSingleShot(false); - m_timer->setInterval(90000); - - connect(m_timer, &QTimer::timeout, this, &AwsCredentialProvider::onTimeout); -} - -QString AwsCredentialProvider::accessKey() const -{ - return m_accessKey; -} - -QString AwsCredentialProvider::secretAccessKey() const -{ - return m_secretAccessKey; -} - -QString AwsCredentialProvider::sessionToken() const -{ - return m_sessionToken; -} - -bool AwsCredentialProvider::isValid() const -{ - return !m_accessKey.isEmpty() && !m_secretAccessKey.isEmpty() && !m_sessionToken.isEmpty(); -} - -bool AwsCredentialProvider::enabled() const -{ - return m_enabled; -} - -void AwsCredentialProvider::refreshCredentials() -{ - qCDebug(dcAwsCredentialsProvider()) << "Update dynamic credentials form" << m_requestUrl.toString(); - - m_requestTimer.start(); - QNetworkReply *reply = m_networkManager->get(QNetworkRequest(m_requestUrl)); - connect(reply, &QNetworkReply::finished, this, &AwsCredentialProvider::onReplyFinished); -} - -void AwsCredentialProvider::clear() -{ - m_accessKey.clear(); - m_secretAccessKey.clear(); - m_sessionToken.clear(); -} - - -void AwsCredentialProvider::onTimeout() -{ - // TODO: check if we need to refresh - refreshCredentials(); -} - -void AwsCredentialProvider::onReplyFinished() -{ - QNetworkReply *reply = static_cast(sender()); - reply->deleteLater(); - - qCDebug(dcAwsCredentialsProvider()) << "Dynamic credentials request finished (" << m_requestTimer.elapsed() << "[ms] )"; - if (reply->error()) { - qCWarning(dcAwsCredentialsProvider()) << "Dynamic credentials reply error: " << reply->errorString(); - return; - } - - QByteArray data = reply->readAll(); - - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); - - if(error.error != QJsonParseError::NoError) { - qCWarning(dcAwsCredentialsProviderTraffic()) << "Failed to parse dynamic credentials reply data" << data << ":" << error.errorString(); - return; - } - - QVariantMap response = jsonDoc.toVariant().toMap(); - - m_accessKey = response.value("AccessKeyId").toString(); - m_secretAccessKey = response.value("SecretAccessKey").toString(); - m_sessionToken = response.value("Token").toString(); - - qCDebug(dcAwsCredentialsProviderTraffic()) << "Dynamic credentials updated:" << response; - - QDateTime expirationTime = QDateTime::fromString(response.value("Expiration").toString(), "yyyy-MM-ddThh:mm:ssZ"); - QDateTime lastUpdateTime = QDateTime::fromString(response.value("LastUpdated").toString(), "yyyy-MM-ddThh:mm:ssZ"); - qCDebug(dcAwsCredentialsProviderTraffic()) << "Exipration time" << expirationTime.toString("dd.MM.yyyy hh:mm:ss"); - qCDebug(dcAwsCredentialsProviderTraffic()) << "Last update time" << lastUpdateTime.toString("dd.MM.yyyy hh:mm:ss"); -} - -void AwsCredentialProvider::enable() -{ - if (!m_enabled) { - clear(); - m_enabled = true; - } - - qCDebug(dcAwsCredentialsProvider()) << "Enable AWS dynamic credentials provider"; - m_timer->start(); - refreshCredentials(); -} - -void AwsCredentialProvider::disable() -{ - qCDebug(dcAwsCredentialsProvider()) << "Disable AWS dynamic credentials provider"; - m_enabled = false; - m_timer->stop(); - - clear(); -} - -} diff --git a/libnymea-remoteproxy/authentication/aws/awscredentialprovider.h b/libnymea-remoteproxy/authentication/aws/awscredentialprovider.h deleted file mode 100644 index 6ba67d2..0000000 --- a/libnymea-remoteproxy/authentication/aws/awscredentialprovider.h +++ /dev/null @@ -1,88 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef AWSCREDENTIALPROVIDER_H -#define AWSCREDENTIALPROVIDER_H - -#include -#include -#include -#include -#include -#include - -namespace remoteproxy { - -class AwsCredentialProvider : public QObject -{ - Q_OBJECT -public: - explicit AwsCredentialProvider(QNetworkAccessManager *networkManager, const QUrl &awsCredentialsUrl, QObject *parent = nullptr); - - QString accessKey() const; - QString secretAccessKey() const; - QString sessionToken() const; - - bool isValid() const; - bool enabled() const; - -private: - QNetworkAccessManager *m_networkManager = nullptr; - QTimer *m_timer = nullptr; - - QElapsedTimer m_requestTimer; - - bool m_enabled = false; - - QUrl m_requestUrl; - - QString m_accessKey; - QString m_secretAccessKey; - QString m_sessionToken; - - QDateTime m_expirationTime; - QDateTime m_lastUpdateTime; - - void refreshCredentials(); - void clear(); - -private slots: - void onTimeout(); - void onReplyFinished(); - -signals: - void credentialsChanged(); - -public slots: - void enable(); - void disable(); - -}; - -} - -#endif // AWSCREDENTIALPROVIDER_H diff --git a/libnymea-remoteproxy/authentication/aws/sigv4utils.cpp b/libnymea-remoteproxy/authentication/aws/sigv4utils.cpp deleted file mode 100644 index 8e60516..0000000 --- a/libnymea-remoteproxy/authentication/aws/sigv4utils.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "sigv4utils.h" - -#include -#include -#include -#include -#include -#include - -#include "loggingcategories.h" - -namespace remoteproxy { - -SigV4Utils::SigV4Utils() -{ - -} - -void SigV4Utils::signRequest(QNetworkAccessManager::Operation operation, QNetworkRequest &request, const QString ®ion, const QString &service, const QString &invocationType, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken, const QByteArray &payload) -{ - QByteArray dateTime; - if (request.rawHeaderList().contains("x-amz-date")) { - dateTime = request.rawHeader("x-amz-date"); - } else { - dateTime = SigV4Utils::getCurrentDateTime(); - request.setRawHeader("x-amz-date", dateTime); - } - - request.setRawHeader("x-amz-invocation-type", invocationType.toUtf8()); - - if (!sessionToken.isEmpty()) { - request.setRawHeader("x-amz-security-token", sessionToken); - } - - QByteArray canonicalRequest = SigV4Utils::getCanonicalRequest(operation, request, payload); - qCDebug(dcAuthenticationProcess()) << "canonical request:" << "\n" << qUtf8Printable(canonicalRequest); - QByteArray stringToSign = SigV4Utils::getStringToSign(canonicalRequest, dateTime, region.toUtf8(), service.toUtf8()); - qCDebug(dcAuthenticationProcess()) << "string to sign:" << "\n" << qUtf8Printable(stringToSign); - QByteArray signature = SigV4Utils::getSignature(stringToSign, secretAccessKey, dateTime, region, service); - qCDebug(dcAuthenticationProcess()) << "signature:" << signature; - QByteArray authorizeHeader = SigV4Utils::getAuthorizationHeader(accessKeyId, dateTime, region, service, request, signature); - - request.setRawHeader("Authorization", authorizeHeader); -} - -QByteArray SigV4Utils::getCurrentDateTime() -{ - return QDateTime::currentDateTime().toUTC().toString("yyyyMMddThhmmssZ").toUtf8(); -} - -QByteArray SigV4Utils::getCanonicalQueryString(const QNetworkRequest &request, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken, const QByteArray ®ion, const QByteArray &service, const QByteArray &payload) -{ - QByteArray algorithm = "AWS4-HMAC-SHA256"; - QByteArray dateTime = getCurrentDateTime(); - QByteArray credentialScope = getCredentialScope(algorithm, dateTime, region, service); - - QByteArray canonicalQueryString; - canonicalQueryString += "X-Amz-Algorithm=AWS4-HMAC-SHA256"; - canonicalQueryString += "&X-Amz-Credential=" + QByteArray(accessKeyId + '/' + credentialScope).toPercentEncoding(); - canonicalQueryString += "&X-Amz-Date=" + dateTime; - if (request.rawHeaderList().count() > 0){ - canonicalQueryString += "&X-Amz-SignedHeaders=" + request.rawHeaderList().join(';').toLower(); - } - - QByteArray canonicalRequest = getCanonicalRequest(QNetworkAccessManager::GetOperation, request, payload); - - QByteArray stringToSign = getStringToSign(canonicalRequest, dateTime, region, service); - QByteArray signature = getSignature(stringToSign, secretAccessKey, dateTime, region, service); - - canonicalQueryString += "&X-Amz-Signature=" + signature; - - if (!sessionToken.isEmpty()) { - canonicalQueryString += "&X-Amz-Security-Token=" + sessionToken.toPercentEncoding(); - } - - return canonicalQueryString; -} - -QByteArray SigV4Utils::getSignatureKey(const QByteArray &key, const QByteArray &date, const QByteArray ®ion, const QByteArray &service) -{ - QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha256; - return QMessageAuthenticationCode::hash("aws4_request", - QMessageAuthenticationCode::hash(service, - QMessageAuthenticationCode::hash(region, - QMessageAuthenticationCode::hash(date, "AWS4" + key, - hashAlgorithm), hashAlgorithm), hashAlgorithm), hashAlgorithm); -} - -QByteArray SigV4Utils::getCanonicalRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, const QByteArray &payload) -{ - QByteArray canonicalRequest; - - QByteArray method; - switch (operation) { - case QNetworkAccessManager::GetOperation: - method = "GET"; - break; - case QNetworkAccessManager::PostOperation: - method = "POST"; - break; - default: - Q_ASSERT_X(false, "Network operation not implemented", "SigV4Utils"); - } - QByteArray uri = request.url().path(QUrl::FullyEncoded).toUtf8(); - - QUrlQuery query(request.url()); - QList > queryItems = query.queryItems(); - QStringList queryItemStrings; - for (int i = 0; i < queryItems.count(); i++) { - QPair queryItem = queryItems.at(i); - queryItemStrings.append(queryItem.first + '=' + queryItem.second); - } - queryItemStrings.sort(Qt::CaseInsensitive); - - QByteArray canonicalQueryString = queryItemStrings.join('&').toUtf8(); - - QByteArray canonicalHeaders; - foreach(const QByteArray &headerName, request.rawHeaderList()) { - canonicalHeaders += headerName.toLower() + ':' + request.rawHeader(headerName) + '\n'; - } - - QByteArray payloadHash = QCryptographicHash::hash(payload, QCryptographicHash::Sha256).toHex(); - - canonicalRequest = method + '\n' + uri + '\n' + canonicalQueryString + '\n' + canonicalHeaders + '\n' + request.rawHeaderList().join(';').toLower() + '\n' + payloadHash.toLower(); - return canonicalRequest; -} - -QByteArray SigV4Utils::getCredentialScope(const QByteArray &algorithm, const QByteArray &dateTime, const QByteArray ®ion, const QByteArray &service) -{ - Q_UNUSED(algorithm) - QByteArray credentialScope = dateTime.left(8) + '/' + region + '/' + service + "/aws4_request"; - return credentialScope; -} - -QByteArray SigV4Utils::getStringToSign(const QByteArray &canonicalRequest, const QByteArray &dateTime, const QByteArray ®ion, const QByteArray &service) -{ - QByteArray algorithm = "AWS4-HMAC-SHA256"; - QByteArray credentialScope = getCredentialScope(algorithm, dateTime, region, service); - QByteArray stringToSign = algorithm + '\n' + dateTime + '\n' + credentialScope + '\n' + QCryptographicHash::hash(canonicalRequest, QCryptographicHash::Sha256).toHex(); - return stringToSign; -} - -QByteArray SigV4Utils::getSignature(const QByteArray &stringToSign, const QByteArray &secretAccessKey, const QByteArray &dateTime, const QString ®ion, const QString &service) -{ - QByteArray signingKey = getSignatureKey(secretAccessKey, dateTime.left(8), region.toUtf8(), service.toUtf8()); - QByteArray signature = QMessageAuthenticationCode::hash(stringToSign, signingKey, QCryptographicHash::Sha256).toHex(); - return signature; -} - -QByteArray SigV4Utils::getAuthorizationHeader(const QByteArray &accessKeyId, const QByteArray &dateTime, const QString ®ion, const QString &service, const QNetworkRequest &request, const QByteArray &signature) -{ - QByteArray authHeader = "AWS4-HMAC-SHA256 Credential=" + accessKeyId + '/' + dateTime.left(8) + '/' + region.toUtf8() + '/' + service.toUtf8() + '/' + "aws4_request, SignedHeaders=" + request.rawHeaderList().join(';').toLower() + ", Signature=" + signature; - return authHeader; -} -} diff --git a/libnymea-remoteproxy/authentication/aws/sigv4utils.h b/libnymea-remoteproxy/authentication/aws/sigv4utils.h deleted file mode 100644 index 7534b91..0000000 --- a/libnymea-remoteproxy/authentication/aws/sigv4utils.h +++ /dev/null @@ -1,60 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef SIGV4UTILS_H -#define SIGV4UTILS_H - -#include -#include -#include - -namespace remoteproxy { - -class SigV4Utils -{ -public: - SigV4Utils(); - - // Signes a request by adding the "X-AMZ-Date" (if not present) and "X-AMZ-Signature" headers - static void signRequest(QNetworkAccessManager::Operation operation, QNetworkRequest &request, const QString ®ion, const QString &service, const QString &invocationType, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken = QByteArray(), const QByteArray &payload = QByteArray()); - - static QByteArray getCurrentDateTime(); - - static QByteArray getCanonicalQueryString(const QNetworkRequest &request, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken, const QByteArray ®ion, const QByteArray &service, const QByteArray &payload); - static QByteArray getCanonicalRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, const QByteArray &payload); - static QByteArray getCanonicalHeaders(const QNetworkRequest &request); - static QByteArray getCredentialScope(const QByteArray &algorithm, const QByteArray &dateTime, const QByteArray ®ion, const QByteArray &service); - static QByteArray getStringToSign(const QByteArray &canonicalRequest, const QByteArray &dateTime, const QByteArray ®ion, const QByteArray &service); - static QByteArray getSignatureKey(const QByteArray &key, const QByteArray &date, const QByteArray ®ion, const QByteArray &service); - static QByteArray getSignature(const QByteArray &stringToSign, const QByteArray &secretAccessKey, const QByteArray &dateTime, const QString ®ion, const QString &service); - static QByteArray getAuthorizationHeader(const QByteArray &accessKeyId, const QByteArray &dateTime, const QString ®ion, const QString &service, const QNetworkRequest &request, const QByteArray &signature); - -}; - -} - -#endif // SIGV4UTILS_H diff --git a/libnymea-remoteproxy/authentication/aws/userinformation.cpp b/libnymea-remoteproxy/authentication/aws/userinformation.cpp deleted file mode 100644 index 6a2e5e7..0000000 --- a/libnymea-remoteproxy/authentication/aws/userinformation.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "userinformation.h" - -namespace remoteproxy { - -UserInformation::UserInformation(const QString &email, const QString &cognitoUsername, const QString &vendorId, const QString &userPoolId) : - m_email(email), - m_cognitoUsername(cognitoUsername), - m_vendorId(vendorId), - m_userPoolId(userPoolId) -{ - -} - -QString UserInformation::email() const -{ - return m_email; -} - -QString UserInformation::cognitoUsername() const -{ - return m_cognitoUsername; -} - -QString UserInformation::vendorId() const -{ - return m_vendorId; -} - -QString UserInformation::userPoolId() const -{ - return m_userPoolId; -} - -bool UserInformation::isValid() -{ - return !m_email.isEmpty() - && !m_cognitoUsername.isEmpty() - && !m_vendorId.isEmpty() - && !m_userPoolId.isEmpty(); -} - -QDebug operator<<(QDebug debug, const UserInformation &userInformation) -{ - QDebugStateSaver saver(debug); - debug.nospace() << "UserInformation(" << userInformation.email(); - debug.nospace() << ", cognito:" << userInformation.cognitoUsername() << ") "; - debug.nospace() << ", vendor" << userInformation.vendorId() << ") "; - debug.nospace() << ", userpool" << userInformation.userPoolId() << ")"; - return debug; -} - -} diff --git a/libnymea-remoteproxy/authentication/aws/userinformation.h b/libnymea-remoteproxy/authentication/aws/userinformation.h deleted file mode 100644 index 1a2c550..0000000 --- a/libnymea-remoteproxy/authentication/aws/userinformation.h +++ /dev/null @@ -1,60 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef USERINFORMATION_H -#define USERINFORMATION_H - -#include -#include - -namespace remoteproxy { - - -class UserInformation -{ -public: - UserInformation(const QString &email = QString(), const QString &cognitoUsername = QString(), const QString &vendorId = QString(), const QString &userPoolId = QString()); - - QString email() const; - QString cognitoUsername() const; - QString vendorId() const; - QString userPoolId() const; - - bool isValid(); - -private: - QString m_email; - QString m_cognitoUsername; - QString m_vendorId; - QString m_userPoolId; -}; - -QDebug operator<<(QDebug debug, const UserInformation &userInformation); - -} - -#endif // USERINFORMATION_H diff --git a/libnymea-remoteproxy/authentication/dummy/dummyauthenticator.cpp b/libnymea-remoteproxy/authentication/dummy/dummyauthenticator.cpp deleted file mode 100644 index 05c8df4..0000000 --- a/libnymea-remoteproxy/authentication/dummy/dummyauthenticator.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "dummyauthenticator.h" -#include "loggingcategories.h" - -#include - -namespace remoteproxy { - -DummyAuthenticator::DummyAuthenticator(QObject *parent) : - Authenticator(parent) -{ - -} - -QString DummyAuthenticator::name() const -{ - return "Dummy authenticator"; -} - -AuthenticationReply *DummyAuthenticator::authenticate(ProxyClient *proxyClient) -{ - qCDebug(dcAuthentication()) << name() << "validate" << proxyClient; - qCWarning(dcAuthentication()) << "Attention: This authenticator will always succeed! This is a security risk and was explicitly enabled!"; - AuthenticationReply *reply = createAuthenticationReply(proxyClient, proxyClient); - - proxyClient->setUserName("dummy@example.com"); - - setReplyError(reply, AuthenticationErrorNoError); - setReplyFinished(reply); - return reply; -} - -} diff --git a/libnymea-remoteproxy/authentication/dummy/dummyauthenticator.h b/libnymea-remoteproxy/authentication/dummy/dummyauthenticator.h deleted file mode 100644 index 26fdc70..0000000 --- a/libnymea-remoteproxy/authentication/dummy/dummyauthenticator.h +++ /dev/null @@ -1,54 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef DUMMYAUTHENTICATOR_H -#define DUMMYAUTHENTICATOR_H - -#include - -#include "proxy/proxyclient.h" -#include "authentication/authenticator.h" - -namespace remoteproxy { - -class DummyAuthenticator : public Authenticator -{ - Q_OBJECT -public: - explicit DummyAuthenticator(QObject *parent = nullptr); - ~DummyAuthenticator() override = default; - - QString name() const override; - -public slots: - AuthenticationReply *authenticate(ProxyClient *proxyClient) override; - -}; - -} - -#endif // DUMMYAUTHENTICATOR_H diff --git a/libnymea-remoteproxy/engine.cpp b/libnymea-remoteproxy/engine.cpp index 197a507..6206334 100644 --- a/libnymea-remoteproxy/engine.cpp +++ b/libnymea-remoteproxy/engine.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -69,49 +69,13 @@ void Engine::start(ProxyConfiguration *configuration) m_configuration = configuration; qCDebug(dcEngine()) << "Using configuration" << m_configuration; - // TODO: the old proxy server is deprecated. Will be removed in future releases - if (configuration->proxyEnabled()) { - // Make sure an authenticator was registered - Q_ASSERT_X(m_authenticator != nullptr, "Engine", "There is no authenticator registerd."); - - // Proxy - // ------------------------------------- - m_proxyServer = new ProxyServer(this); - m_webSocketServerProxy = new WebSocketServer(m_configuration->sslEnabled(), m_configuration->sslConfiguration(), this); - m_tcpSocketServerProxy = new TcpSocketServer(m_configuration->sslEnabled(), m_configuration->sslConfiguration(), this); - m_unixSocketServerProxy = new UnixSocketServer(m_configuration->unixSocketFileName(), this); - - // Configure websocket server - QUrl websocketServerUrl; - websocketServerUrl.setScheme(m_configuration->sslEnabled() ? "wss" : "ws"); - websocketServerUrl.setHost(m_configuration->webSocketServerProxyHost().toString()); - websocketServerUrl.setPort(m_configuration->webSocketServerProxyPort()); - m_webSocketServerProxy->setServerUrl(websocketServerUrl); - - // Configure tcp socket server - QUrl tcpSocketServerProxyUrl; - tcpSocketServerProxyUrl.setScheme(m_configuration->sslEnabled() ? "ssl" : "tcp"); - tcpSocketServerProxyUrl.setHost(m_configuration->tcpServerHost().toString()); - tcpSocketServerProxyUrl.setPort(m_configuration->tcpServerPort()); - m_tcpSocketServerProxy->setServerUrl(tcpSocketServerProxyUrl); - - // Register the transport interfaces in the proxy server - m_proxyServer->registerTransportInterface(m_webSocketServerProxy); - m_proxyServer->registerTransportInterface(m_tcpSocketServerProxy); - m_proxyServer->registerTransportInterface(m_unixSocketServerProxy); - - // Start the server - qCDebug(dcEngine()) << "Starting the proxy servers..."; - m_proxyServer->startServer(); - } else { - qCDebug(dcEngine()) << "Proxy server disabled. Not starting proxy server."; - } // Tunnel proxy // ------------------------------------- m_tunnelProxyServer = new TunnelProxyServer(this); m_webSocketServerTunnelProxy = new WebSocketServer(m_configuration->sslEnabled(), m_configuration->sslConfiguration(), this); m_tcpSocketServerTunnelProxy = new TcpSocketServer(m_configuration->sslEnabled(), m_configuration->sslConfiguration(), this); + m_unixSocketServerTunnelProxy = new UnixSocketServer(m_configuration->unixSocketFileName(), this); // Configure websocket server QUrl websocketServerTunnelProxyUrl; @@ -130,6 +94,7 @@ void Engine::start(ProxyConfiguration *configuration) // Register the transport interfaces in the proxy server m_tunnelProxyServer->registerTransportInterface(m_webSocketServerTunnelProxy); m_tunnelProxyServer->registerTransportInterface(m_tcpSocketServerTunnelProxy); + m_tunnelProxyServer->registerTransportInterface(m_unixSocketServerTunnelProxy); // Start the server qCDebug(dcEngine()) << "Starting the tunnel proxy manager..."; @@ -161,67 +126,24 @@ bool Engine::running() const return m_running; } -bool Engine::developerMode() const -{ - return m_developerMode; -} - QString Engine::serverName() const { return m_configuration->serverName(); } -void Engine::setAuthenticator(Authenticator *authenticator) -{ - if (m_authenticator == authenticator) - return; - - if (m_authenticator) { - qCDebug(dcEngine()) << "There is already an authenticator registered. Unregister default authenticator"; - m_authenticator = nullptr; - } - - m_authenticator = authenticator; -} - -void Engine::setDeveloperModeEnabled(bool enabled) -{ - m_developerMode = enabled; -} - ProxyConfiguration *Engine::configuration() const { return m_configuration; } -Authenticator *Engine::authenticator() const -{ - return m_authenticator; -} - -ProxyServer *Engine::proxyServer() const -{ - return m_proxyServer; -} - TunnelProxyServer *Engine::tunnelProxyServer() const { return m_tunnelProxyServer; } -TcpSocketServer *Engine::tcpSocketServerProxy() const +UnixSocketServer *Engine::unixSocketServerTunnelProxy() const { - return m_tcpSocketServerProxy; -} - -WebSocketServer *Engine::webSocketServerProxy() const -{ - return m_webSocketServerProxy; -} - -UnixSocketServer *Engine::unixSocketServerProxy() const -{ - return m_unixSocketServerProxy; + return m_unixSocketServerTunnelProxy; } TcpSocketServer *Engine::tcpSocketServerTunnelProxy() const @@ -250,9 +172,6 @@ QVariantMap Engine::buildMonitorData(bool printAll) monitorData.insert("serverName", m_configuration->serverName()); monitorData.insert("serverVersion", SERVER_VERSION_STRING); monitorData.insert("apiVersion", API_VERSION_STRING); - if (m_proxyServer) { - monitorData.insert("proxyStatistic", m_proxyServer->currentStatistics()); - } monitorData.insert("tunnelProxyStatistic", tunnelProxyServer()->currentStatistics(printAll)); return monitorData; } @@ -285,21 +204,9 @@ void Engine::onTimerTick() if (m_currentTimeCounter >= 1000) { // One second passed, do second tick m_currentTimeCounter = 0; - - if (m_proxyServer) { - m_proxyServer->tick(); - } - if (m_tunnelProxyServer) { m_tunnelProxyServer->tick(); } - - // QVariantMap serverStatistics = buildMonitorData(); - // m_monitorServer->updateClients(serverStatistics); - - // m_logEngine->logStatistics(serverStatistics.value("proxyStatistic").toMap().value("tunnelCount").toInt(), - // serverStatistics.value("proxyStatistic").toMap().value("clientCount").toInt(), - // serverStatistics.value("proxyStatistic").toMap().value("troughput").toInt()); } } @@ -311,28 +218,12 @@ void Engine::clean() m_monitorServer = nullptr; } - if (m_proxyServer) { - m_proxyServer->stopServer(); - delete m_proxyServer; - m_proxyServer = nullptr; - } - if (m_tunnelProxyServer) { m_tunnelProxyServer->stopServer(); delete m_tunnelProxyServer; m_tunnelProxyServer = nullptr; } - if (m_tcpSocketServerProxy) { - delete m_tcpSocketServerProxy; - m_tcpSocketServerProxy = nullptr; - } - - if (m_webSocketServerProxy) { - delete m_webSocketServerProxy; - m_webSocketServerProxy = nullptr; - } - if (m_tcpSocketServerTunnelProxy) { delete m_tcpSocketServerTunnelProxy; m_tcpSocketServerTunnelProxy = nullptr; @@ -343,6 +234,11 @@ void Engine::clean() m_webSocketServerTunnelProxy = nullptr; } + if (m_unixSocketServerTunnelProxy) { + delete m_unixSocketServerTunnelProxy; + m_unixSocketServerTunnelProxy = nullptr; + } + if (m_configuration) { delete m_configuration; m_configuration = nullptr; @@ -354,9 +250,6 @@ void Engine::setRunning(bool running) if (m_running == running) return; - if (m_proxyServer) - m_proxyServer->setRunning(running); - if (m_tunnelProxyServer) m_tunnelProxyServer->setRunning(running); diff --git a/libnymea-remoteproxy/engine.h b/libnymea-remoteproxy/engine.h index e3297dc..65b4edf 100644 --- a/libnymea-remoteproxy/engine.h +++ b/libnymea-remoteproxy/engine.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -36,14 +36,12 @@ #include #include "logengine.h" -#include "proxy/proxyserver.h" #include "proxyconfiguration.h" #include "server/monitorserver.h" #include "server/jsonrpcserver.h" #include "server/tcpsocketserver.h" #include "server/websocketserver.h" #include "server/unixsocketserver.h" -#include "authentication/authenticator.h" #include "tunnelproxy/tunnelproxyserver.h" namespace remoteproxy { @@ -61,23 +59,14 @@ public: void stop(); bool running() const; - bool developerMode() const; QString serverName() const; - void setAuthenticator(Authenticator *authenticator); - void setDeveloperModeEnabled(bool enabled); - ProxyConfiguration *configuration() const; - Authenticator *authenticator() const; - ProxyServer *proxyServer() const; TunnelProxyServer *tunnelProxyServer() const; - TcpSocketServer *tcpSocketServerProxy() const; - WebSocketServer *webSocketServerProxy() const; - UnixSocketServer *unixSocketServerProxy() const; - + UnixSocketServer *unixSocketServerTunnelProxy() const; TcpSocketServer *tcpSocketServerTunnelProxy() const; WebSocketServer *webSocketServerTunnelProxy() const; @@ -97,18 +86,11 @@ private: qint64 m_runTime = 0; bool m_running = false; - bool m_developerMode = false; ProxyConfiguration *m_configuration = nullptr; - Authenticator *m_authenticator = nullptr; - - ProxyServer *m_proxyServer = nullptr; TunnelProxyServer *m_tunnelProxyServer = nullptr; - TcpSocketServer *m_tcpSocketServerProxy = nullptr; - WebSocketServer *m_webSocketServerProxy = nullptr; - UnixSocketServer *m_unixSocketServerProxy = nullptr; - + UnixSocketServer *m_unixSocketServerTunnelProxy = nullptr; TcpSocketServer *m_tcpSocketServerTunnelProxy = nullptr; WebSocketServer *m_webSocketServerTunnelProxy = nullptr; diff --git a/libnymea-remoteproxy/jsonrpc/authenticationhandler.cpp b/libnymea-remoteproxy/jsonrpc/authenticationhandler.cpp deleted file mode 100644 index fba509f..0000000 --- a/libnymea-remoteproxy/jsonrpc/authenticationhandler.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "jsontypes.h" -#include "loggingcategories.h" -#include "authenticationhandler.h" -#include "server/transportclient.h" - -#include "engine.h" - -namespace remoteproxy { - -AuthenticationHandler::AuthenticationHandler(QObject *parent) : - JsonHandler(parent) -{ - // Methods - QVariantMap params; QVariantMap returns; - - setDescription("Authenticate", "Authenticate this connection. The returned AuthenticationError informs " - "about the result. If the authentication was not successfull, the server will close the " - "connection immediatly after sending the error response. The given id should be a unique " - "id the other tunnel client can understand. Once the authentication was successfull, you " - "can wait for the RemoteProxy.TunnelEstablished notification. If you send any data before " - "getting this notification, the server will close the connection. If the tunnel client does " - "not show up within 10 seconds, the server will close the connection."); - params.insert("uuid", JsonTypes::basicTypeToString(JsonTypes::String)); - params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String)); - params.insert("token", JsonTypes::basicTypeToString(JsonTypes::String)); - params.insert("o:nonce", JsonTypes::basicTypeToString(JsonTypes::String)); - setParams("Authenticate", params); - returns.insert("authenticationError", JsonTypes::authenticationErrorRef()); - setReturns("Authenticate", returns); -} - -QString AuthenticationHandler::name() const -{ - return "Authentication"; -} - -JsonReply *AuthenticationHandler::Authenticate(const QVariantMap ¶ms, TransportClient *transportClient) -{ - QUuid uuid = params.value("uuid").toUuid(); - QString name = params.value("name").toString(); - QString token = params.value("token").toString(); - QString nonce = params.value("nonce").toString(); - - qCDebug(dcJsonRpc()) << "Authenticate:" << name << uuid << token << nonce; - JsonReply *jsonReply = createAsyncReply("Authenticate"); - - // Set the token for this proxy client - ProxyClient *proxyClient = qobject_cast(transportClient); - proxyClient->setUuid(uuid); - proxyClient->setName(name); - proxyClient->setToken(token); - proxyClient->setNonce(nonce); - - AuthenticationReply *authReply = Engine::instance()->authenticator()->authenticate(proxyClient); - connect(authReply, &AuthenticationReply::finished, jsonReply, [=](){ - authReply->deleteLater(); - - qCDebug(dcJsonRpc()) << "Authentication reply finished"; - if (authReply->error() != Authenticator::AuthenticationErrorNoError) { - qCWarning(dcJsonRpc()) << "Authentication error occurred" << authReply->error(); - jsonReply->setSuccess(false); - } else { - // Successfully authenticated - jsonReply->setSuccess(true); - } - - // Set client authenticated if still there - if (!authReply->proxyClient().isNull()) { - authReply->proxyClient()->setAuthenticated(authReply->error() == Authenticator::AuthenticationErrorNoError); - jsonReply->setData(errorToReply(authReply->error())); - } - - emit jsonReply->finished(); - }); - - return jsonReply; -} - -} diff --git a/libnymea-remoteproxy/jsonrpc/authenticationhandler.h b/libnymea-remoteproxy/jsonrpc/authenticationhandler.h deleted file mode 100644 index 6513887..0000000 --- a/libnymea-remoteproxy/jsonrpc/authenticationhandler.h +++ /dev/null @@ -1,55 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef AUTHENTICATIONHANDLER_H -#define AUTHENTICATIONHANDLER_H - -#include - -#include "jsonhandler.h" -#include "authentication/authenticationreply.h" - -namespace remoteproxy { - -class TransportClient; - -class AuthenticationHandler : public JsonHandler -{ - Q_OBJECT -public: - explicit AuthenticationHandler(QObject *parent = nullptr); - ~AuthenticationHandler() override = default; - - QString name() const override; - - Q_INVOKABLE JsonReply *Authenticate(const QVariantMap ¶ms, TransportClient *transportClient); - -}; - -} - -#endif // AUTHENTICATIONHANDLER_H diff --git a/libnymea-remoteproxy/jsonrpc/jsonhandler.cpp b/libnymea-remoteproxy/jsonrpc/jsonhandler.cpp index 8b9dc88..bdecbcc 100644 --- a/libnymea-remoteproxy/jsonrpc/jsonhandler.cpp +++ b/libnymea-remoteproxy/jsonrpc/jsonhandler.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -135,12 +135,6 @@ void JsonHandler::setReturns(const QString &methodName, const QVariantMap &retur qCWarning(dcJsonRpc()) << "Cannot set returns. No such method:" << methodName; } -QVariantMap JsonHandler::errorToReply(Authenticator::AuthenticationError error) const -{ - QVariantMap returns; - returns.insert("authenticationError", JsonTypes::authenticationErrorToString(error)); - return returns; -} JsonReply *JsonHandler::createReply(const QString &method, const QVariantMap &data) const { diff --git a/libnymea-remoteproxy/jsonrpc/jsonhandler.h b/libnymea-remoteproxy/jsonrpc/jsonhandler.h index 5d9e1e3..d8c3ec8 100644 --- a/libnymea-remoteproxy/jsonrpc/jsonhandler.h +++ b/libnymea-remoteproxy/jsonrpc/jsonhandler.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -34,8 +34,6 @@ #include #include -#include "authentication/authenticator.h" - namespace remoteproxy { class JsonReply; @@ -67,8 +65,6 @@ protected: void setParams(const QString &methodName, const QVariantMap ¶ms); void setReturns(const QString &methodName, const QVariantMap &returns); - QVariantMap errorToReply(Authenticator::AuthenticationError error) const; - JsonReply *createReply(const QString &method, const QVariantMap &data) const; JsonReply *createAsyncReply(const QString &method) const; }; diff --git a/libnymea-remoteproxy/jsonrpc/jsonreply.cpp b/libnymea-remoteproxy/jsonrpc/jsonreply.cpp index 4ca5fad..3753c87 100644 --- a/libnymea-remoteproxy/jsonrpc/jsonreply.cpp +++ b/libnymea-remoteproxy/jsonrpc/jsonreply.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/jsonrpc/jsonreply.h b/libnymea-remoteproxy/jsonrpc/jsonreply.h index 15bba7b..01977ca 100644 --- a/libnymea-remoteproxy/jsonrpc/jsonreply.h +++ b/libnymea-remoteproxy/jsonrpc/jsonreply.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/jsonrpc/jsontypes.cpp b/libnymea-remoteproxy/jsonrpc/jsontypes.cpp index a91d19f..94e6df1 100644 --- a/libnymea-remoteproxy/jsonrpc/jsontypes.cpp +++ b/libnymea-remoteproxy/jsonrpc/jsontypes.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -39,7 +39,6 @@ QString JsonTypes::s_lastError; // Types QVariantList JsonTypes::s_basicType; -QVariantList JsonTypes::s_authenticationError; QVariantList JsonTypes::s_tunnelProxyError; // Objects @@ -51,7 +50,6 @@ QVariantMap JsonTypes::allTypes() // Enums allTypes.insert("BasicType", basicType()); - allTypes.insert("AuthenticationError", authenticationError()); allTypes.insert("TunnelProxyError", tunnelProxyError()); return allTypes; @@ -61,7 +59,6 @@ void JsonTypes::init() { // Declare types s_basicType = enumToStrings(JsonTypes::staticMetaObject, "BasicType"); - s_authenticationError = enumToStrings(Authenticator::staticMetaObject, "AuthenticationError"); s_tunnelProxyError = enumToStrings(TunnelProxyServer::staticMetaObject, "TunnelProxyError"); s_initialized = true; @@ -118,12 +115,6 @@ QPair JsonTypes::validateVariant(const QVariant &templateVariant, qCWarning(dcJsonRpc()) << QString("Value %1 not allowed in %2").arg(variant.toString()).arg(basicTypeRef()); return result; } - } else if (refName == authenticationErrorRef()) { - QPair result = validateEnum(s_authenticationError, variant); - if (!result.first) { - qCWarning(dcJsonRpc()) << QString("Value %1 not allowed in %2").arg(variant.toString()).arg(authenticationErrorRef()); - return result; - } } else if (refName == tunnelProxyErrorRef()) { QPair result = validateEnum(s_tunnelProxyError, variant); if (!result.first) { diff --git a/libnymea-remoteproxy/jsonrpc/jsontypes.h b/libnymea-remoteproxy/jsonrpc/jsontypes.h index bab2c1f..812fefc 100644 --- a/libnymea-remoteproxy/jsonrpc/jsontypes.h +++ b/libnymea-remoteproxy/jsonrpc/jsontypes.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -34,7 +34,6 @@ #include #include "tunnelproxy/tunnelproxyserver.h" -#include "authentication/authenticator.h" namespace remoteproxy { @@ -90,7 +89,6 @@ public: // Declare types DECLARE_TYPE(basicType, "BasicType", JsonTypes, BasicType) - DECLARE_TYPE(authenticationError, "AuthenticationError", Authenticator, AuthenticationError) DECLARE_TYPE(tunnelProxyError, "TunnelProxyError", TunnelProxyServer, TunnelProxyError) // Declare objects diff --git a/libnymea-remoteproxy/libnymea-remoteproxy.pro b/libnymea-remoteproxy/libnymea-remoteproxy.pro index 5c4b166..9f3ade5 100644 --- a/libnymea-remoteproxy/libnymea-remoteproxy.pro +++ b/libnymea-remoteproxy/libnymea-remoteproxy.pro @@ -9,22 +9,10 @@ HEADERS += \ logengine.h \ loggingcategories.h \ proxyconfiguration.h \ - authentication/authenticator.h \ - authentication/authenticationreply.h \ - authentication/aws/awsauthenticator.h \ - authentication/aws/userinformation.h \ - authentication/aws/authenticationprocess.h \ - authentication/aws/sigv4utils.h \ - authentication/aws/awscredentialprovider.h \ - authentication/dummy/dummyauthenticator.h \ jsonrpc/jsonhandler.h \ jsonrpc/jsonreply.h \ jsonrpc/jsontypes.h \ - jsonrpc/authenticationhandler.h \ jsonrpc/tunnelproxyhandler.h \ - proxy/proxyclient.h \ - proxy/proxyserver.h \ - proxy/tunnelconnection.h \ server/tcpsocketserver.h \ server/transportinterface.h \ server/unixsocketserver.h \ @@ -42,22 +30,10 @@ SOURCES += \ logengine.cpp \ loggingcategories.cpp \ proxyconfiguration.cpp \ - authentication/authenticator.cpp \ - authentication/authenticationreply.cpp \ - authentication/aws/awsauthenticator.cpp \ - authentication/aws/userinformation.cpp \ - authentication/aws/authenticationprocess.cpp \ - authentication/aws/sigv4utils.cpp \ - authentication/aws/awscredentialprovider.cpp \ - authentication/dummy/dummyauthenticator.cpp \ jsonrpc/jsonhandler.cpp \ jsonrpc/jsonreply.cpp \ jsonrpc/jsontypes.cpp \ - jsonrpc/authenticationhandler.cpp \ jsonrpc/tunnelproxyhandler.cpp \ - proxy/proxyclient.cpp \ - proxy/proxyserver.cpp \ - proxy/tunnelconnection.cpp \ server/tcpsocketserver.cpp \ server/transportinterface.cpp \ server/transportclient.cpp \ diff --git a/libnymea-remoteproxy/logengine.cpp b/libnymea-remoteproxy/logengine.cpp index ab7392c..73f5a71 100644 --- a/libnymea-remoteproxy/logengine.cpp +++ b/libnymea-remoteproxy/logengine.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -44,25 +44,6 @@ LogEngine::~LogEngine() disable(); } -void LogEngine::logTunnel(const TunnelConnection &tunnel) -{ - if (!m_tunnelsFile.isOpen()) - return; - - // - - QStringList logString; - logString << createTimestamp(); - logString << QString::number(tunnel.creationTime()); - logString << tunnel.clientOne()->userName(); - logString << tunnel.clientOne()->peerAddress().toString(); - logString << tunnel.clientTwo()->peerAddress().toString(); - logString << QString::number(tunnel.clientOne()->rxDataCount() + tunnel.clientOne()->txDataCount()); - - QTextStream textStream(&m_tunnelsFile); - textStream << logString.join(" ") << "\n"; -} - void LogEngine::logStatistics(int tunnelCount, int connectionCount, int troughput) { if (!m_statisticsFile.isOpen()) diff --git a/libnymea-remoteproxy/logengine.h b/libnymea-remoteproxy/logengine.h index 5acf8b3..9668a1a 100644 --- a/libnymea-remoteproxy/logengine.h +++ b/libnymea-remoteproxy/logengine.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -31,8 +31,6 @@ #include #include -#include "proxy/tunnelconnection.h" - namespace remoteproxy { class LogEngine : public QObject @@ -42,7 +40,6 @@ public: explicit LogEngine(QObject *parent = nullptr); ~LogEngine(); - void logTunnel(const TunnelConnection &tunnel); void logStatistics(int tunnelCount, int connectionCount, int troughput); private: diff --git a/libnymea-remoteproxy/loggingcategories.cpp b/libnymea-remoteproxy/loggingcategories.cpp index bca229b..f13d1cd 100644 --- a/libnymea-remoteproxy/loggingcategories.cpp +++ b/libnymea-remoteproxy/loggingcategories.cpp @@ -30,20 +30,14 @@ Q_LOGGING_CATEGORY(dcApplication, "Application") Q_LOGGING_CATEGORY(dcEngine, "Engine") Q_LOGGING_CATEGORY(dcJsonRpc, "JsonRpc") -Q_LOGGING_CATEGORY(dcTunnel, "Tunnel") Q_LOGGING_CATEGORY(dcJsonRpcTraffic, "JsonRpcTraffic") Q_LOGGING_CATEGORY(dcTcpSocketServer, "TcpSocketServer") Q_LOGGING_CATEGORY(dcTcpSocketServerTraffic, "TcpSocketServerTraffic") Q_LOGGING_CATEGORY(dcWebSocketServer, "WebSocketServer") Q_LOGGING_CATEGORY(dcWebSocketServerTraffic, "WebSocketServerTraffic") -Q_LOGGING_CATEGORY(dcAuthentication, "Authentication") -Q_LOGGING_CATEGORY(dcAuthenticationProcess, "AuthenticationProcess") -Q_LOGGING_CATEGORY(dcProxyServer, "ProxyServer") -Q_LOGGING_CATEGORY(dcProxyServerTraffic, "ProxyServerTraffic") Q_LOGGING_CATEGORY(dcTunnelProxyServer, "TunnelProxyServer") Q_LOGGING_CATEGORY(dcTunnelProxyServerTraffic, "TunnelProxyServerTraffic") Q_LOGGING_CATEGORY(dcMonitorServer, "MonitorServer") Q_LOGGING_CATEGORY(dcUnixSocketServer, "UnixSocketServer") Q_LOGGING_CATEGORY(dcUnixSocketServerTraffic, "UnixSocketServerTraffic") -Q_LOGGING_CATEGORY(dcAwsCredentialsProvider, "AwsCredentialsProvider") -Q_LOGGING_CATEGORY(dcAwsCredentialsProviderTraffic, "AwsCredentialsProviderTraffic") + diff --git a/libnymea-remoteproxy/loggingcategories.h b/libnymea-remoteproxy/loggingcategories.h index af3d79e..cbc13a8 100644 --- a/libnymea-remoteproxy/loggingcategories.h +++ b/libnymea-remoteproxy/loggingcategories.h @@ -34,22 +34,15 @@ Q_DECLARE_LOGGING_CATEGORY(dcApplication) Q_DECLARE_LOGGING_CATEGORY(dcEngine) Q_DECLARE_LOGGING_CATEGORY(dcJsonRpc) -Q_DECLARE_LOGGING_CATEGORY(dcTunnel) Q_DECLARE_LOGGING_CATEGORY(dcJsonRpcTraffic) Q_DECLARE_LOGGING_CATEGORY(dcWebSocketServer) Q_DECLARE_LOGGING_CATEGORY(dcWebSocketServerTraffic) Q_DECLARE_LOGGING_CATEGORY(dcTcpSocketServer) Q_DECLARE_LOGGING_CATEGORY(dcTcpSocketServerTraffic) -Q_DECLARE_LOGGING_CATEGORY(dcAuthentication) -Q_DECLARE_LOGGING_CATEGORY(dcAuthenticationProcess) -Q_DECLARE_LOGGING_CATEGORY(dcProxyServer) -Q_DECLARE_LOGGING_CATEGORY(dcProxyServerTraffic) Q_DECLARE_LOGGING_CATEGORY(dcTunnelProxyServer) Q_DECLARE_LOGGING_CATEGORY(dcTunnelProxyServerTraffic) Q_DECLARE_LOGGING_CATEGORY(dcMonitorServer) Q_DECLARE_LOGGING_CATEGORY(dcUnixSocketServer) Q_DECLARE_LOGGING_CATEGORY(dcUnixSocketServerTraffic) -Q_DECLARE_LOGGING_CATEGORY(dcAwsCredentialsProvider) -Q_DECLARE_LOGGING_CATEGORY(dcAwsCredentialsProviderTraffic) #endif // LOGGINGCATEGORIES_H diff --git a/libnymea-remoteproxy/proxy/proxyclient.cpp b/libnymea-remoteproxy/proxy/proxyclient.cpp deleted file mode 100644 index 118b8b2..0000000 --- a/libnymea-remoteproxy/proxy/proxyclient.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "engine.h" -#include "proxyclient.h" -#include "loggingcategories.h" - -#include - -namespace remoteproxy { - -ProxyClient::ProxyClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent) : - TransportClient(interface, clientId, address, parent) -{ - m_timer = new QTimer(this); - connect(m_timer, &QTimer::timeout, this, &ProxyClient::timeoutOccurred); - m_timer->setSingleShot(true); - resetTimer(); -} - -bool ProxyClient::isAuthenticated() const -{ - return m_authenticated; -} - -void ProxyClient::setAuthenticated(bool isAuthenticated) -{ - m_authenticated = isAuthenticated; - if (m_authenticated) { - m_timerWaitState = TimerWaitStateAlone; - resetTimer(); - emit authenticated(); - } -} - -bool ProxyClient::isTunnelConnected() const -{ - return m_tunnelConnected; -} - -void ProxyClient::setTunnelConnected(bool isTunnelConnected) -{ - m_tunnelConnected = isTunnelConnected; - if (m_tunnelConnected) { - m_timer->stop(); - emit tunnelConnected(); - } -} - -QString ProxyClient::userName() const -{ - return m_userName; -} - -void ProxyClient::setUserName(const QString &userName) -{ - m_userName = userName; -} - -QString ProxyClient::tunnelIdentifier() const -{ - return m_token + m_nonce; -} - -QString ProxyClient::token() const -{ - return m_token; -} - -void ProxyClient::setToken(const QString &token) -{ - m_token = token; -} - -QString ProxyClient::nonce() const -{ - return m_nonce; -} - -void ProxyClient::setNonce(const QString &nonce) -{ - m_nonce = nonce; -} - -ProxyClient::TimerWaitState ProxyClient::timerWaitState() const -{ - return m_timerWaitState; -} - -void ProxyClient::resetTimer() -{ - switch (m_timerWaitState) { - case TimerWaitStateInactive: - m_timer->start(Engine::instance()->configuration()->inactiveTimeout()); - break; - case TimerWaitStateAlone: - m_timer->start(Engine::instance()->configuration()->aloneTimeout()); - break; - } -} - -QList ProxyClient::processData(const QByteArray &data) -{ - QList packets; - - // Handle packet fragmentation - m_dataBuffer.append(data); - int splitIndex = m_dataBuffer.indexOf("}\n{"); - while (splitIndex > -1) { - packets.append(m_dataBuffer.left(splitIndex + 1)); - m_dataBuffer = m_dataBuffer.right(m_dataBuffer.length() - splitIndex - 2); - splitIndex = m_dataBuffer.indexOf("}\n{"); - } - if (m_dataBuffer.endsWith("}\n") || m_dataBuffer.endsWith("}")) { - packets.append(m_dataBuffer); - m_dataBuffer.clear(); - } - - return packets; -} - -QDebug operator<<(QDebug debug, ProxyClient *proxyClient) -{ - QDebugStateSaver saver(debug); - debug.nospace() << "ProxyClient("; - if (!proxyClient->name().isEmpty()) { - debug.nospace() << proxyClient->name() << ", "; - } - debug.nospace() << proxyClient->interface()->serverName(); - debug.nospace() << ", " << proxyClient->clientId().toString(); - debug.nospace() << ", " << proxyClient->userName(); - debug.nospace() << ", " << proxyClient->peerAddress().toString(); - debug.nospace() << ", " << proxyClient->creationTimeString() << ")"; - return debug; -} - -} diff --git a/libnymea-remoteproxy/proxy/proxyclient.h b/libnymea-remoteproxy/proxy/proxyclient.h deleted file mode 100644 index 8d4aff5..0000000 --- a/libnymea-remoteproxy/proxy/proxyclient.h +++ /dev/null @@ -1,101 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef PROXYCLIENT_H -#define PROXYCLIENT_H - -#include -#include -#include -#include -#include - -#include "server/transportclient.h" - -namespace remoteproxy { - -class ProxyClient : public TransportClient -{ - Q_OBJECT - -public: - enum TimerWaitState { - TimerWaitStateInactive, - TimerWaitStateAlone - }; - Q_ENUM(TimerWaitState) - - explicit ProxyClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent = nullptr); - - bool isAuthenticated() const; - void setAuthenticated(bool isAuthenticated); - - bool isTunnelConnected() const; - void setTunnelConnected(bool isTunnelConnected); - - QString userName() const; - void setUserName(const QString &userName); - - QString tunnelIdentifier() const; - - QString token() const; - void setToken(const QString &token); - - QString nonce() const; - void setNonce(const QString &nonce); - - // Actions for this client - TimerWaitState timerWaitState() const; - void resetTimer(); - - // Json server methods - QList processData(const QByteArray &data) override; - -private: - QTimer *m_timer = nullptr; - TimerWaitState m_timerWaitState = TimerWaitStateInactive; - - bool m_authenticated = false; - bool m_tunnelConnected = false; - - QString m_token; - QString m_nonce; - - QString m_userName; - -signals: - void authenticated(); - void tunnelConnected(); - void timeoutOccurred(); - -}; - -QDebug operator<< (QDebug debug, ProxyClient *proxyClient); - -} - -#endif // PROXYCLIENT_H diff --git a/libnymea-remoteproxy/proxy/proxyserver.cpp b/libnymea-remoteproxy/proxy/proxyserver.cpp deleted file mode 100644 index 28681d2..0000000 --- a/libnymea-remoteproxy/proxy/proxyserver.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2022, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "engine.h" -#include "proxyserver.h" -#include "loggingcategories.h" - -#include -#include -#include -#include - -namespace remoteproxy { - -ProxyServer::ProxyServer(QObject *parent) : - QObject(parent) -{ - qRegisterMetaType("ProxyClient *"); - m_jsonRpcServer = new JsonRpcServer(this); - m_jsonRpcServer->registerHandler(m_jsonRpcServer); - m_jsonRpcServer->registerHandler(new AuthenticationHandler(this)); - - loadStatistics(); -} - -ProxyServer::~ProxyServer() -{ - qCDebug(dcProxyServer()) << "Shutting down proxy server"; -} - -bool ProxyServer::running() const -{ - return m_running; -} - -void ProxyServer::registerTransportInterface(TransportInterface *interface) -{ - qCDebug(dcProxyServer()) << "Register transport interface" << interface->serverName(); - - if (m_transportInterfaces.contains(interface)) { - qCWarning(dcProxyServer()) << "Transport interface already registerd."; - return; - } - - connect(interface, &TransportInterface::clientConnected, this, &ProxyServer::onClientConnected); - connect(interface, &TransportInterface::clientDisconnected, this, &ProxyServer::onClientDisconnected); - connect(interface, &TransportInterface::dataAvailable, this, &ProxyServer::onClientDataAvailable); - - m_transportInterfaces.append(interface); -} - -QVariantMap ProxyServer::currentStatistics() -{ - QVariantMap statisticsMap; - statisticsMap.insert("clientCount", m_proxyClients.count()); - statisticsMap.insert("tunnelCount", m_tunnels.count()); - statisticsMap.insert("troughput", m_troughput); - - QVariantMap totalStatisticsMap; - totalStatisticsMap.insert("totalClientCount", m_totalClientCount); - totalStatisticsMap.insert("totalTunnelCount", m_totalTunnelCount); - totalStatisticsMap.insert("totalTraffic", m_totalTraffic); - statisticsMap.insert("total", totalStatisticsMap); - - // Create client list - QVariantList clientList; - foreach (ProxyClient *client, m_proxyClients) { - QVariantMap clientMap; - clientMap.insert("id", client->clientId().toString()); - clientMap.insert("address", client->peerAddress().toString()); - clientMap.insert("timestamp", client->creationTime()); - clientMap.insert("authenticated", client->isAuthenticated()); - clientMap.insert("tunnelConnected", client->isTunnelConnected()); - clientMap.insert("name", client->name()); - clientMap.insert("userName", client->userName()); - clientMap.insert("uuid", client->uuid()); - clientMap.insert("rxDataCount", client->rxDataCount()); - clientMap.insert("txDataCount", client->txDataCount()); - clientList.append(clientMap); - } - statisticsMap.insert("clients", clientList); - - // Create tunnel list - QVariantList tunnelList; - foreach (const TunnelConnection &tunnel, m_tunnels) { - QVariantMap tunnelMap; - tunnelMap.insert("clientOne", tunnel.clientOne()->clientId().toString()); - tunnelMap.insert("clientTwo", tunnel.clientTwo()->clientId().toString()); - tunnelMap.insert("timestamp", tunnel.creationTime()); - tunnelList.append(tunnelMap); - } - statisticsMap.insert("tunnels", tunnelList); - - return statisticsMap; -} - -void ProxyServer::setRunning(bool running) -{ - if (m_running == running) - return; - - qCDebug(dcProxyServer()) << "The proxy server is" << (running ? "up and running." : "not running any more."); - m_running = running; - emit runningChanged(); -} - -void ProxyServer::loadStatistics() -{ - QSettings settings; - settings.beginGroup("Statistics"); - m_totalClientCount = settings.value("totalClientCount", 0).toInt(); - m_totalTunnelCount = settings.value("totalTunnelCount", 0).toInt(); - m_totalTraffic = settings.value("totalTraffic", 0).toInt(); - settings.endGroup(); -} - -void ProxyServer::saveStatistics() -{ - QSettings settings; - settings.beginGroup("Statistics"); - settings.setValue("totalClientCount", m_totalClientCount); - settings.value("totalTunnelCount", m_totalTunnelCount); - settings.value("totalTraffic", m_totalTraffic); - settings.endGroup(); -} - -ProxyClient *ProxyServer::getRemoteClient(ProxyClient *proxyClient) -{ - if (!m_tunnels.contains(proxyClient->tunnelIdentifier())) - return nullptr; - - if (proxyClient == m_tunnels.value(proxyClient->tunnelIdentifier()).clientOne()) { - return m_tunnels.value(proxyClient->tunnelIdentifier()).clientTwo(); - } else if (proxyClient == m_tunnels.value(proxyClient->tunnelIdentifier()).clientTwo()) { - return m_tunnels.value(proxyClient->tunnelIdentifier()).clientOne(); - } - - return nullptr; -} - -void ProxyServer::establishTunnel(ProxyClient *firstClient, ProxyClient *secondClient) -{ - qCDebug(dcProxyServer()) << "Create tunnel between authenticated clients " << firstClient << secondClient; - - TunnelConnection tunnel(firstClient, secondClient); - if (!tunnel.isValid()) { - qCWarning(dcProxyServer()) << "Invalid tunnel. Could not establish connection."; - //FIXME: - } - - m_tunnels.insert(tunnel.tunnelIdentifier(), tunnel); - - // Tell both clients the tunnel has been established - QVariantMap notificationParamsFirst; - notificationParamsFirst.insert("name", tunnel.clientTwo()->name()); - notificationParamsFirst.insert("uuid", tunnel.clientTwo()->uuid()); - - QVariantMap notificationParamsSecond; - notificationParamsSecond.insert("name", tunnel.clientOne()->name()); - notificationParamsSecond.insert("uuid", tunnel.clientOne()->uuid()); - - // Make sure the proxy is the first one who knows that the tunnel is connected - firstClient->setTunnelConnected(true); - secondClient->setTunnelConnected(true); - - qCDebug(dcProxyServer()) << tunnel; - qCDebug(dcTunnel()) << "Tunnel established between" << firstClient->peerAddress().toString() << firstClient->clientId() - << "<-->" << secondClient->peerAddress().toString() << secondClient->clientId(); - - m_totalTunnelCount += 1; - saveStatistics(); - - // Notify the clients in the next event loop - QMetaObject::invokeMethod(m_jsonRpcServer, QString("sendNotification").toLatin1().data(), Qt::QueuedConnection, - Q_ARG(QString, m_jsonRpcServer->name()), - Q_ARG(QString, "TunnelEstablished"), - Q_ARG(QVariantMap, notificationParamsFirst), - Q_ARG(TransportClient*, tunnel.clientOne())); - - QMetaObject::invokeMethod(m_jsonRpcServer, QString("sendNotification").toLatin1().data(), Qt::QueuedConnection, - Q_ARG(QString, m_jsonRpcServer->name()), - Q_ARG(QString, "TunnelEstablished"), - Q_ARG(QVariantMap, notificationParamsSecond), - Q_ARG(TransportClient*, tunnel.clientTwo())); -} - -void ProxyServer::onClientConnected(const QUuid &clientId, const QHostAddress &address) -{ - TransportInterface *interface = static_cast(sender()); - - qCDebug(dcProxyServer()) << "New client connected" << interface->serverName() << clientId.toString() << address.toString(); - - ProxyClient *proxyClient = new ProxyClient(interface, clientId, address, this); - connect(proxyClient, &ProxyClient::authenticated, this, &ProxyServer::onProxyClientAuthenticated); - connect(proxyClient, &ProxyClient::timeoutOccurred, this, &ProxyServer::onProxyClientTimeoutOccurred); - - m_totalClientCount += 1; - saveStatistics(); - - m_proxyClients.insert(clientId, proxyClient); - m_jsonRpcServer->registerClient(proxyClient); -} - -void ProxyServer::onClientDisconnected(const QUuid &clientId) -{ - TransportInterface *interface = static_cast(sender()); - qCDebug(dcProxyServer()) << "Client disconnected" << interface->serverName() << clientId.toString(); - - if (m_proxyClients.contains(clientId)) { - ProxyClient *proxyClient = m_proxyClients.take(clientId); - - // Clean up client tables - if (m_authenticatedClients.values().contains(proxyClient)) { - m_authenticatedClients.remove(proxyClient->token()); - } - - if (m_authenticatedClientsNonce.values().contains(proxyClient)) { - m_authenticatedClientsNonce.remove(proxyClient->nonce()); - } - - // Unregister from json rpc server - m_jsonRpcServer->unregisterClient(proxyClient); - - // Check if - if (m_tunnels.contains(proxyClient->tunnelIdentifier())) { - // There is a tunnel connection for this client, remove the tunnel and disconnect also the other client - ProxyClient *remoteClient = getRemoteClient(proxyClient); - TunnelConnection tunnelConnection = m_tunnels.take(proxyClient->tunnelIdentifier()); - Engine::instance()->logEngine()->logTunnel(tunnelConnection); - if (remoteClient) { - qCDebug(dcTunnel()) << "Remove tunnel between" << proxyClient->peerAddress().toString() << proxyClient->clientId() - << "<-->" << remoteClient->peerAddress().toString() << remoteClient->clientId(); - remoteClient->killConnection("Tunnel client disconnected"); - } - } - - // Delete the proxy client - proxyClient->deleteLater(); - } else { - qCWarning(dcProxyServer()) << "Unknown client disconnected from proxy server." << clientId.toString(); - } -} - -void ProxyServer::onClientDataAvailable(const QUuid &clientId, const QByteArray &data) -{ - ProxyClient *proxyClient = m_proxyClients.value(clientId); - if (!proxyClient) { - qCWarning(dcProxyServer()) << "Could not find client for uuid" << clientId; - return; - } - - // If this client is not authenticated yet, and not tunnel connected, pipe the traffic into the json rpc server - if (!proxyClient->isAuthenticated() && !proxyClient->isTunnelConnected()) { - qCDebug(dcProxyServerTraffic()) << "Client data available" << proxyClient << qUtf8Printable(data); - m_jsonRpcServer->processData(proxyClient, data); - // Reset the inactive timer - proxyClient->resetTimer(); - return; - } - - // If the client is authenticated, but no tunnel created yet, kill the connection since no addition call is allowed until - // the tunne is fully established. - if (proxyClient->isAuthenticated() && !proxyClient->isTunnelConnected()) { - qCWarning(dcProxyServer()) << "An authenticated client sent data without tunnel connection. This is not allowed."; - m_jsonRpcServer->unregisterClient(proxyClient); - // The client is authenticated and tries to send data, this is not allowed. - proxyClient->killConnection("Data received while authenticated but not remote connected."); - return; - } - - if (proxyClient->isAuthenticated() && proxyClient->isTunnelConnected()) { - ProxyClient *remoteClient = getRemoteClient(proxyClient); - Q_ASSERT_X(remoteClient, "ProxyServer", "Tunnel existing but not tunnel client available"); - Q_ASSERT_X(m_tunnels.contains(proxyClient->tunnelIdentifier()), "ProxyServer", "Tunnel connect but not existing"); - - // Calculate server statisitcs - m_troughputCounter += data.count(); - proxyClient->addRxDataCount(data.count()); - - if (!remoteClient) - return; - - remoteClient->addTxDataCount(data.count()); - - m_totalTraffic += data.count(); - saveStatistics(); - - qCDebug(dcProxyServerTraffic()) << "Pipe tunnel data:"; - qCDebug(dcProxyServerTraffic()) << " --> from" << proxyClient; - qCDebug(dcProxyServerTraffic()) << " --> to" << remoteClient; - qCDebug(dcProxyServerTraffic()) << " --> data:" << qUtf8Printable(data); - - remoteClient->sendData(data); - } -} - -void ProxyServer::onProxyClientAuthenticated() -{ - ProxyClient *proxyClient = static_cast(sender()); - - qCDebug(dcProxyServer()) << "Client authenticated" << proxyClient; - - //FIXME: limit the amount of connection with one token - - // Check if we already have a tunnel with this identifier - if (m_tunnels.contains(proxyClient->tunnelIdentifier())) { - qCWarning(dcProxyServer()) << "There is already a tunnel with this token and nonce. The client has to take a new nonce or a new token."; - // There is already a tunnel with this token and nonce. Reject the connection - proxyClient->killConnection("Tunnel already exists for this token nonce combination."); - return; - } - - - // FIXME: for backwards compatibility - if (proxyClient->nonce().isEmpty()) { - // Check if we have an other authenticated client with this token - if (m_authenticatedClients.keys().contains(proxyClient->token())) { - - // Found a client with this token - ProxyClient *tunnelPartner = m_authenticatedClients.take(proxyClient->token()); - - // Check if the two clients show up with the same uuid to prevent connection loops - if (tunnelPartner->uuid() == proxyClient->uuid()) { - qCWarning(dcProxyServer()) << "The clients have the same uuid. This is not allowed."; - proxyClient->killConnection("Duplicated client UUID."); - tunnelPartner->killConnection("Duplicated client UUID."); - return; - } - - // All ok so far. Create the tunnel - establishTunnel(tunnelPartner, proxyClient); - } else { - // Append and wait for the other client - m_authenticatedClients.insert(proxyClient->token(), proxyClient); - } - } else { - // The client passed a nonce, let's hash with that to prevent cross connections - if (m_authenticatedClientsNonce.keys().contains(proxyClient->nonce())) { - // Found a client with this nonce - ProxyClient *tunnelPartner = m_authenticatedClientsNonce.take(proxyClient->nonce()); - - // Check if the two clients show up with the same uuid to prevent connection loops - if (tunnelPartner->uuid() == proxyClient->uuid()) { - qCWarning(dcProxyServer()) << "The clients have the same uuid. This could cause a loop and is not allowed."; - proxyClient->killConnection("Client loop detected."); - tunnelPartner->killConnection("Client loop detected."); - return; - } - - // All ok so far. Create the tunnel - establishTunnel(tunnelPartner, proxyClient); - } else { - m_authenticatedClientsNonce.insert(proxyClient->nonce(), proxyClient); - } - } -} - -void ProxyServer::onProxyClientTimeoutOccurred() -{ - ProxyClient *proxyClient = static_cast(sender()); - qCDebug(dcProxyServer()) << "Timeout occurred for" << proxyClient; - switch (proxyClient->timerWaitState()) { - case ProxyClient::TimerWaitStateInactive: - proxyClient->killConnection("Proxy timeout occurred. The socket was inactive."); - break; - case ProxyClient::TimerWaitStateAlone: - proxyClient->killConnection("Proxy timeout occurred. The tunnel partner did not show up."); - break; - } -} - -void ProxyServer::startServer() -{ - qCDebug(dcProxyServer()) << "Starting proxy server..."; - foreach (TransportInterface *interface, m_transportInterfaces) { - interface->startServer(); - } - setRunning(true); -} - -void ProxyServer::stopServer() -{ - qCDebug(dcProxyServer()) << "Stopping proxy..."; - foreach (TransportInterface *interface, m_transportInterfaces) { - interface->stopServer(); - } - setRunning(false); -} - -void ProxyServer::tick() -{ - m_troughput = m_troughputCounter; - m_troughputCounter = 0; -} - -} diff --git a/libnymea-remoteproxy/proxy/proxyserver.h b/libnymea-remoteproxy/proxy/proxyserver.h deleted file mode 100644 index 2f8d1fa..0000000 --- a/libnymea-remoteproxy/proxy/proxyserver.h +++ /dev/null @@ -1,111 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef PROXYSERVER_H -#define PROXYSERVER_H - -#include -#include -#include - -#include "proxyclient.h" -#include "tunnelconnection.h" -#include "server/jsonrpcserver.h" -#include "server/transportinterface.h" - -namespace remoteproxy { - -class ProxyServer : public QObject -{ - Q_OBJECT -public: - explicit ProxyServer(QObject *parent = nullptr); - ~ProxyServer(); - - bool running() const; - void setRunning(bool running); - - void registerTransportInterface(TransportInterface *interface); - - QVariantMap currentStatistics(); - -private: - JsonRpcServer *m_jsonRpcServer = nullptr; - QList m_transportInterfaces; - - bool m_running = false; - - // Transport ClientId, ProxyClient - QHash m_proxyClients; - - // FIXME: Token, ProxyClient - QHash m_authenticatedClients; - - // TunnelIdentifier (token + nonce), ProxyClient - QHash m_authenticatedClientsNonce; - - // Token, Tunnel - QHash m_tunnels; - - // Statistic measurments - int m_troughput = 0; - int m_troughputCounter = 0; - - // Persistent statistics - int m_totalClientCount = 0; - int m_totalTunnelCount = 0; - int m_totalTraffic = 0; - - void loadStatistics(); - void saveStatistics(); - - // Helper methods - ProxyClient *getRemoteClient(ProxyClient *proxyClient); - void establishTunnel(ProxyClient *firstClient, ProxyClient *secondClient); - -signals: - void runningChanged(); - -private slots: - void onClientConnected(const QUuid &clientId, const QHostAddress &address); - void onClientDisconnected(const QUuid &clientId); - void onClientDataAvailable(const QUuid &clientId, const QByteArray &data); - - void onProxyClientAuthenticated(); - void onProxyClientTimeoutOccurred(); - -public slots: - void startServer(); - void stopServer(); - - void tick(); - -}; - -} - -#endif // PROXYSERVER_H diff --git a/libnymea-remoteproxy/proxy/tunnelconnection.cpp b/libnymea-remoteproxy/proxy/tunnelconnection.cpp deleted file mode 100644 index 6a88014..0000000 --- a/libnymea-remoteproxy/proxy/tunnelconnection.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "tunnelconnection.h" - -#include - -namespace remoteproxy { - -TunnelConnection::TunnelConnection(ProxyClient *clientOne, ProxyClient *clientTwo): - m_clientOne(clientOne), - m_clientTwo(clientTwo) -{ - m_creationTimeStamp = QDateTime::currentDateTimeUtc().toTime_t(); -} - -QString TunnelConnection::token() const -{ - if (!isValid()) - return QString(); - - return m_clientOne->token(); -} - -QString TunnelConnection::nonce() const -{ - if (!isValid()) - return QString(); - - return m_clientOne->nonce(); -} - -QString TunnelConnection::tunnelIdentifier() const -{ - if (!isValid()) - return QString(); - - return m_clientOne->tunnelIdentifier(); -} - -uint TunnelConnection::creationTime() const -{ - return m_creationTimeStamp; -} - -QString TunnelConnection::creationTimeString() const -{ - return QDateTime::fromTime_t(creationTime()).toString("dd.MM.yyyy hh:mm:ss"); -} - -ProxyClient *TunnelConnection::clientOne() const -{ - return m_clientOne; -} - -ProxyClient *TunnelConnection::clientTwo() const -{ - return m_clientTwo; -} - -bool TunnelConnection::hasClient(ProxyClient *proxyClient) const -{ - return m_clientOne == proxyClient || m_clientTwo == proxyClient; -} - -bool TunnelConnection::isValid() const -{ - // Both clients have to be valid - if (!m_clientOne || !m_clientTwo) - return false; - - // Both clients need the same token - if (m_clientOne->token() != m_clientTwo->token()) - return false; - - // The clients need to be different - if (m_clientOne == m_clientTwo) - return false; - - return true; -} - -QDebug operator<<(QDebug debug, const TunnelConnection &tunnel) -{ - QDebugStateSaver saver(debug); - debug.nospace() << "TunnelConnection(" << tunnel.creationTimeString() << ")\n"; - debug.nospace() << " --> " << tunnel.clientOne() << "\n"; - debug.nospace() << " --> " << tunnel.clientTwo() << "\n"; - return debug; -} - -} diff --git a/libnymea-remoteproxy/proxy/tunnelconnection.h b/libnymea-remoteproxy/proxy/tunnelconnection.h deleted file mode 100644 index fb022be..0000000 --- a/libnymea-remoteproxy/proxy/tunnelconnection.h +++ /dev/null @@ -1,66 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef TUNNELCONNECTION_H -#define TUNNELCONNECTION_H - -#include "proxyclient.h" - -namespace remoteproxy { - -class TunnelConnection -{ -public: - TunnelConnection(ProxyClient *clientOne = nullptr, ProxyClient *clientTwo = nullptr); - - QString token() const; - QString nonce() const; - QString tunnelIdentifier() const; - - uint creationTime() const; - QString creationTimeString() const; - - ProxyClient *clientOne() const; - ProxyClient *clientTwo() const; - - bool hasClient(ProxyClient *proxyClient) const; - - bool isValid() const; - -private: - uint m_creationTimeStamp = 0; - - ProxyClient *m_clientOne = nullptr; - ProxyClient *m_clientTwo = nullptr; - -}; - -QDebug operator<< (QDebug debug, const TunnelConnection &tunnel); - -} - -#endif // TUNNELCONNECTION_H diff --git a/libnymea-remoteproxy/proxyconfiguration.cpp b/libnymea-remoteproxy/proxyconfiguration.cpp index cbc72fd..6c4afc0 100644 --- a/libnymea-remoteproxy/proxyconfiguration.cpp +++ b/libnymea-remoteproxy/proxyconfiguration.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -54,21 +54,12 @@ bool ProxyConfiguration::loadConfiguration(const QString &fileName) settings.beginGroup("ProxyServer"); setServerName(settings.value("name", "nymea-remoteproxy").toString()); - setProxyEnabled(settings.value("proxyEnabled", true).toBool()); setWriteLogFile(settings.value("writeLogs", false).toBool()); setLogFileName(settings.value("logFile", "/var/log/nymea-remoteproxy.log").toString()); setLogEngineEnabled(settings.value("logEngineEnabled", false).toBool()); setMonitorSocketFileName(settings.value("monitorSocket", "/tmp/nymea-remoteproxy.monitor").toString()); setJsonRpcTimeout(settings.value("jsonRpcTimeout", 10000).toInt()); - setAuthenticationTimeout(settings.value("authenticationTimeout", 8000).toInt()); setInactiveTimeout(settings.value("inactiveTimeout", 8000).toInt()); - setAloneTimeout(settings.value("aloneTimeout", 8000).toInt()); - settings.endGroup(); - - settings.beginGroup("AWS"); - setAwsRegion(settings.value("region", "eu-west-1").toString()); - setAwsAuthorizerLambdaFunctionName(settings.value("authorizerLambdaFunction", "system-services-authorizer-dev-checkToken").toString()); - setAwsCredentialsUrl(QUrl(settings.value("awsCredentialsUrl", "http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2-Remote-Connection-Proxy-Role").toString())); settings.endGroup(); settings.beginGroup("SSL"); @@ -78,17 +69,7 @@ bool ProxyConfiguration::loadConfiguration(const QString &fileName) setSslCertificateChainFileName(settings.value("certificateChain", "").toString()); settings.endGroup(); - settings.beginGroup("WebSocketServer"); - setWebSocketServerHost(QHostAddress(settings.value("host", "127.0.0.1").toString())); - setWebSocketServerPort(static_cast(settings.value("port", 1212).toInt())); - settings.endGroup(); - - settings.beginGroup("TcpServer"); - setTcpServerHost(QHostAddress(settings.value("host", "127.0.0.1").toString())); - setTcpServerPort(static_cast(settings.value("port", 1213).toInt())); - settings.endGroup(); - - settings.beginGroup("UnixSocketServer"); + settings.beginGroup("UnixSocketServerTunnelProxy"); setUnixSocketFileName(settings.value("unixSocketFileName", "/run/nymea-remoteproxy.socket").toString()); settings.endGroup(); @@ -212,16 +193,6 @@ void ProxyConfiguration::setJsonRpcTimeout(int timeout) m_jsonRpcTimeout = timeout; } -int ProxyConfiguration::authenticationTimeout() const -{ - return m_authenticationTimeout; -} - -void ProxyConfiguration::setAuthenticationTimeout(int timeout) -{ - m_authenticationTimeout = timeout; -} - int ProxyConfiguration::inactiveTimeout() const { return m_inactiveTimeout; @@ -232,56 +203,6 @@ void ProxyConfiguration::setInactiveTimeout(int timeout) m_inactiveTimeout = timeout; } -int ProxyConfiguration::aloneTimeout() const -{ - return m_aloneTimeout; -} - -void ProxyConfiguration::setAloneTimeout(int timeout) -{ - m_aloneTimeout = timeout; -} - -bool ProxyConfiguration::proxyEnabled() const -{ - return m_proxyEnabled; -} - -void ProxyConfiguration::setProxyEnabled(bool proxyEnabled) -{ - m_proxyEnabled = proxyEnabled; -} - -QString ProxyConfiguration::awsRegion() const -{ - return m_awsRegion; -} - -void ProxyConfiguration::setAwsRegion(const QString ®ion) -{ - m_awsRegion = region; -} - -QString ProxyConfiguration::awsAuthorizerLambdaFunctionName() const -{ - return m_awsAuthorizerLambdaFunctionName; -} - -void ProxyConfiguration::setAwsAuthorizerLambdaFunctionName(const QString &functionName) -{ - m_awsAuthorizerLambdaFunctionName = functionName; -} - -QUrl ProxyConfiguration::awsCredentialsUrl() const -{ - return m_awsCredentialsUrl; -} - -void ProxyConfiguration::setAwsCredentialsUrl(const QUrl &url) -{ - m_awsCredentialsUrl = url; -} - bool ProxyConfiguration::sslEnabled() const { return m_sslEnabled; @@ -327,46 +248,6 @@ QSslConfiguration ProxyConfiguration::sslConfiguration() const return m_sslConfiguration; } -QHostAddress ProxyConfiguration::webSocketServerProxyHost() const -{ - return m_webSocketServerProxyHost; -} - -void ProxyConfiguration::setWebSocketServerHost(const QHostAddress &address) -{ - m_webSocketServerProxyHost = address; -} - -quint16 ProxyConfiguration::webSocketServerProxyPort() const -{ - return m_webSocketServerProxyPort; -} - -void ProxyConfiguration::setWebSocketServerPort(quint16 port) -{ - m_webSocketServerProxyPort = port; -} - -QHostAddress ProxyConfiguration::tcpServerHost() const -{ - return m_tcpServerHost; -} - -void ProxyConfiguration::setTcpServerHost(const QHostAddress &address) -{ - m_tcpServerHost = address; -} - -quint16 ProxyConfiguration::tcpServerPort() const -{ - return m_tcpServerPort; -} - -void ProxyConfiguration::setTcpServerPort(quint16 port) -{ - m_tcpServerPort = port; -} - QString ProxyConfiguration::unixSocketFileName() const { return m_unixSocketFileName; @@ -428,9 +309,7 @@ QDebug operator<<(QDebug debug, ProxyConfiguration *configuration) debug.nospace() << " - Logfile:" << configuration->logFileName() << "\n"; debug.nospace() << " - Log engine enabled:" << configuration->logEngineEnabled() << "\n"; debug.nospace() << " - JSON RPC timeout:" << configuration->jsonRpcTimeout() << " [ms]" << "\n"; - debug.nospace() << " - Authentication timeout:" << configuration->authenticationTimeout() << " [ms]" << "\n"; debug.nospace() << " - Inactive timeout:" << configuration->inactiveTimeout() << " [ms]" << "\n"; - debug.nospace() << " - Alone timeout:" << configuration->aloneTimeout() << " [ms]" << "\n"; debug.nospace() << "SSL configuration" << "\n"; debug.nospace() << " - Enabled:" << configuration->sslEnabled() << "\n"; debug.nospace() << " - Certificate:" << configuration->sslCertificateFileName() << "\n"; @@ -452,22 +331,8 @@ QDebug operator<<(QDebug debug, ProxyConfiguration *configuration) debug.nospace() << " Locality name:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::LocalityName) << "\n"; debug.nospace() << " State/Province:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::StateOrProvinceName) << "\n"; debug.nospace() << " Email address:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::EmailAddress) << "\n"; - if (configuration->proxyEnabled()) { - debug.nospace() << "AWS configuration" << "\n"; - debug.nospace() << " - Region:" << configuration->awsRegion() << "\n"; - debug.nospace() << " - Authorizer lambda function:" << configuration->awsAuthorizerLambdaFunctionName() << "\n"; - debug.nospace() << " - Credentials URL:" << configuration->awsCredentialsUrl().toString() << "\n"; - debug.nospace() << "WebSocketServer Proxy" << "\n"; - debug.nospace() << " - Host:" << configuration->webSocketServerProxyHost().toString() << "\n"; - debug.nospace() << " - Port:" << configuration->webSocketServerProxyPort() << "\n"; - debug.nospace() << "TcpServer Proxy" << "\n"; - debug.nospace() << " - Host:" << configuration->tcpServerHost().toString() << "\n"; - debug.nospace() << " - Port:" << configuration->tcpServerPort() << "\n"; - debug.nospace() << "UnixSocketServer Proxy" << "\n"; - debug.nospace() << " - Filename:" << configuration->unixSocketFileName() << "\n"; - } else { - debug.nospace() << "Proxy Server: disabled" << "\n"; - } + debug.nospace() << "UnixSocketServer Proxy" << endl; + debug.nospace() << " - Filename:" << configuration->unixSocketFileName() << "\n"; debug.nospace() << "WebSocketServer TunnelProxy" << "\n"; debug.nospace() << " - Host:" << configuration->webSocketServerTunnelProxyHost().toString() << "\n"; debug.nospace() << " - Port:" << configuration->webSocketServerTunnelProxyPort() << "\n"; diff --git a/libnymea-remoteproxy/proxyconfiguration.h b/libnymea-remoteproxy/proxyconfiguration.h index 0a9e3a7..d7f76fe 100644 --- a/libnymea-remoteproxy/proxyconfiguration.h +++ b/libnymea-remoteproxy/proxyconfiguration.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -65,28 +65,9 @@ public: int jsonRpcTimeout() const; void setJsonRpcTimeout(int timeout); - int authenticationTimeout() const; - void setAuthenticationTimeout(int timeout); - int inactiveTimeout() const; void setInactiveTimeout(int timeout); - int aloneTimeout() const; - void setAloneTimeout(int timeout); - - bool proxyEnabled() const; - void setProxyEnabled(bool proxyEnabled); - - // AWS - QString awsRegion() const; - void setAwsRegion(const QString ®ion); - - QString awsAuthorizerLambdaFunctionName() const; - void setAwsAuthorizerLambdaFunctionName( const QString &functionName); - - QUrl awsCredentialsUrl() const; - void setAwsCredentialsUrl(const QUrl &url); - // Ssl bool sslEnabled() const; void setSslEnabled(bool enabled); @@ -102,21 +83,7 @@ public: QSslConfiguration sslConfiguration() const; - // WebSocketServer - QHostAddress webSocketServerProxyHost() const; - void setWebSocketServerHost(const QHostAddress &address); - - quint16 webSocketServerProxyPort() const; - void setWebSocketServerPort(quint16 port); - - // TcpServer - QHostAddress tcpServerHost() const; - void setTcpServerHost(const QHostAddress &address); - - quint16 tcpServerPort() const; - void setTcpServerPort(quint16 port); - - // UnixSocketServer + // UnixSocketServer (tunnel) QString unixSocketFileName() const; void setUnixSocketFileName(const QString &unixSocketFileName); @@ -144,16 +111,7 @@ private: QString m_monitorSocketFileName; int m_jsonRpcTimeout = 10000; - int m_authenticationTimeout = 8000; int m_inactiveTimeout = 8000; - int m_aloneTimeout = 8000; - - bool m_proxyEnabled = true; - - // AWS - QString m_awsRegion; - QString m_awsAuthorizerLambdaFunctionName; - QUrl m_awsCredentialsUrl; // Ssl bool m_sslEnabled = true; @@ -162,15 +120,7 @@ private: QString m_sslCertificateChainFileName; QSslConfiguration m_sslConfiguration; - // WebSocketServer (proxy) - QHostAddress m_webSocketServerProxyHost = QHostAddress::LocalHost; - quint16 m_webSocketServerProxyPort = 1212; - - // TcpServer (proxy) - QHostAddress m_tcpServerHost = QHostAddress::LocalHost; - quint16 m_tcpServerPort = 1213; - - // UnixSocketServer (proxy) + // UnixSocketServer (tunnel) QString m_unixSocketFileName = "/run/nymea-remoteproxy.socket"; // WebSocketServer (tunnel) @@ -181,7 +131,6 @@ private: QHostAddress m_tcpServerTunnelProxyHost = QHostAddress::LocalHost; quint16 m_tcpServerTunnelProxyPort = 2213; - }; QDebug operator<< (QDebug debug, ProxyConfiguration *configuration); diff --git a/libnymea-remoteproxy/server/jsonrpcserver.cpp b/libnymea-remoteproxy/server/jsonrpcserver.cpp index a5c5950..6cc8c5e 100644 --- a/libnymea-remoteproxy/server/jsonrpcserver.cpp +++ b/libnymea-remoteproxy/server/jsonrpcserver.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/server/jsonrpcserver.h b/libnymea-remoteproxy/server/jsonrpcserver.h index a18a941..f0f3be0 100644 --- a/libnymea-remoteproxy/server/jsonrpcserver.h +++ b/libnymea-remoteproxy/server/jsonrpcserver.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -31,11 +31,10 @@ #include #include -#include "proxy/proxyclient.h" +#include "transportclient.h" #include "jsonrpc/jsonreply.h" #include "transportinterface.h" #include "jsonrpc/jsonhandler.h" -#include "jsonrpc/authenticationhandler.h" namespace remoteproxy { diff --git a/libnymea-remoteproxy/server/monitorserver.cpp b/libnymea-remoteproxy/server/monitorserver.cpp index 380e4ad..e12d0d9 100644 --- a/libnymea-remoteproxy/server/monitorserver.cpp +++ b/libnymea-remoteproxy/server/monitorserver.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/server/monitorserver.h b/libnymea-remoteproxy/server/monitorserver.h index 951efc9..9d7057d 100644 --- a/libnymea-remoteproxy/server/monitorserver.h +++ b/libnymea-remoteproxy/server/monitorserver.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/server/tcpsocketserver.cpp b/libnymea-remoteproxy/server/tcpsocketserver.cpp index 5be62c7..a6d60cb 100644 --- a/libnymea-remoteproxy/server/tcpsocketserver.cpp +++ b/libnymea-remoteproxy/server/tcpsocketserver.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/server/tcpsocketserver.h b/libnymea-remoteproxy/server/tcpsocketserver.h index a76dae5..1768891 100644 --- a/libnymea-remoteproxy/server/tcpsocketserver.h +++ b/libnymea-remoteproxy/server/tcpsocketserver.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/server/transportinterface.cpp b/libnymea-remoteproxy/server/transportinterface.cpp index 5e969b1..573c8e1 100644 --- a/libnymea-remoteproxy/server/transportinterface.cpp +++ b/libnymea-remoteproxy/server/transportinterface.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/server/transportinterface.h b/libnymea-remoteproxy/server/transportinterface.h index 606ae9c..2abad50 100644 --- a/libnymea-remoteproxy/server/transportinterface.h +++ b/libnymea-remoteproxy/server/transportinterface.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/server/websocketserver.cpp b/libnymea-remoteproxy/server/websocketserver.cpp index f90ef94..bbc440f 100644 --- a/libnymea-remoteproxy/server/websocketserver.cpp +++ b/libnymea-remoteproxy/server/websocketserver.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/server/websocketserver.h b/libnymea-remoteproxy/server/websocketserver.h index 6ab8008..e772297 100644 --- a/libnymea-remoteproxy/server/websocketserver.h +++ b/libnymea-remoteproxy/server/websocketserver.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxy/tunnelproxy/tunnelproxyserver.cpp b/libnymea-remoteproxy/tunnelproxy/tunnelproxyserver.cpp index 560cb6b..81c05a2 100644 --- a/libnymea-remoteproxy/tunnelproxy/tunnelproxyserver.cpp +++ b/libnymea-remoteproxy/tunnelproxy/tunnelproxyserver.cpp @@ -317,11 +317,6 @@ void TunnelProxyServer::onClientConnected(const QUuid &clientId, const QHostAddr TunnelProxyClient *tunnelProxyClient = new TunnelProxyClient(interface, clientId, address, this); m_proxyClients.insert(clientId, tunnelProxyClient); m_jsonRpcServer->registerClient(tunnelProxyClient); - -// // For debugging -// qCDebug(dcTunnelProxyServer()) << "#### Total clients:" << m_proxyClients.count() << "JSON RPC clients:" << m_jsonRpcServer->registeredClientCount() -// << "Interface connections:" << tunnelProxyClient->interface()->connectionsCount() -// << "Servers:" << m_tunnelProxyServerConnections.count() << "Clients:" << m_tunnelProxyClientConnections.count(); } void TunnelProxyServer::onClientDisconnected(const QUuid &clientId) diff --git a/libnymea-remoteproxyclient/jsonreply.cpp b/libnymea-remoteproxyclient/jsonreply.cpp index 18d6620..652c40b 100644 --- a/libnymea-remoteproxyclient/jsonreply.cpp +++ b/libnymea-remoteproxyclient/jsonreply.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxyclient/jsonreply.h b/libnymea-remoteproxyclient/jsonreply.h index 7461ea2..7868acb 100644 --- a/libnymea-remoteproxyclient/jsonreply.h +++ b/libnymea-remoteproxyclient/jsonreply.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri b/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri index 0e02bc9..8fe87e3 100644 --- a/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri +++ b/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri @@ -5,22 +5,20 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/tunnelproxy/tunnelproxyremoteconnection.h \ $$PWD/tunnelproxy/tunnelproxysocket.h \ + $$PWD/tunnelproxy/tunnelproxysocketserver.h \ $$PWD/tcpsocketconnection.h \ $$PWD/proxyjsonrpcclient.h \ $$PWD/jsonreply.h \ - $$PWD/remoteproxyconnection.h \ $$PWD/proxyconnection.h \ - $$PWD/tunnelproxy/tunnelproxysocketserver.h \ $$PWD/websocketconnection.h SOURCES += \ $$PWD/tunnelproxy/tunnelproxyremoteconnection.cpp \ $$PWD/tunnelproxy/tunnelproxysocket.cpp \ + $$PWD/tunnelproxy/tunnelproxysocketserver.cpp \ $$PWD/tcpsocketconnection.cpp \ $$PWD/proxyjsonrpcclient.cpp \ $$PWD/jsonreply.cpp \ - $$PWD/remoteproxyconnection.cpp \ $$PWD/proxyconnection.cpp \ - $$PWD/tunnelproxy/tunnelproxysocketserver.cpp \ $$PWD/websocketconnection.cpp diff --git a/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pro b/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pro index 665366f..acaf853 100644 --- a/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pro +++ b/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pro @@ -10,8 +10,8 @@ installheaders.files = remoteproxyconnection.h installheaders.path = $$[QT_INSTALL_PREFIX]/include/nymea-remoteproxyclient/ installtunnelheaders.files = tunnelproxy/tunnelproxyremoteconnection.h \ - tunnelproxy/tunnelproxysocket.h \ - tunnelproxy/tunnelproxysocketserver.h + tunnelproxy/tunnelproxysocket.h \ + tunnelproxy/tunnelproxysocketserver.h installtunnelheaders.path = $$[QT_INSTALL_PREFIX]/include/nymea-remoteproxyclient/tunnelproxy diff --git a/libnymea-remoteproxyclient/proxyconnection.cpp b/libnymea-remoteproxyclient/proxyconnection.cpp index 6fe5377..dd4bfa3 100644 --- a/libnymea-remoteproxyclient/proxyconnection.cpp +++ b/libnymea-remoteproxyclient/proxyconnection.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxyclient/proxyconnection.h b/libnymea-remoteproxyclient/proxyconnection.h index 6cfb7b1..f0d4ad2 100644 --- a/libnymea-remoteproxyclient/proxyconnection.h +++ b/libnymea-remoteproxyclient/proxyconnection.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp b/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp index e80bfb5..4170548 100644 --- a/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp +++ b/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -52,21 +52,6 @@ JsonReply *JsonRpcClient::callHello() return reply; } -JsonReply *JsonRpcClient::callAuthenticate(const QUuid &clientUuid, const QString &clientName, const QString &token, const QString &nonce) -{ - QVariantMap params; - params.insert("name", clientName); - params.insert("uuid", clientUuid.toString()); - params.insert("token", token); - if (!nonce.isEmpty()) params.insert("nonce", nonce); - - JsonReply *reply = new JsonReply(m_commandId, "Authentication", "Authenticate", params, this); - qCDebug(dcRemoteProxyClientJsonRpc()) << "Calling" << QString("%1.%2").arg(reply->nameSpace()).arg(reply->method()); - sendRequest(reply->requestMap()); - m_replies.insert(m_commandId, reply); - return reply; -} - JsonReply *JsonRpcClient::callRegisterServer(const QUuid &serverUuid, const QString &serverName) { QVariantMap params; diff --git a/libnymea-remoteproxyclient/proxyjsonrpcclient.h b/libnymea-remoteproxyclient/proxyjsonrpcclient.h index 115c859..af96d84 100644 --- a/libnymea-remoteproxyclient/proxyjsonrpcclient.h +++ b/libnymea-remoteproxyclient/proxyjsonrpcclient.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -50,9 +50,6 @@ public: // General JsonReply *callHello(); - // Proxy - JsonReply *callAuthenticate(const QUuid &clientUuid, const QString &clientName, const QString &token, const QString &nonce); - // Tunnel proxy JsonReply *callRegisterServer(const QUuid &serverUuid, const QString &serverName); JsonReply *callRegisterClient(const QUuid &clientUuid, const QString &clientName, const QUuid &serverUuid); diff --git a/libnymea-remoteproxyclient/remoteproxyconnection.cpp b/libnymea-remoteproxyclient/remoteproxyconnection.cpp deleted file mode 100644 index 44f018e..0000000 --- a/libnymea-remoteproxyclient/remoteproxyconnection.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU Lesser General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the terms of the GNU -* Lesser General Public License as published by the Free Software Foundation; version 3. -* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -* See the GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "proxyconnection.h" -#include "proxyjsonrpcclient.h" -#include "tcpsocketconnection.h" -#include "websocketconnection.h" -#include "remoteproxyconnection.h" - -Q_LOGGING_CATEGORY(dcRemoteProxyClientConnection, "RemoteProxyClientConnection") -Q_LOGGING_CATEGORY(dcRemoteProxyClientConnectionTraffic, "RemoteProxyClientConnectionTraffic") - -namespace remoteproxyclient { - -RemoteProxyConnection::RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, QObject *parent) : - QObject(parent), - m_clientUuid(clientUuid), - m_clientName(clientName) -{ - -} - -RemoteProxyConnection::RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, RemoteProxyConnection::ConnectionType connectionType, QObject *parent) : - QObject(parent), - m_clientUuid(clientUuid), - m_clientName(clientName), - m_connectionType(connectionType) -{ - -} - -RemoteProxyConnection::~RemoteProxyConnection() -{ - -} - -RemoteProxyConnection::State RemoteProxyConnection::state() const -{ - return m_state; -} - -QAbstractSocket::SocketError RemoteProxyConnection::error() const -{ - return m_error; -} - -void RemoteProxyConnection::ignoreSslErrors() -{ - m_connection->ignoreSslErrors(); -} - -void RemoteProxyConnection::ignoreSslErrors(const QList &errors) -{ - m_connection->ignoreSslErrors(errors); -} - -bool RemoteProxyConnection::isConnected() const -{ - return m_state == StateConnected - || m_state == StateInitializing - || m_state == StateReady - || m_state == StateAuthenticating - || m_state == StateAuthenticated - || m_state == StateRemoteConnected; -} - -bool RemoteProxyConnection::isAuthenticated() const -{ - return m_state == StateAuthenticated || m_state == StateRemoteConnected; -} - -bool RemoteProxyConnection::isRemoteConnected() const -{ - return m_state == StateRemoteConnected; -} - -RemoteProxyConnection::ConnectionType RemoteProxyConnection::connectionType() const -{ - return m_connectionType; -} - -QUrl RemoteProxyConnection::serverUrl() const -{ - return m_serverUrl; -} - -QString RemoteProxyConnection::serverName() const -{ - return m_serverName; -} - -QString RemoteProxyConnection::proxyServerName() const -{ - return m_proxyServerName; -} - -QString RemoteProxyConnection::proxyServerVersion() const -{ - return m_proxyServerVersion; -} - -QString RemoteProxyConnection::proxyServerApiVersion() const -{ - return m_proxyServerApiVersion; -} - -QString RemoteProxyConnection::tunnelPartnerName() const -{ - return m_tunnelPartnerName; -} - -QString RemoteProxyConnection::tunnelPartnerUuid() const -{ - return m_tunnelPartnerUuid; -} - -void RemoteProxyConnection::cleanUp() -{ - if (m_jsonClient) { - m_jsonClient->deleteLater(); - m_jsonClient = nullptr; - } - - if (m_connection) { - m_connection->deleteLater(); - m_connection = nullptr; - } - - m_serverName = QString(); - m_proxyServerName = QString(); - m_proxyServerVersion = QString(); - m_proxyServerApiVersion = QString(); - - setState(StateDisconnected); -} - -void RemoteProxyConnection::setState(RemoteProxyConnection::State state) -{ - if (m_state == state) - return; - - m_state = state; - qCDebug(dcRemoteProxyClientConnection()) << "State changed" << m_state; - emit stateChanged(m_state); - - switch (m_state) { - case StateConnected: - emit connected(); - break; - case StateDisconnected: - emit disconnected(); - break; - case StateReady: - emit ready(); - break; - case StateRemoteConnected: - emit remoteConnectionEstablished(); - break; - default: - break; - } - -} - -void RemoteProxyConnection::setError(QAbstractSocket::SocketError error) -{ - if (m_error == error) - return; - - m_error = error; - qCDebug(dcRemoteProxyClientConnection()) << "Error occurred" << m_error; - emit errorOccurred(m_error); -} - -void RemoteProxyConnection::onConnectionChanged(bool isConnected) -{ - if (isConnected) { - qCDebug(dcRemoteProxyClientConnection()) << "Connected to proxy server."; - setState(StateConnected); - - setState(StateInitializing); - JsonReply *reply = m_jsonClient->callHello(); - connect(reply, &JsonReply::finished, this, &RemoteProxyConnection::onHelloFinished); - } else { - qCDebug(dcRemoteProxyClientConnection()) << "Disconnected from proxy server."; - setState(StateDisconnected); - cleanUp(); - } -} - -void RemoteProxyConnection::onConnectionDataAvailable(const QByteArray &data) -{ - switch (m_state) { - case StateHostLookup: - case StateConnecting: - case StateConnected: - case StateInitializing: - case StateReady: - case StateAuthenticating: - case StateAuthenticated: - m_jsonClient->processData(data); - break; - case StateRemoteConnected: - // Remote data arrived - emit dataReady(data); - break; - default: - qCWarning(dcRemoteProxyClientConnection()) << "Unhandled: Data received" << data; - break; - } -} - -void RemoteProxyConnection::onConnectionSocketError(QAbstractSocket::SocketError error) -{ - setError(error); -} - -void RemoteProxyConnection::onConnectionStateChanged(QAbstractSocket::SocketState state) -{ - switch (state) { - case QAbstractSocket::UnconnectedState: - setState(StateDisconnected); - break; - case QAbstractSocket::HostLookupState: - setState(StateHostLookup); - break; - case QAbstractSocket::ConnectingState: - setState(StateConnecting); - break; - case QAbstractSocket::ConnectedState: - setState(StateConnected); - break; - case QAbstractSocket::ClosingState: - setState(StateDiconnecting); - break; - case QAbstractSocket::BoundState: - case QAbstractSocket::ListeningState: - break; - } -} - -void RemoteProxyConnection::onHelloFinished() -{ - JsonReply *reply = static_cast(sender()); - reply->deleteLater(); - - QVariantMap response = reply->response(); - qCDebug(dcRemoteProxyClientConnectionTraffic()) << "Hello response ready" << reply->commandId() << response; - - if (response.value("status").toString() != "success") { - qCWarning(dcRemoteProxyClientConnection()) << "Could not get initial information from proxy server."; - m_connection->disconnectServer(); - return; - } - - QVariantMap responseParams = response.value("params").toMap(); - - // TODO: verify success - - m_serverName = responseParams.value("server").toString(); - m_proxyServerName = responseParams.value("name").toString(); - m_proxyServerVersion = responseParams.value("version").toString(); - m_proxyServerApiVersion = responseParams.value("apiVersion").toString(); - - setState(StateReady); -} - -void RemoteProxyConnection::onAuthenticateFinished() -{ - JsonReply *reply = static_cast(sender()); - reply->deleteLater(); - - QVariantMap response = reply->response(); - qCDebug(dcRemoteProxyClientConnectionTraffic()) << "Authentication response ready" << reply->commandId() << response; - - QVariantMap responseParams = response.value("params").toMap(); - if (responseParams.value("authenticationError").toString() != "AuthenticationErrorNoError") { - qCWarning(dcRemoteProxyClientConnection()) << "Authentication request finished with error" << responseParams.value("authenticationError").toString(); - setError(QAbstractSocket::ProxyConnectionRefusedError); - m_connection->disconnectServer(); - } else { - qCDebug(dcRemoteProxyClientConnection()) << "Successfully authenticated."; - setState(StateAuthenticated); - emit authenticated(); - } -} - -void RemoteProxyConnection::onTunnelEstablished(const QString &clientName, const QString &clientUuid) -{ - qCDebug(dcRemoteProxyClientConnection()) << "Remote connection established successfully with" << clientName << clientUuid; - m_tunnelPartnerName = clientName; - m_tunnelPartnerUuid = clientUuid; - setState(StateRemoteConnected); -} - -bool RemoteProxyConnection::connectServer(const QUrl &url) -{ - m_serverUrl = url; - m_error = QAbstractSocket::UnknownSocketError; - - cleanUp(); - - switch (m_connectionType) { - case ConnectionTypeWebSocket: - qCDebug(dcRemoteProxyClientConnection()) << "Creating a web socket connection to" << url.toString(); - m_connection = qobject_cast(new WebSocketConnection(this)); - break; - case ConnectionTypeTcpSocket: - qCDebug(dcRemoteProxyClientConnection()) << "Creating a TCP socket connection to" << url.toString(); - m_connection = qobject_cast(new TcpSocketConnection(this)); - break; - } - - connect(m_connection, &ProxyConnection::connectedChanged, this, &RemoteProxyConnection::onConnectionChanged); - connect(m_connection, &ProxyConnection::dataReceived, this, &RemoteProxyConnection::onConnectionDataAvailable); - connect(m_connection, &ProxyConnection::errorOccurred, this, &RemoteProxyConnection::onConnectionSocketError); - connect(m_connection, &ProxyConnection::stateChanged, this, &RemoteProxyConnection::onConnectionStateChanged); - connect(m_connection, &ProxyConnection::sslErrors, this, &RemoteProxyConnection::sslErrors); - - m_jsonClient = new JsonRpcClient(m_connection, this); - connect(m_jsonClient, &JsonRpcClient::tunnelEstablished, this, &RemoteProxyConnection::onTunnelEstablished); - - qCDebug(dcRemoteProxyClientConnection()) << "Connecting to" << m_serverUrl.toString(); - m_connection->connectServer(m_serverUrl); - - return true; -} - -bool RemoteProxyConnection::authenticate(const QString &token, const QString &nonce) -{ - if (m_state != StateReady) { - qCWarning(dcRemoteProxyClientConnection()) << "Could not authenticate. The connection is not ready"; - return false; - } - - setState(StateAuthenticating); - - qCDebug(dcRemoteProxyClientConnection()) << "Start authentication using token" << token << nonce; - JsonReply *reply = m_jsonClient->callAuthenticate(m_clientUuid, m_clientName, token, nonce); - connect(reply, &JsonReply::finished, this, &RemoteProxyConnection::onAuthenticateFinished); - return true; -} - -void RemoteProxyConnection::disconnectServer() -{ - if (m_connection) { - qCDebug(dcRemoteProxyClientConnection()) << "Disconnecting from" << m_connection->serverUrl().toString(); - m_connection->disconnectServer(); - } -} - -bool RemoteProxyConnection::sendData(const QByteArray &data) -{ - if (!isConnected()) { - qCWarning(dcRemoteProxyClientConnection()) << "Could not send data. Not connected."; - return false; - } - - if (!isRemoteConnected()) { - qCWarning(dcRemoteProxyClientConnection()) << "Could not send data. The remote client is not connected yet."; - return false; - } - - m_connection->sendData(data); - return true; -} - - -} diff --git a/libnymea-remoteproxyclient/remoteproxyconnection.h b/libnymea-remoteproxyclient/remoteproxyconnection.h deleted file mode 100644 index 4347775..0000000 --- a/libnymea-remoteproxyclient/remoteproxyconnection.h +++ /dev/null @@ -1,164 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU Lesser General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the terms of the GNU -* Lesser General Public License as published by the Free Software Foundation; version 3. -* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -* See the GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef REMOTEPROXYCONNECTOR_H -#define REMOTEPROXYCONNECTOR_H - -#include -#include -#include -#include -#include -#include -#include - -Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyClientConnection) -Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyClientConnectionTraffic) - -namespace remoteproxyclient { - -class JsonRpcClient; -class ProxyConnection; - -class RemoteProxyConnection : public QObject -{ - Q_OBJECT -public: - enum ConnectionType { - ConnectionTypeWebSocket, - ConnectionTypeTcpSocket - }; - Q_ENUM(ConnectionType) - - enum State { - StateHostLookup, - StateConnecting, - StateConnected, - StateInitializing, - StateReady, - StateAuthenticating, - StateAuthenticated, - StateRemoteConnected, - StateDiconnecting, - StateDisconnected, - }; - Q_ENUM(State) - - explicit RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, QObject *parent = nullptr); - RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, ConnectionType connectionType, QObject *parent = nullptr); - ~RemoteProxyConnection(); - - RemoteProxyConnection::State state() const; - QAbstractSocket::SocketError error() const; - - void ignoreSslErrors(); - void ignoreSslErrors(const QList &errors); - - bool isConnected() const; - bool isAuthenticated() const; - bool isRemoteConnected() const; - - RemoteProxyConnection::ConnectionType connectionType() const; - - QUrl serverUrl() const; - - QString serverName() const; - QString proxyServerName() const; - QString proxyServerVersion() const; - QString proxyServerApiVersion() const; - - QString tunnelPartnerName() const; - QString tunnelPartnerUuid() const; - -private: - QUuid m_clientUuid; - QString m_clientName; - ConnectionType m_connectionType = ConnectionTypeTcpSocket; - - QUrl m_serverUrl; - - State m_state = StateDisconnected; - QAbstractSocket::SocketError m_error = QAbstractSocket::UnknownSocketError; - - bool m_insecureConnection = false; - bool m_remoteConnected = false; - - JsonRpcClient *m_jsonClient = nullptr; - ProxyConnection *m_connection = nullptr; - - // Server information - QString m_serverName; - QString m_proxyServerName; - QString m_proxyServerVersion; - QString m_proxyServerApiVersion; - - // Tunnel - QString m_tunnelPartnerName; - QString m_tunnelPartnerUuid; - - void cleanUp(); - - void setState(State state); - void setError(QAbstractSocket::SocketError error); - -signals: - void connected(); - void ready(); - void authenticated(); - void remoteConnectionEstablished(); - void disconnected(); - - void stateChanged(RemoteProxyConnection::State state); - void errorOccurred(QAbstractSocket::SocketError error); - void sslErrors(const QList &errors); - - void dataReady(const QByteArray &data); - -private slots: - void onConnectionChanged(bool isConnected); - void onConnectionDataAvailable(const QByteArray &data); - void onConnectionSocketError(QAbstractSocket::SocketError error); - void onConnectionStateChanged(QAbstractSocket::SocketState state); - - void onHelloFinished(); - void onAuthenticateFinished(); - void onTunnelEstablished(const QString &clientName, const QString &clientUuid); - -public slots: - bool connectServer(const QUrl &url); - bool authenticate(const QString &token, const QString &nonce = QString()); - void disconnectServer(); - bool sendData(const QByteArray &data); - -}; - -} - -Q_DECLARE_METATYPE(remoteproxyclient::RemoteProxyConnection::State); -Q_DECLARE_METATYPE(remoteproxyclient::RemoteProxyConnection::ConnectionType); - -#endif // REMOTEPROXYCONNECTOR_H diff --git a/libnymea-remoteproxyclient/tcpsocketconnection.cpp b/libnymea-remoteproxyclient/tcpsocketconnection.cpp index e4fcd93..75ef006 100644 --- a/libnymea-remoteproxyclient/tcpsocketconnection.cpp +++ b/libnymea-remoteproxyclient/tcpsocketconnection.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxyclient/tcpsocketconnection.h b/libnymea-remoteproxyclient/tcpsocketconnection.h index 232d45c..cad1adc 100644 --- a/libnymea-remoteproxyclient/tcpsocketconnection.h +++ b/libnymea-remoteproxyclient/tcpsocketconnection.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxyclient/websocketconnection.cpp b/libnymea-remoteproxyclient/websocketconnection.cpp index da33dba..9e17a2c 100644 --- a/libnymea-remoteproxyclient/websocketconnection.cpp +++ b/libnymea-remoteproxyclient/websocketconnection.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/libnymea-remoteproxyclient/websocketconnection.h b/libnymea-remoteproxyclient/websocketconnection.h index 252d0d9..e0bf59b 100644 --- a/libnymea-remoteproxyclient/websocketconnection.h +++ b/libnymea-remoteproxyclient/websocketconnection.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/monitor/monitor.cpp b/monitor/monitor.cpp index 156de5b..e5cab92 100644 --- a/monitor/monitor.cpp +++ b/monitor/monitor.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/monitor/monitor.h b/monitor/monitor.h index aa31343..4edd15d 100644 --- a/monitor/monitor.h +++ b/monitor/monitor.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/monitor/monitorclient.cpp b/monitor/monitorclient.cpp index 0ca0a1b..1e735e9 100644 --- a/monitor/monitorclient.cpp +++ b/monitor/monitorclient.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/monitor/monitorclient.h b/monitor/monitorclient.h index b5800d2..b6f60b1 100644 --- a/monitor/monitorclient.h +++ b/monitor/monitorclient.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/monitor/terminalwindow.cpp b/monitor/terminalwindow.cpp index c959abd..f6836a3 100644 --- a/monitor/terminalwindow.cpp +++ b/monitor/terminalwindow.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -37,7 +37,7 @@ TerminalWindow::TerminalWindow(QObject *parent) : QObject(parent) { // Init view tabs - m_tabs << ViewClients << ViewTunnels << ViewTunnelProxy; + m_tabs << ViewTunnelProxy; // Create main window m_mainWindow = initscr(); @@ -160,34 +160,6 @@ void TerminalWindow::paintHeader() QString windowName; QString headerString; switch (m_view) { - case ViewClients: - windowName = "-- Clients --"; - headerString = QString(" Server: %1 (%2) | API: %3 | Clients: %4, %5 | Tunnels: %6, %7 | %8 | %9 | %10") - .arg(m_dataMap.value("serverName", "-").toString()) - .arg(m_dataMap.value("serverVersion", "-").toString()) - .arg(m_dataMap.value("apiVersion", "-").toString()) - .arg(m_dataMap.value("proxyStatistic").toMap().value("clientCount", 0).toInt()) - .arg(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalClientCount").toInt()) - .arg(m_dataMap.value("proxyStatistic").toMap().value("tunnelCount", 0).toInt()) - .arg(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTunnelCount").toInt()) - .arg(Utils::humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("troughput", 0).toInt()) + " / s", - 13) - .arg(Utils::humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTraffic").toInt()), - 10) - .arg(windowName); - break; - case ViewTunnels: - windowName = "-- Tunnels --"; - headerString = QString(" Server: %1 (%2) | API: %3 | Clients: %4, %5 | Tunnels: %6, %7 | %8 | %9 | %10") - .arg(m_dataMap.value("serverName", "-").toString()) - .arg(m_dataMap.value("serverVersion", "-").toString()) - .arg(m_dataMap.value("apiVersion", "-").toString()) - .arg(m_dataMap.value("proxyStatistic").toMap().value("clientCount", 0).toInt()) - .arg(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalClientCount").toInt()) - .arg(m_dataMap.value("proxyStatistic").toMap().value("tunnelCount", 0).toInt()) - .arg(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTunnelCount").toInt()) - .arg(Utils::humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("troughput", 0).toInt()) + " / s", - 13) - .arg(Utils::humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTraffic").toInt()), - 10) - .arg(windowName); - break; case ViewTunnelProxy: windowName = "-- TunnelProxy --"; headerString = QString(" Server: %1 (%2) | API: %3 | Total: %4 | Servers: %5 | Clients: %6 | %7 | %8") @@ -366,12 +338,6 @@ void TerminalWindow::eventLoop() // Refresh content window switch (m_view) { - case ViewClients: - paintContentClients(); - break; - case ViewTunnels: - paintContentTunnels(); - break; case ViewTunnelProxy: paintContentTunnelProxy(); break; diff --git a/monitor/terminalwindow.h b/monitor/terminalwindow.h index 42b43f5..2bb4bac 100644 --- a/monitor/terminalwindow.h +++ b/monitor/terminalwindow.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -40,8 +40,6 @@ class TerminalWindow : public QObject public: enum View { - ViewClients, - ViewTunnels, ViewTunnelProxy }; Q_ENUM(View) diff --git a/nymea-remoteproxy-logging.conf b/nymea-remoteproxy-logging.conf index d1a75d0..d3205d1 100644 --- a/nymea-remoteproxy-logging.conf +++ b/nymea-remoteproxy-logging.conf @@ -2,8 +2,7 @@ *.debug=false Application.debug=true Engine.debug=true -Tunnel.debug=true -JsonRpc.debug=true +JsonRpc.debug=false JsonRpcTraffic.debug=false WebSocketServer.debug=true WebSocketServerTraffic.debug=false @@ -11,12 +10,6 @@ TcpSocketServer.debug=true TcpSocketServerTraffic.debug=false UnixSocketServer.debug=true UnixSocketServerTraffic.debug=false -Authentication.debug=true -AuthenticationProcess.debug=false -ProxyServer.debug=true -ProxyServerTraffic.debug=false TunnelProxyServer.debug=true TunnelProxyServerTraffic.debug=false MonitorServer.debug=true -AwsCredentialsProvider.debug=false -AwsCredentialsProviderTraffic.debug=false diff --git a/nymea-remoteproxy.conf b/nymea-remoteproxy.conf index a2594f1..87e8ada 100644 --- a/nymea-remoteproxy.conf +++ b/nymea-remoteproxy.conf @@ -5,14 +5,7 @@ logFile=/var/log/nymea-remoteproxy.log logEngineEnabled=false monitorSocket=/tmp/nymea-remoteproxy-monitor.sock jsonRpcTimeout=10000 -authenticationTimeout=8000 inactiveTimeout=8000 -aloneTimeout=8000 - -[AWS] -region=eu-west-1 -authorizerLambdaFunction=system-services-authorizer-dev-checkToken -awsCredentialsUrl=http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2-Remote-Connection-Proxy-Role [SSL] enabled=false @@ -20,15 +13,7 @@ certificate=/etc/ssl/certs/ssl-cert-snakeoil.pem certificateKey=/etc/ssl/private/ssl-cert-snakeoil.key certificateChain= -[WebSocketServer] -host=127.0.0.1 -port=443 - -[TcpServer] -host=127.0.0.1 -port=80 - -[UnixSocketServer] +[UnixSocketServerTunnelProxy] unixSocketFileName=/run/nymea-remoteproxy.socket [WebSocketServerTunnelProxy] diff --git a/nymea-remoteproxy.pro b/nymea-remoteproxy.pro index 7350add..e6bace9 100644 --- a/nymea-remoteproxy.pro +++ b/nymea-remoteproxy.pro @@ -3,7 +3,7 @@ include(nymea-remoteproxy.pri) # Define versions SERVER_NAME=nymea-remoteproxy API_VERSION_MAJOR=0 -API_VERSION_MINOR=5 +API_VERSION_MINOR=6 COPYRIGHT_YEAR=2023 # Parse and export SERVER_VERSION @@ -12,18 +12,13 @@ SERVER_VERSION=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"') QMAKE_SUBSTITUTES += version.h.in TEMPLATE=subdirs -SUBDIRS += server client tunnelclient libnymea-remoteproxy libnymea-remoteproxyclient +SUBDIRS += server tunnelclient monitor libnymea-remoteproxy libnymea-remoteproxyclient !disabletests { SUBDIRS += tests } -!disablemonitor { - SUBDIRS += monitor -} - server.depends = libnymea-remoteproxy -client.depends = libnymea-remoteproxyclient tunnelclient.depends = libnymea-remoteproxyclient tests.depends = libnymea-remoteproxy libnymea-remoteproxyclient @@ -46,6 +41,3 @@ ccache { message("Building with ccache support") } -disablemonitor { - message("Building without the monitor") -} diff --git a/server/main.cpp b/server/main.cpp index 690da03..2178bd3 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -48,8 +48,6 @@ #include "loggingcategories.h" #include "proxyconfiguration.h" #include "remoteproxyserverapplication.h" -#include "authentication/aws/awsauthenticator.h" -#include "authentication/dummy/dummyauthenticator.h" #include "../version.h" @@ -114,8 +112,7 @@ int main(int argc, char *argv[]) QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); - parser.setApplicationDescription(QString("\nThe nymea remote proxy server. This server allowes nymea-cloud users and " - "registered nymea deamons to establish a tunnel connection.\n\n" + parser.setApplicationDescription(QString("\nThe nymea remote proxy server. This server allowes nymea clients to establish a tunnel connection to nymea deamons.\n\n" "Version: %1\n" "API version: %2\n\n" "Copyright %3 %4 nymea GmbH \n") @@ -128,13 +125,6 @@ int main(int argc, char *argv[]) "logfile", "/var/log/nymea-remoteproxy.log"); parser.addOption(logfileOption); - QCommandLineOption developmentOption(QStringList() << "d" << "development", "Enable the development mode. This enabled the server " - "assumes there are static AWS credentials provided to aws-cli."); - parser.addOption(developmentOption); - - QCommandLineOption mockAuthenticatorOption(QStringList() << "m" << "mock-authenticator", "Start the server using a mock authenticator which returns always true."); - parser.addOption(mockAuthenticatorOption); - QCommandLineOption configOption(QStringList() << "c" <<"configuration", "The path to the proxy server configuration file. The default is " + configFile, "configuration"); configOption.setDefaultValue(configFile); parser.addOption(configOption); @@ -152,7 +142,7 @@ int main(int argc, char *argv[]) qCDebug(dcApplication()) << "Loading configuration file from" << configFile; if (!configuration->loadConfiguration(parser.value(configOption))) { qCCritical(dcApplication()) << "Invalid configuration file passed" << parser.value(configOption); - exit(-1); + exit(EXIT_FAILURE); } if (parser.isSet(logfileOption)) { @@ -167,31 +157,19 @@ int main(int argc, char *argv[]) QDir dir(fi.absolutePath()); if (!dir.exists() && !dir.mkpath(dir.absolutePath())) { qCWarning(dcApplication()) << "Error opening log file" << configuration->logFileName(); - exit(-1); + exit(EXIT_FAILURE); } s_logFile.setFileName(configuration->logFileName()); if (!s_logFile.open(QFile::WriteOnly | QFile::Append)) { qWarning() << "Error opening log file" << configuration->logFileName(); - exit(-1); + exit(EXIT_FAILURE); } } - // Verify webserver configuration - if (configuration->webSocketServerProxyHost().isNull()) { - qCCritical(dcApplication()) << "Invalid web socket host address passed."; - exit(-1); - } - - // Verify tcp server configuration - if (configuration->tcpServerHost().isNull()) { - qCCritical(dcApplication()) << "Invalid TCP server host address passed."; - exit(-1); - } - // Verify SSL configuration if (configuration->sslEnabled() && configuration->sslConfiguration().isNull()) { qCCritical(dcApplication()) << "SSL is enabled but no SSL configuration specified."; - exit(-1); + exit(EXIT_FAILURE); } else { qCDebug(dcApplication()) << "Using SSL version:" << QSslSocket::sslLibraryVersionString(); } @@ -199,28 +177,12 @@ int main(int argc, char *argv[]) qCDebug(dcApplication()) << "=========================================================="; qCDebug(dcApplication()) << "Starting" << application.applicationName() << application.applicationVersion(); qCDebug(dcApplication()) << "=========================================================="; - if (parser.isSet(developmentOption)) { - qCWarning(dcApplication()) << "##########################################################"; - qCWarning(dcApplication()) << "# DEVELOPMENT MODE #"; - qCWarning(dcApplication()) << "##########################################################"; - } if (s_loggingEnabled) qCDebug(dcApplication()) << "Logging enabled. Writing logs to" << s_logFile.fileName(); - Authenticator *authenticator = nullptr; - if (parser.isSet(mockAuthenticatorOption)) { - authenticator = qobject_cast(new DummyAuthenticator(nullptr)); - } else { - if (configuration->proxyEnabled()) { - // Create default authenticator - authenticator = qobject_cast(new AwsAuthenticator(configuration->awsCredentialsUrl(), nullptr)); - } - } // Configure and start the engines - Engine::instance()->setAuthenticator(authenticator); - Engine::instance()->setDeveloperModeEnabled(parser.isSet(developmentOption)); Engine::instance()->start(configuration); return application.exec(); diff --git a/server/remoteproxyserverapplication.cpp b/server/remoteproxyserverapplication.cpp index 28d12a3..db50329 100644 --- a/server/remoteproxyserverapplication.cpp +++ b/server/remoteproxyserverapplication.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/server/remoteproxyserverapplication.h b/server/remoteproxyserverapplication.h index e00f53e..795c4a0 100644 --- a/server/remoteproxyserverapplication.h +++ b/server/remoteproxyserverapplication.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/tests/resources/test-configuration-chain.conf b/tests/resources/test-configuration-chain.conf index e6406dd..cdd55f3 100644 --- a/tests/resources/test-configuration-chain.conf +++ b/tests/resources/test-configuration-chain.conf @@ -9,15 +9,7 @@ certificate=:/test-certificate.crt certificateKey=:/test-certificate.key certificateChain=:/test-certificate.crt -[WebSocketServer] -host=127.0.0.1 -port=1212 - -[TcpServer] -host=127.0.0.1 -port=1213 - -[UnixSocketServer] +[UnixSocketServerTunnelProxy] unixSocketFileName=/tmp/nymea-remoteproxy.socket [WebSocketServerTunnelProxy] diff --git a/tests/resources/test-configuration-faulty-certificate.conf b/tests/resources/test-configuration-faulty-certificate.conf index e58af46..460a769 100644 --- a/tests/resources/test-configuration-faulty-certificate.conf +++ b/tests/resources/test-configuration-faulty-certificate.conf @@ -9,15 +9,7 @@ certificate=:/not-existing-test-certificate.crt certificateKey=:/test-certificate.key certificateChain= -[WebSocketServer] -host=127.0.0.1 -port=1212 - -[TcpServer] -host=127.0.0.1 -port=1213 - -[UnixSocketServer] +[UnixSocketServerTunnelProxy] unixSocketFileName=/tmp/nymea-remoteproxy.socket [WebSocketServerTunnelProxy] diff --git a/tests/resources/test-configuration-faulty-chain.conf b/tests/resources/test-configuration-faulty-chain.conf index c71da10..11bbae6 100644 --- a/tests/resources/test-configuration-faulty-chain.conf +++ b/tests/resources/test-configuration-faulty-chain.conf @@ -9,15 +9,7 @@ certificate=:/test-certificate.crt certificateKey=:/test-certificate.key certificateChain=:/not-existing-test-certificate.crt -[WebSocketServer] -host=127.0.0.1 -port=1212 - -[TcpServer] -host=127.0.0.1 -port=1213 - -[UnixSocketServer] +[UnixSocketServerTunnelProxy] unixSocketFileName=/tmp/nymea-remoteproxy.socket [WebSocketServerTunnelProxy] diff --git a/tests/resources/test-configuration-faulty-key.conf b/tests/resources/test-configuration-faulty-key.conf index 5fca17e..8e9695b 100644 --- a/tests/resources/test-configuration-faulty-key.conf +++ b/tests/resources/test-configuration-faulty-key.conf @@ -9,15 +9,7 @@ certificate=:/test-certificate.crt certificateKey=:/not-existing-test-certificate.key certificateChain= -[WebSocketServer] -host=127.0.0.1 -port=1212 - -[TcpServer] -host=127.0.0.1 -port=1213 - -[UnixSocketServer] +[UnixSocketServerTunnelProxy] unixSocketFileName=/tmp/nymea-remoteproxy.socket [WebSocketServerTunnelProxy] diff --git a/tests/resources/test-configuration.conf b/tests/resources/test-configuration.conf index 437604f..638e28c 100644 --- a/tests/resources/test-configuration.conf +++ b/tests/resources/test-configuration.conf @@ -4,24 +4,14 @@ writeLogs=false logFile=/var/log/nymea-remoteproxy.log monitorSocket=/tmp/nymea-remoteproxy-test.sock jsonRpcTimeout=10000 -authenticationTimeout=10000 inactiveTimeout=5000 -aloneTimeout=10000 [SSL] certificate=:/test-certificate.crt certificateKey=:/test-certificate.key certificateChain= -[WebSocketServer] -host=127.0.0.1 -port=1212 - -[TcpServer] -host=127.0.0.1 -port=1213 - -[UnixSocketServer] +[UnixSocketServerTunnelProxy] unixSocketFileName=/tmp/nymea-remoteproxy.socket [WebSocketServerTunnelProxy] diff --git a/tests/test-proxy/remoteproxytestsproxy.cpp b/tests/test-proxy/remoteproxytestsproxy.cpp deleted file mode 100644 index b57fa31..0000000 --- a/tests/test-proxy/remoteproxytestsproxy.cpp +++ /dev/null @@ -1,1435 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "remoteproxytestsproxy.h" - -#include "engine.h" -#include "loggingcategories.h" -#include "remoteproxyconnection.h" -#include "../../version.h" - -#include -#include -#include -#include -#include - -RemoteProxyTestsProxy::RemoteProxyTestsProxy(QObject *parent) : - BaseTest(parent) -{ - -} - -void RemoteProxyTestsProxy::startStopServer() -{ - resetDebugCategories(); - addDebugCategory("ProxyServer.debug=true"); - addDebugCategory("Engine.debug=true"); - addDebugCategory("JsonRpc.debug=true"); - addDebugCategory("TcpSocketServer.debug=true"); - addDebugCategory("WebSocketServer.debug=true"); - - startServer(); - stopServer(); - - resetDebugCategories(); -} - -void RemoteProxyTestsProxy::dummyAuthenticator() -{ - resetDebugCategories(); - addDebugCategory("ProxyServer.debug=true"); - - cleanUpEngine(); - - m_configuration = new ProxyConfiguration(this); - loadConfiguration(":/test-configuration.conf"); - - m_dummyAuthenticator = new DummyAuthenticator(this); - m_authenticator = qobject_cast(m_dummyAuthenticator); - - // Start proxy webserver - Engine::instance()->setAuthenticator(m_dummyAuthenticator); - QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged); - Engine::instance()->start(m_configuration); - runningSpy.wait(); - - QVERIFY(runningSpy.count() == 1); - - // Make sure the server is running - QVERIFY(Engine::instance()->running()); - QVERIFY(Engine::instance()->webSocketServerProxy()->running()); - QVERIFY(Engine::instance()->unixSocketServerProxy()->running()); - QVERIFY(Engine::instance()->proxyServer()->running()); - - // Create request - QVariantMap params; - params.insert("uuid", QUuid::createUuid().toString()); - params.insert("name", "test"); - params.insert("token", "foobar"); - - QVariant response = invokeWebSocketProxyApiCall("Authentication.Authenticate", params); - qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - verifyAuthenticationError(response); - - cleanUpEngine(); -} - - -void RemoteProxyTestsProxy::monitorServer() -{ - // Start the server - startServer(); - - QVERIFY(Engine::instance()->monitorServer()->running()); - - // Create a tunnel - // Configure mock authenticator - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - QString nameConnectionOne = "Test client one"; - QUuid uuidConnectionOne = QUuid::createUuid(); - - QString nameConnectionTwo = "Test client two"; - QUuid uuidConnectionTwo = QUuid::createUuid(); - - QByteArray dataOne = "Hello from client one :-)"; - QByteArray dataTwo = "Hello from client two :-)"; - - // Create two connection - RemoteProxyConnection *connectionOne = new RemoteProxyConnection(uuidConnectionOne, nameConnectionOne, this); - connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(uuidConnectionTwo, nameConnectionTwo, this); - connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrlProxyTcp)); - if (connectionOneReadySpy.count() < 1) connectionOneReadySpy.wait(); - QVERIFY(connectionOneReadySpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - - // Connect two - QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrlProxyTcp)); - if (connectionTwoReadySpy.count() < 1) connectionTwoReadySpy.wait(); - QVERIFY(connectionTwoReadySpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - - // Authenticate one - QSignalSpy remoteConnectionEstablishedOne(connectionOne, &RemoteProxyConnection::remoteConnectionEstablished); - QSignalSpy connectionOneAuthenticatedSpy(connectionOne, &RemoteProxyConnection::authenticated); - QVERIFY(connectionOne->authenticate(m_testToken)); - if (connectionOneAuthenticatedSpy.count() < 1) connectionOneAuthenticatedSpy.wait(); - QVERIFY(connectionOneAuthenticatedSpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - QVERIFY(connectionOne->isAuthenticated()); - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateAuthenticated); - - // Authenticate two - QSignalSpy remoteConnectionEstablishedTwo(connectionTwo, &RemoteProxyConnection::remoteConnectionEstablished); - QSignalSpy connectionTwoAuthenticatedSpy(connectionTwo, &RemoteProxyConnection::authenticated); - QVERIFY(connectionTwo->authenticate(m_testToken)); - if (connectionTwoAuthenticatedSpy.count() < 1) connectionTwoAuthenticatedSpy.wait(); - QVERIFY(connectionTwoAuthenticatedSpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - QVERIFY(connectionTwo->isAuthenticated()); - - // Wait for both to be connected - if (remoteConnectionEstablishedOne.count() < 1) - remoteConnectionEstablishedOne.wait(); - - if (remoteConnectionEstablishedTwo.count() < 1) - remoteConnectionEstablishedTwo.wait(); - - QVERIFY(remoteConnectionEstablishedOne.count() == 1); - QVERIFY(remoteConnectionEstablishedTwo.count() == 1); - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected); - QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected); - - QCOMPARE(connectionOne->tunnelPartnerName(), nameConnectionTwo); - QCOMPARE(QUuid(connectionOne->tunnelPartnerUuid()), uuidConnectionTwo); - QCOMPARE(connectionTwo->tunnelPartnerName(), nameConnectionOne); - QCOMPARE(QUuid(connectionTwo->tunnelPartnerUuid()), uuidConnectionOne); - - // Get monitor data - QLocalSocket *monitor = new QLocalSocket(this); - QSignalSpy connectedSpy(monitor, &QLocalSocket::connected); - monitor->connectToServer(m_configuration->monitorSocketFileName()); - if (connectedSpy.count() < 1) connectedSpy.wait(); - QVERIFY(connectedSpy.count() == 1); - - QSignalSpy dataSpy(monitor, &QLocalSocket::readyRead); - if (dataSpy.count() < 1) dataSpy.wait(); - QVERIFY(dataSpy.count() == 1); - QByteArray data = monitor->readAll(); - qDebug() << data; - - // TODO: verify monitor data - - QSignalSpy disconnectedSpy(monitor, &QLocalSocket::connected); - monitor->disconnectFromServer(); - if (disconnectedSpy.count() < 1) disconnectedSpy.wait(); - - // Clean up - monitor->deleteLater(); - connectionOne->deleteLater(); - connectionTwo->deleteLater(); - stopServer(); -} - -void RemoteProxyTestsProxy::configuration_data() -{ - QTest::addColumn("fileName"); - QTest::addColumn("success"); - - QTest::newRow("valid configuration") << ":/test-configuration.conf" << true; - QTest::newRow("valid configuration chain") << ":/test-configuration-chain.conf" << true; - QTest::newRow("faulty filename") << ":/not-exisitng-test-configuration.conf" << false; - QTest::newRow("faulty certificate") << ":/test-configuration-faulty-certificate.conf" << false; - QTest::newRow("faulty key") << ":/test-configuration-faulty-key.conf" << false; - QTest::newRow("faulty chain") << ":/test-configuration-faulty-chain.conf" << false; -} - -void RemoteProxyTestsProxy::configuration() -{ - QFETCH(QString, fileName); - QFETCH(bool, success); - - ProxyConfiguration configuration; - QCOMPARE(configuration.loadConfiguration(fileName), success); -} - -void RemoteProxyTestsProxy::serverPortBlocked() -{ - cleanUpEngine(); - - m_configuration = new ProxyConfiguration(this); - loadConfiguration(":/test-configuration.conf"); - - m_mockAuthenticator = new MockAuthenticator(this); - m_authenticator = qobject_cast(m_mockAuthenticator); - - // Create a dummy server which blocks the port - QWebSocketServer dummyServer("dummy-server", QWebSocketServer::NonSecureMode); - QVERIFY(dummyServer.listen(QHostAddress::LocalHost, m_configuration->webSocketServerProxyPort())); - - // Start proxy webserver - QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged); - Engine::instance()->setAuthenticator(m_authenticator); - Engine::instance()->start(m_configuration); - runningSpy.wait(); - QVERIFY(runningSpy.count() == 1); - - // Make sure the server is not running - QVERIFY(Engine::instance()->running()); - - // Make sure the websocket server is not running - QVERIFY(!Engine::instance()->webSocketServerProxy()->running()); - - QSignalSpy closedSpy(&dummyServer, &QWebSocketServer::closed); - dummyServer.close(); - closedSpy.wait(); - QVERIFY(closedSpy.count() == 1); - - // Try again - startServer(); - - // Clean up - stopServer(); - - // Do the same with the tcp server - cleanUpEngine(); - - m_configuration = new ProxyConfiguration(this); - loadConfiguration(":/test-configuration.conf"); - - m_mockAuthenticator = new MockAuthenticator(this); - m_authenticator = qobject_cast(m_mockAuthenticator); - - // Create a dummy server which blocks the port - QTcpServer *tcpDummyServer = new QTcpServer(this); - QVERIFY(tcpDummyServer->listen(QHostAddress::LocalHost, m_configuration->tcpServerPort())); - - // Start proxy webserver - QSignalSpy runningSpy2(Engine::instance(), &Engine::runningChanged); - Engine::instance()->setAuthenticator(m_authenticator); - Engine::instance()->start(m_configuration); - runningSpy2.wait(); - QVERIFY(runningSpy2.count() == 1); - - // Make sure the engine is running - QVERIFY(Engine::instance()->running()); - - // Make sure the TCP server is not running - QVERIFY(!Engine::instance()->tcpSocketServerProxy()->running()); - - tcpDummyServer->close(); - delete tcpDummyServer; - - // Try again - startServer(); - - // Make sure the TCP server is not running - QVERIFY(Engine::instance()->webSocketServerProxy()->running()); - QVERIFY(Engine::instance()->tcpSocketServerProxy()->running()); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::websocketBinaryData() -{ - // Start the server - startServer(); - - QWebSocket *client = new QWebSocket("bad-client", QWebSocketProtocol::Version13); - connect(client, &QWebSocket::sslErrors, this, &BaseTest::sslErrors); - QSignalSpy spyConnection(client, SIGNAL(connected())); - client->open(Engine::instance()->webSocketServerProxy()->serverUrl()); - spyConnection.wait(); - - // Send binary data and make sure the server disconnects this socket - QSignalSpy spyDisconnected(client, SIGNAL(disconnected())); - client->sendBinaryMessage("trying to upload stuff...stuff...more stuff... other stuff"); - spyConnection.wait(1000); - QVERIFY(spyConnection.count() == 1); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::websocketPing() -{ - // Start the server - startServer(); - - QWebSocket *client = new QWebSocket("bad-client", QWebSocketProtocol::Version13); - connect(client, &QWebSocket::sslErrors, this, &BaseTest::sslErrors); - QSignalSpy spyConnection(client, SIGNAL(connected())); - client->open(Engine::instance()->webSocketServerProxy()->serverUrl()); - spyConnection.wait(); - QVERIFY(spyConnection.count() == 1); - - QByteArray pingMessage = QByteArray("ping!"); - QSignalSpy pongSpy(client, &QWebSocket::pong); - client->ping(pingMessage); - pongSpy.wait(); - QVERIFY(pongSpy.count() == 1); - qDebug() << pongSpy.at(0).at(0) << pongSpy.at(0).at(1); - - QVERIFY(pongSpy.at(0).at(1).toByteArray() == pingMessage); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::apiBasicCallsTcp_data() -{ - QTest::addColumn("data"); - QTest::addColumn("responseId"); - QTest::addColumn("responseStatus"); - - QTest::newRow("valid call") << QByteArray("{\"id\":42, \"method\":\"RemoteProxy.Hello\"}") << 42 << "success"; - QTest::newRow("missing id") << QByteArray("{\"method\":\"RemoteProxy.Hello\"}") << -1 << "error"; - QTest::newRow("missing method") << QByteArray("{\"id\":42}") << 42 << "error"; - //QTest::newRow("invalid json") << QByteArray("{\"id\":42, \"method\":\"RemoteProx") << -1 << "error"; - QTest::newRow("invalid function") << QByteArray("{\"id\":42, \"method\":\"RemoteProxy.Explode\"}") << 42 << "error"; - QTest::newRow("invalid namespace") << QByteArray("{\"id\":42, \"method\":\"ProxyRemote.Hello\"}") << 42 << "error"; - QTest::newRow("missing dot") << QByteArray("{\"id\":42, \"method\":\"RemoteProxyHello\"}") << 42 << "error"; - QTest::newRow("invalid params") << QByteArray("{\"id\":42, \"method\":\"RemoteProxy.Hello\", \"params\":{\"törööö\":\"chooo-chooo\"}}") << 42 << "error"; - QTest::newRow("invalid authentication params") << QByteArray("{\"id\":42, \"method\":\"Authentication.Authenticate\", \"params\":{\"your\":\"mamma\"}}") << 42 << "error"; -} - -void RemoteProxyTestsProxy::apiBasicCallsTcp() -{ - QFETCH(QByteArray, data); - QFETCH(int, responseId); - QFETCH(QString, responseStatus); - - // Start the server - startServer(); - - QVariant response = injectTcpSocketProxyData(data); - QVERIFY(!response.isNull()); - - qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - - QCOMPARE(response.toMap().value("id").toInt(), responseId); - QCOMPARE(response.toMap().value("status").toString(), responseStatus); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::getIntrospect() -{ - // Start the server - startServer(); - - QVariantMap response; - - // WebSocket - response = invokeWebSocketProxyApiCall("RemoteProxy.Introspect").toMap(); - //qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - QVERIFY(!response.isEmpty()); - QVERIFY(response.value("status").toString() == "success"); - QVERIFY(response.value("params").toMap().contains("methods")); - QVERIFY(response.value("params").toMap().contains("notifications")); - QVERIFY(response.value("params").toMap().contains("types")); - - // Tcp - response.clear(); - response = invokeTcpSocketProxyApiCall("RemoteProxy.Introspect").toMap(); - //qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - - QVERIFY(!response.isEmpty()); - QVERIFY(response.value("status").toString() == "success"); - QVERIFY(response.value("params").toMap().contains("methods")); - QVERIFY(response.value("params").toMap().contains("notifications")); - QVERIFY(response.value("params").toMap().contains("types")); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::getHello() -{ - // Start the server - startServer(); - QVariantMap response; - - // WebSocket - response = invokeWebSocketProxyApiCall("RemoteProxy.Hello").toMap(); - qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - - // Verify data - QVERIFY(!response.isEmpty()); - QCOMPARE(response.value("params").toMap().value("name").toString(), Engine::instance()->configuration()->serverName()); - QCOMPARE(response.value("params").toMap().value("server").toString(), QString(SERVER_NAME_STRING)); - QCOMPARE(response.value("params").toMap().value("version").toString(), QString(SERVER_VERSION_STRING)); - QCOMPARE(response.value("params").toMap().value("apiVersion").toString(), QString(API_VERSION_STRING)); - - // TCP - response.clear(); - response = invokeTcpSocketProxyApiCall("RemoteProxy.Hello").toMap(); - qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - - // Verify data - QVERIFY(!response.isEmpty()); - QCOMPARE(response.value("params").toMap().value("name").toString(), Engine::instance()->configuration()->serverName()); - QCOMPARE(response.value("params").toMap().value("server").toString(), QString(SERVER_NAME_STRING)); - QCOMPARE(response.value("params").toMap().value("version").toString(), QString(SERVER_VERSION_STRING)); - QCOMPARE(response.value("params").toMap().value("apiVersion").toString(), QString(API_VERSION_STRING)); - - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::apiBasicCalls_data() -{ - QTest::addColumn("data"); - QTest::addColumn("responseId"); - QTest::addColumn("responseStatus"); - - QTest::newRow("valid call") << QByteArray("{\"id\":42, \"method\":\"RemoteProxy.Hello\"}") << 42 << "success"; - QTest::newRow("missing id") << QByteArray("{\"method\":\"RemoteProxy.Hello\"}") << -1 << "error"; - QTest::newRow("missing method") << QByteArray("{\"id\":42}") << 42 << "error"; - QTest::newRow("invalid json") << QByteArray("{\"id\":42, \"method\":\"RemoteProx}") << -1 << "error"; - QTest::newRow("invalid function") << QByteArray("{\"id\":42, \"method\":\"RemoteProxy.Explode\"}") << 42 << "error"; - QTest::newRow("invalid namespace") << QByteArray("{\"id\":42, \"method\":\"ProxyRemote.Hello\"}") << 42 << "error"; - QTest::newRow("missing dot") << QByteArray("{\"id\":42, \"method\":\"RemoteProxyHello\"}") << 42 << "error"; - QTest::newRow("invalid params") << QByteArray("{\"id\":42, \"method\":\"RemoteProxy.Hello\", \"params\":{\"törööö\":\"chooo-chooo\"}}") << 42 << "error"; - QTest::newRow("invalid authentication params") << QByteArray("{\"id\":42, \"method\":\"Authentication.Authenticate\", \"params\":{\"your\":\"mamma\"}}") << 42 << "error"; -} - -void RemoteProxyTestsProxy::apiBasicCalls() -{ - QFETCH(QByteArray, data); - QFETCH(int, responseId); - QFETCH(QString, responseStatus); - - // Start the server - startServer(); - - QVariantMap response; - - // Websocket - response = injectWebSocketProxyData(data).toMap(); - //qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - QVERIFY(!response.isEmpty()); - QCOMPARE(response.value("id").toInt(), responseId); - QCOMPARE(response.value("status").toString(), responseStatus); - - // TCP - response.clear(); - response = injectTcpSocketProxyData(data).toMap(); - //qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - QVERIFY(!response.isEmpty()); - QCOMPARE(response.value("id").toInt(), responseId); - QCOMPARE(response.value("status").toString(), responseStatus); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::authenticate_data() -{ - QTest::addColumn("uuid"); - QTest::addColumn("name"); - QTest::addColumn("token"); - QTest::addColumn("nonce"); - - QTest::addColumn("timeout"); - QTest::addColumn("expectedError"); - - QTest::newRow("success") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << "" - << 500 << Authenticator::AuthenticationErrorNoError; - - QTest::newRow("success") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << "nonce" - << 500 << Authenticator::AuthenticationErrorNoError; - - QTest::newRow("success") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << "nonce" - << 300 << Authenticator::AuthenticationErrorAuthenticationFailed; - - - QTest::newRow("failed") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << "" - << 300 << Authenticator::AuthenticationErrorAuthenticationFailed; - - QTest::newRow("not responding") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << "" - << 500 << Authenticator::AuthenticationErrorProxyError; - - QTest::newRow("aborted") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << "" - << 300 << Authenticator::AuthenticationErrorAborted; - - QTest::newRow("unknown") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << "" - << 300 << Authenticator::AuthenticationErrorUnknown; - -} - -void RemoteProxyTestsProxy::authenticate() -{ - QFETCH(QString, uuid); - QFETCH(QString, name); - QFETCH(QString, token); - QFETCH(QString, nonce); - QFETCH(int, timeout); - QFETCH(Authenticator::AuthenticationError, expectedError); - - // Start the server - startServer(); - - m_configuration->setAuthenticationTimeout(8000); - m_configuration->setJsonRpcTimeout(10000); - m_configuration->setInactiveTimeout(10000); - - // Configure result - m_mockAuthenticator->setExpectedAuthenticationError(expectedError); - m_mockAuthenticator->setTimeoutDuration(timeout); - - // Create request - QVariantMap params; - params.insert("uuid", uuid); - params.insert("name", name); - params.insert("token", token); - if (!nonce.isEmpty()) params.insert("nonce", nonce); - - // WebSocket - QVariantMap response; - response = invokeWebSocketProxyApiCall("Authentication.Authenticate", params).toMap(); - //qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - verifyAuthenticationError(response, expectedError); - - // TCP - response = invokeTcpSocketProxyApiCall("Authentication.Authenticate", params).toMap(); - verifyAuthenticationError(response, expectedError); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::authenticateNonce() -{ - // Start the server - startServer(); - - QString nonce = "67af856c4e4071833ed01128e50b3ea5"; - QString token = "C001L0ckingT0ken"; - - // Configure moch authenticator - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - QString nameConnectionOne = "Test client one"; - QUuid uuidConnectionOne = QUuid::createUuid(); - - QString nameConnectionTwo = "Test client two"; - QUuid uuidConnectionTwo = QUuid::createUuid(); - - QByteArray dataOne = "Hello from client one :-)"; - QByteArray dataTwo = "Hello from client two :-)"; - - // Create two connection - RemoteProxyConnection *connectionOne = new RemoteProxyConnection(uuidConnectionOne, nameConnectionOne, this); - connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(uuidConnectionTwo, nameConnectionTwo, this); - connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrlProxyTcp)); - connectionOneReadySpy.wait(); - QVERIFY(connectionOneReadySpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - - // Connect two - QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrlProxyTcp)); - connectionTwoReadySpy.wait(); - QVERIFY(connectionTwoReadySpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - - // Authenticate one - QSignalSpy remoteConnectionEstablishedOne(connectionOne, &RemoteProxyConnection::remoteConnectionEstablished); - QSignalSpy connectionOneAuthenticatedSpy(connectionOne, &RemoteProxyConnection::authenticated); - QVERIFY(connectionOne->authenticate(m_testToken, nonce)); - connectionOneAuthenticatedSpy.wait(); - QVERIFY(connectionOneAuthenticatedSpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - QVERIFY(connectionOne->isAuthenticated()); - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateAuthenticated); - - // Authenticate two - QSignalSpy remoteConnectionEstablishedTwo(connectionTwo, &RemoteProxyConnection::remoteConnectionEstablished); - QSignalSpy connectionTwoAuthenticatedSpy(connectionTwo, &RemoteProxyConnection::authenticated); - QVERIFY(connectionTwo->authenticate(m_testToken, nonce)); - connectionTwoAuthenticatedSpy.wait(); - QVERIFY(connectionTwoAuthenticatedSpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - QVERIFY(connectionTwo->isAuthenticated()); - - // Wait for both to be connected - if (remoteConnectionEstablishedOne.count() < 1) - remoteConnectionEstablishedOne.wait(); - - if (remoteConnectionEstablishedTwo.count() < 1) - remoteConnectionEstablishedTwo.wait(); - - QVERIFY(remoteConnectionEstablishedOne.count() == 1); - QVERIFY(remoteConnectionEstablishedTwo.count() == 1); - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected); - QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected); - - QCOMPARE(connectionOne->tunnelPartnerName(), nameConnectionTwo); - QCOMPARE(QUuid(connectionOne->tunnelPartnerUuid()), uuidConnectionTwo); - QCOMPARE(connectionTwo->tunnelPartnerName(), nameConnectionOne); - QCOMPARE(QUuid(connectionTwo->tunnelPartnerUuid()), uuidConnectionOne); - - // Pipe data trought the tunnel - QSignalSpy remoteConnectionDataOne(connectionOne, &RemoteProxyConnection::dataReady); - QSignalSpy remoteConnectionDataTwo(connectionTwo, &RemoteProxyConnection::dataReady); - - connectionOne->sendData(dataOne); - remoteConnectionDataTwo.wait(); - QVERIFY(remoteConnectionDataTwo.count() == 1); - QCOMPARE(remoteConnectionDataTwo.at(0).at(0).toByteArray().trimmed(), dataOne); - - connectionTwo->sendData(dataTwo); - remoteConnectionDataOne.wait(); - QVERIFY(remoteConnectionDataOne.count() == 1); - QCOMPARE(remoteConnectionDataOne.at(0).at(0).toByteArray().trimmed(), dataTwo); - - connectionOne->deleteLater(); - connectionTwo->deleteLater(); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::authenticateSendData() -{ - // Start the server - startServer(); - - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - QVariantMap params; - params.insert("uuid", "uuid"); - params.insert("name", "name"); - params.insert("token", "token"); - params.insert("nonce", "nonce"); - - QVariantMap request; - request.insert("id", m_commandCounter); - request.insert("method", "Authentication.Authenticate"); - request.insert("params", params); - QJsonDocument jsonDoc = QJsonDocument::fromVariant(request); - - // Connect socket - QWebSocket *socket = new QWebSocket("proxy-testclient", QWebSocketProtocol::Version13); - connect(socket, &QWebSocket::sslErrors, this, &BaseTest::sslErrors); - QSignalSpy spyConnection(socket, &QWebSocket::connected); - socket->open(Engine::instance()->webSocketServerProxy()->serverUrl()); - spyConnection.wait(); - QVERIFY(spyConnection.count() == 1); - - // Authenticate - QSignalSpy dataSpy(socket, &QWebSocket::textMessageReceived); - socket->sendTextMessage(QString(jsonDoc.toJson(QJsonDocument::Compact))); - dataSpy.wait(); - QVERIFY(dataSpy.count() == 1); - - // Send data again and make sure we get disconnected since sending data while waiting for the partner is forbidden - QSignalSpy disconnectedSpy(socket, SIGNAL(disconnected())); - socket->sendTextMessage(QString(jsonDoc.toJson(QJsonDocument::Compact))); - disconnectedSpy.wait(); - QVERIFY(disconnectedSpy.count() == 1); - - socket->deleteLater(); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::clientConnectionWebSocket() -{ - // Start the server - startServer(); - - // Configure moch authenticator - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - // Connect to the server using WebSocket (insecure disabled) - RemoteProxyConnection *connection = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", RemoteProxyConnection::ConnectionTypeWebSocket, this); - connect(connection, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect to server (insecue enabled for testing) - QSignalSpy readySpy(connection, &RemoteProxyConnection::ready); - QVERIFY(connection->connectServer(m_serverUrlProxyWebSocket)); - readySpy.wait(); - QVERIFY(readySpy.count() == 1); - QVERIFY(connection->isConnected()); - QVERIFY(!connection->isRemoteConnected()); - QVERIFY(connection->state() == RemoteProxyConnection::StateReady); - QVERIFY(connection->error() == QAbstractSocket::UnknownSocketError); - QVERIFY(connection->serverUrl() == m_serverUrlProxyWebSocket); - QVERIFY(connection->connectionType() == RemoteProxyConnection::ConnectionTypeWebSocket); - QVERIFY(connection->serverName() == SERVER_NAME_STRING); - QVERIFY(connection->proxyServerName() == Engine::instance()->serverName()); - QVERIFY(connection->proxyServerVersion() == SERVER_VERSION_STRING); - QVERIFY(connection->proxyServerApiVersion() == API_VERSION_STRING); - - QSignalSpy authenticatedSpy(connection, &RemoteProxyConnection::authenticated); - QVERIFY(connection->authenticate("foobar")); - authenticatedSpy.wait(); - QVERIFY(authenticatedSpy.count() == 1); - QVERIFY(connection->isConnected()); - QVERIFY(connection->isAuthenticated()); - QVERIFY(connection->state() == RemoteProxyConnection::StateAuthenticated); - - // Disconnect and clean up - QSignalSpy spyDisconnected(connection, &RemoteProxyConnection::disconnected); - connection->disconnectServer(); - if (spyDisconnected.count() < 1) spyDisconnected.wait(); - - QVERIFY(spyDisconnected.count() >= 1); - QVERIFY(!connection->isConnected()); - - connection->deleteLater(); - stopServer(); -} - -void RemoteProxyTestsProxy::clientConnectionTcpSocket() -{ - // Start the server - startServer(); - - // Configure mock authenticator - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - // Connect to the server using TCP (insecure disabled) - RemoteProxyConnection *connection = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", RemoteProxyConnection::ConnectionTypeTcpSocket, this); - connect(connection, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect to server (insecue enabled for testing) - QSignalSpy readySpy(connection, &RemoteProxyConnection::ready); - QVERIFY(connection->connectServer(m_serverUrlProxyTcp)); - readySpy.wait(); - QVERIFY(readySpy.count() == 1); - QVERIFY(connection->isConnected()); - QVERIFY(!connection->isRemoteConnected()); - QVERIFY(connection->state() == RemoteProxyConnection::StateReady); - QVERIFY(connection->error() == QAbstractSocket::UnknownSocketError); - QVERIFY(connection->serverUrl() == m_serverUrlProxyTcp); - QVERIFY(connection->connectionType() == RemoteProxyConnection::ConnectionTypeTcpSocket); - QVERIFY(connection->serverName() == SERVER_NAME_STRING); - QVERIFY(connection->proxyServerName() == Engine::instance()->serverName()); - QVERIFY(connection->proxyServerVersion() == SERVER_VERSION_STRING); - QVERIFY(connection->proxyServerApiVersion() == API_VERSION_STRING); - - QSignalSpy authenticatedSpy(connection, &RemoteProxyConnection::authenticated); - QVERIFY(connection->authenticate("foobar")); - authenticatedSpy.wait(); - QVERIFY(authenticatedSpy.count() == 1); - QVERIFY(connection->isConnected()); - QVERIFY(connection->isAuthenticated()); - QVERIFY(connection->state() == RemoteProxyConnection::StateAuthenticated); - - // Disconnect and clean up - QSignalSpy spyDisconnected(connection, &RemoteProxyConnection::disconnected); - connection->disconnectServer(); - - if (spyDisconnected.count() < 1) spyDisconnected.wait(); - - QVERIFY(spyDisconnected.count() >= 1); - QVERIFY(!connection->isConnected()); - - connection->deleteLater(); - stopServer(); -} - -void RemoteProxyTestsProxy::remoteConnection() -{ - // Start the server - startServer(); - - // Configure mock authenticator - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - QString nameConnectionOne = "Test client one"; - QUuid uuidConnectionOne = QUuid::createUuid(); - - QString nameConnectionTwo = "Test client two"; - QUuid uuidConnectionTwo = QUuid::createUuid(); - - QByteArray dataOne = "Hello from client one :-)"; - QByteArray dataTwo = "Hello from client two :-)"; - - // Create two connection - RemoteProxyConnection *connectionOne = new RemoteProxyConnection(uuidConnectionOne, nameConnectionOne, this); - connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(uuidConnectionTwo, nameConnectionTwo, this); - connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrlProxyTcp)); - connectionOneReadySpy.wait(); - QVERIFY(connectionOneReadySpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - - // Connect two - QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrlProxyTcp)); - connectionTwoReadySpy.wait(); - QVERIFY(connectionTwoReadySpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - - // Authenticate one - QSignalSpy remoteConnectionEstablishedOne(connectionOne, &RemoteProxyConnection::remoteConnectionEstablished); - 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::StateAuthenticated); - - // 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 - if (remoteConnectionEstablishedOne.count() < 1) - remoteConnectionEstablishedOne.wait(); - - if (remoteConnectionEstablishedTwo.count() < 1) - remoteConnectionEstablishedTwo.wait(); - - QVERIFY(remoteConnectionEstablishedOne.count() == 1); - QVERIFY(remoteConnectionEstablishedTwo.count() == 1); - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected); - QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected); - - QCOMPARE(connectionOne->tunnelPartnerName(), nameConnectionTwo); - QCOMPARE(QUuid(connectionOne->tunnelPartnerUuid()), uuidConnectionTwo); - QCOMPARE(connectionTwo->tunnelPartnerName(), nameConnectionOne); - QCOMPARE(QUuid(connectionTwo->tunnelPartnerUuid()), uuidConnectionOne); - - // Pipe data trought the tunnel - QSignalSpy remoteConnectionDataOne(connectionOne, &RemoteProxyConnection::dataReady); - QSignalSpy remoteConnectionDataTwo(connectionTwo, &RemoteProxyConnection::dataReady); - - connectionOne->sendData(dataOne); - remoteConnectionDataTwo.wait(); - QVERIFY(remoteConnectionDataTwo.count() == 1); - QCOMPARE(remoteConnectionDataTwo.at(0).at(0).toByteArray().trimmed(), dataOne); - - connectionTwo->sendData(dataTwo); - remoteConnectionDataOne.wait(); - QVERIFY(remoteConnectionDataOne.count() == 1); - QCOMPARE(remoteConnectionDataOne.at(0).at(0).toByteArray().trimmed(), dataTwo); - - connectionOne->deleteLater(); - connectionTwo->deleteLater(); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::multipleRemoteConnection() -{ - // Start the server - startServer(); - - // Configure moch authenticator - m_mockAuthenticator->setExpectedAuthenticationError(); - m_mockAuthenticator->setTimeoutDuration(1000); - m_configuration->setAuthenticationTimeout(2000); - m_configuration->setJsonRpcTimeout(5000); - m_configuration->setInactiveTimeout(5000); - - // Create multiple tunnels with one token, but different nonces for each connection - QObject *parent = new QObject(this); - for (int i = 0; i < 5; i++) { - qDebug() << "============== Create remote connection" << i; - bool connectionResult = createRemoteConnection(m_testToken, QUuid::createUuid().toString(), parent); - if (!connectionResult) { - qWarning() << "Test failed because could not create remote connection"; - delete parent; - } - QVERIFY(connectionResult); - } - - delete parent; - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::trippleConnection() -{ - // Start the server - startServer(); - - // Configure moch authenticator - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - QString nonce = QUuid::createUuid().toString(); - - // Create two connection - RemoteProxyConnection *connectionOne = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", this); - connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(QUuid::createUuid(), "Test client two", this); - connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - RemoteProxyConnection *connectionThree = new RemoteProxyConnection(QUuid::createUuid(), "Token thief ^v^", this); - connect(connectionThree, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrlProxyTcp)); - if (connectionOneReadySpy.count() < 1) connectionOneReadySpy.wait(); - QVERIFY(connectionOneReadySpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - - // Connect two - QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrlProxyTcp)); - if (connectionTwoReadySpy.count() < 1) connectionTwoReadySpy.wait(); - QVERIFY(connectionTwoReadySpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - - // Authenticate one - QSignalSpy connectionOneAuthenticatedSpy(connectionOne, &RemoteProxyConnection::authenticated); - QVERIFY(connectionOne->authenticate(m_testToken, nonce)); - if (connectionOneAuthenticatedSpy.count() < 1) connectionOneAuthenticatedSpy.wait(); - QVERIFY(connectionOneAuthenticatedSpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - QVERIFY(connectionOne->isAuthenticated()); - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateAuthenticated); - - QSignalSpy remoteConnectionEstablishedOne(connectionOne, &RemoteProxyConnection::remoteConnectionEstablished); - - // Authenticate two - QSignalSpy remoteConnectionEstablishedTwo(connectionTwo, &RemoteProxyConnection::remoteConnectionEstablished); - QSignalSpy connectionTwoAuthenticatedSpy(connectionTwo, &RemoteProxyConnection::authenticated); - QVERIFY(connectionTwo->authenticate(m_testToken, nonce)); - if (connectionTwoAuthenticatedSpy.count() < 1) connectionTwoAuthenticatedSpy.wait(); - QVERIFY(connectionTwoAuthenticatedSpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - QVERIFY(connectionTwo->isAuthenticated()); - - // Wait for both to be connected - if (remoteConnectionEstablishedOne.count() < 1) - remoteConnectionEstablishedOne.wait(); - - // Now connect a third connection and make sure the client will be closed - - // Connect three - QSignalSpy connectionThreeReadySpy(connectionThree, &RemoteProxyConnection::ready); - QSignalSpy connectionThreeDisconnectedSpy(connectionThree, &RemoteProxyConnection::disconnected); - QVERIFY(connectionThree->connectServer(m_serverUrlProxyTcp)); - if (connectionThreeReadySpy.count() < 1) connectionThreeReadySpy.wait(); - QVERIFY(connectionThreeReadySpy.count() == 1); - QVERIFY(connectionThree->isConnected()); - - // Authenticate three - QSignalSpy connectionThreeAuthenticatedSpy(connectionThree, &RemoteProxyConnection::authenticated); - QVERIFY(connectionThree->authenticate(m_testToken, nonce)); - if (connectionThreeAuthenticatedSpy.count() < 1) connectionThreeAuthenticatedSpy.wait(); - QVERIFY(connectionOneAuthenticatedSpy.count() == 1); - - if (connectionThreeDisconnectedSpy.count() < 1) connectionThreeDisconnectedSpy.wait(); - QVERIFY(connectionThreeDisconnectedSpy.count() >= 1); - - // Make sure the one and two are still connected - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected); - QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::duplicateUuid() -{ - // Start the server - startServer(); - - // Configure moch authenticator - m_mockAuthenticator->setTimeoutDuration(10); - m_mockAuthenticator->setExpectedAuthenticationError(); - - QUuid connectionUuid = QUuid::createUuid(); - - QString nameConnectionOne = "Test client one"; - QString nameConnectionTwo = "Test client two"; - - // Create two connection - RemoteProxyConnection *connectionOne = new RemoteProxyConnection(connectionUuid, nameConnectionOne, this); - connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(connectionUuid, nameConnectionTwo, this); - connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrlProxyTcp)); - if (connectionOneReadySpy.count() < 1) connectionOneReadySpy.wait(); - QVERIFY(connectionOneReadySpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - - // Connect two - QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrlProxyTcp)); - if (connectionTwoReadySpy.count() < 1) connectionTwoReadySpy.wait(); - QVERIFY(connectionTwoReadySpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - - // Authenticate one - QSignalSpy connectionOneAuthenticatedSpy(connectionOne, &RemoteProxyConnection::authenticated); - QVERIFY(connectionOne->authenticate(m_testToken)); - if (connectionOneAuthenticatedSpy.count() < 1) connectionOneAuthenticatedSpy.wait(); - QVERIFY(connectionOneAuthenticatedSpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - QVERIFY(connectionOne->isAuthenticated()); - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateAuthenticated); - - // Authenticate two - QSignalSpy disconnectSpyOne(connectionOne, &RemoteProxyConnection::disconnected); - QSignalSpy disconnectSpyTwo(connectionTwo, &RemoteProxyConnection::disconnected); - - QVERIFY(connectionTwo->authenticate(m_testToken)); - if (disconnectSpyOne.count() < 1 ) disconnectSpyOne.wait(); - QVERIFY(disconnectSpyOne.count() >= 1); - - if (disconnectSpyTwo.count() < 1 ) disconnectSpyTwo.wait(); - QVERIFY(disconnectSpyTwo.count() >= 1); - - connectionOne->deleteLater(); - connectionTwo->deleteLater(); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::sslConfigurations() -{ - // Start the server - startServer(); - - // Connect to the server (insecure disabled) - RemoteProxyConnection *connector = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", this); - QSignalSpy spyError(connector, &RemoteProxyConnection::errorOccurred); - QVERIFY(connector->connectServer(m_serverUrlProxyTcp)); - spyError.wait(); - QVERIFY(spyError.count() == 1); - qDebug() << connector->error(); - QCOMPARE(connector->error(), QAbstractSocket::SslHandshakeFailedError); - QVERIFY(connector->state() == RemoteProxyConnection::StateDisconnected); - - // Connect to server (insecue enabled) - QSignalSpy spyConnected(connector, &RemoteProxyConnection::connected); - connect(connector, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - connector->connectServer(m_serverUrlProxyTcp); - spyConnected.wait(); - - QVERIFY(connector->isConnected()); - - // Disconnect and clean up - connector->disconnectServer(); - QVERIFY(!connector->isConnected()); - - connector->deleteLater(); - stopServer(); -} - -void RemoteProxyTestsProxy::jsonRpcTimeout() -{ - // Start the server - startServer(); - - // Configure result (authentication takes longer than json rpc timeout - m_mockAuthenticator->setExpectedAuthenticationError(); - m_mockAuthenticator->setTimeoutDuration(10000); - m_configuration->setAuthenticationTimeout(10000); - m_configuration->setJsonRpcTimeout(1000); - m_configuration->setInactiveTimeout(10000); - - // Create request - QVariantMap params; - params.insert("uuid", "uuid"); - params.insert("name", "name"); - params.insert("token", "token"); - - QVariant response = invokeWebSocketProxyApiCall("Authentication.Authenticate", params); - qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - - QVERIFY(response.toMap().value("status").toString() == "error"); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::inactiveTimeout() -{ - // Start the server - startServer(); - - m_configuration->setInactiveTimeout(1000); - - RemoteProxyConnection *connection = new RemoteProxyConnection(QUuid::createUuid(), "Sleepy test client", this); - connect(connection, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionReadySpy(connection, &RemoteProxyConnection::ready); - QSignalSpy connectionDisconnectedSpy(connection, &RemoteProxyConnection::disconnected); - QVERIFY(connection->connectServer(m_serverUrlProxyTcp)); - if (connectionReadySpy.count() < 1) connectionReadySpy.wait(); - QVERIFY(connectionReadySpy.count() == 1); - - // Now wait for disconnected - if (connectionDisconnectedSpy.count() < 1) - connectionDisconnectedSpy.wait(); - - QVERIFY(connectionDisconnectedSpy.count() >= 1); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::authenticationReplyTimeout() -{ - // Start the server - startServer(); - - // Configure result (authentication takes longer than json rpc timeout - m_mockAuthenticator->setExpectedAuthenticationError(); - m_mockAuthenticator->setTimeoutDuration(2000); - - m_configuration->setAuthenticationTimeout(500); - m_configuration->setJsonRpcTimeout(1000); - m_configuration->setInactiveTimeout(1000); - - // Create request - QVariantMap params; - params.insert("uuid", QUuid::createUuid().toString()); - params.insert("name", "Sleepy test client"); - params.insert("token", "sleepy token zzzZZZ"); - - QVariant response = invokeWebSocketProxyApiCall("Authentication.Authenticate", params); - qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - verifyAuthenticationError(response, Authenticator::AuthenticationErrorTimeout); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::authenticationReplyConnection() -{ - // Start the server - startServer(); - - // Configure result (authentication takes longer than json rpc timeout - m_mockAuthenticator->setExpectedAuthenticationError(); - m_mockAuthenticator->setTimeoutDuration(1000); - - m_configuration->setAuthenticationTimeout(500); - m_configuration->setJsonRpcTimeout(1000); - m_configuration->setInactiveTimeout(1000); - - RemoteProxyConnection *connection = new RemoteProxyConnection(QUuid::createUuid(), "Sleepy test client", this); - connect(connection, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionReadySpy(connection, &RemoteProxyConnection::ready); - QVERIFY(connection->connectServer(m_serverUrlProxyTcp)); - connectionReadySpy.wait(); - QVERIFY(connectionReadySpy.count() == 1); - - QSignalSpy connectionErrorSpy(connection, &RemoteProxyConnection::errorOccurred); - connection->authenticate("blub"); - connectionErrorSpy.wait(); - QVERIFY(connectionErrorSpy.count() == 1); - QVERIFY(connectionErrorSpy.at(0).at(0).toInt() == static_cast(QAbstractSocket::ProxyConnectionRefusedError)); - QVERIFY(connection->error() == QAbstractSocket::ProxyConnectionRefusedError); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::tcpRemoteConnection() -{ - // Start the server - startServer(); - - // Configure mock authenticator - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - QString nameConnectionOne = "Test client one"; - QUuid uuidConnectionOne = QUuid::createUuid(); - - QString nameConnectionTwo = "Test client two"; - QUuid uuidConnectionTwo = QUuid::createUuid(); - - QByteArray dataOne = "Hello from client one :-)"; - QByteArray dataTwo = "Hello from client two :-)"; - - // Create two connection - RemoteProxyConnection *connectionOne = new RemoteProxyConnection(uuidConnectionOne, nameConnectionOne, RemoteProxyConnection::ConnectionTypeTcpSocket, this); - connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(uuidConnectionTwo, nameConnectionTwo, RemoteProxyConnection::ConnectionTypeTcpSocket, this); - connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrlProxyTcp)); - connectionOneReadySpy.wait(); - QVERIFY(connectionOneReadySpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - - // Connect two - QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrlProxyTcp)); - connectionTwoReadySpy.wait(); - QVERIFY(connectionTwoReadySpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - - // Authenticate one - QSignalSpy remoteConnectionEstablishedOne(connectionOne, &RemoteProxyConnection::remoteConnectionEstablished); - 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::StateAuthenticated); - - // Authenticate two - QSignalSpy remoteConnectionEstablishedTwo(connectionTwo, &RemoteProxyConnection::remoteConnectionEstablished); - QSignalSpy connectionTwoAuthenticatedSpy(connectionTwo, &RemoteProxyConnection::authenticated); - QVERIFY(connectionTwo->authenticate(m_testToken)); - connectionTwoAuthenticatedSpy.wait(); - qDebug() << connectionTwoAuthenticatedSpy.count(); - QVERIFY(connectionTwoAuthenticatedSpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - QVERIFY(connectionTwo->isAuthenticated()); - - // Wait for both to be connected - if (remoteConnectionEstablishedOne.count() < 1) - remoteConnectionEstablishedOne.wait(); - - if (remoteConnectionEstablishedTwo.count() < 1) - remoteConnectionEstablishedTwo.wait(); - - QVERIFY(remoteConnectionEstablishedOne.count() == 1); - QVERIFY(remoteConnectionEstablishedTwo.count() == 1); - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected); - QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected); - - QCOMPARE(connectionOne->tunnelPartnerName(), nameConnectionTwo); - QCOMPARE(QUuid(connectionOne->tunnelPartnerUuid()), uuidConnectionTwo); - QCOMPARE(connectionTwo->tunnelPartnerName(), nameConnectionOne); - QCOMPARE(QUuid(connectionTwo->tunnelPartnerUuid()), uuidConnectionOne); - - // Pipe data trought the tunnel - QSignalSpy remoteConnectionDataOne(connectionOne, &RemoteProxyConnection::dataReady); - QSignalSpy remoteConnectionDataTwo(connectionTwo, &RemoteProxyConnection::dataReady); - - connectionOne->sendData(dataOne); - remoteConnectionDataTwo.wait(); - QVERIFY(remoteConnectionDataTwo.count() == 1); - QCOMPARE(remoteConnectionDataTwo.at(0).at(0).toByteArray().trimmed(), dataOne); - - connectionTwo->sendData(dataTwo); - remoteConnectionDataOne.wait(); - QVERIFY(remoteConnectionDataOne.count() == 1); - QCOMPARE(remoteConnectionDataOne.at(0).at(0).toByteArray().trimmed(), dataTwo); - - connectionOne->deleteLater(); - connectionTwo->deleteLater(); - - // Clean up - stopServer(); -} - -void RemoteProxyTestsProxy::tcpWebsocketRemoteConnection() -{ - // Start the server - startServer(); - - // Configure mock authenticator - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - QString nameConnectionOne = "Test client one"; - QUuid uuidConnectionOne = QUuid::createUuid(); - - QString nameConnectionTwo = "Test client two"; - QUuid uuidConnectionTwo = QUuid::createUuid(); - - QByteArray dataOne = "Hello from client one :-)"; - QByteArray dataTwo = "Hello from client two :-)"; - - // Create two connection - RemoteProxyConnection *connectionOne = new RemoteProxyConnection(uuidConnectionOne, nameConnectionOne, RemoteProxyConnection::ConnectionTypeWebSocket, this); - connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(uuidConnectionTwo, nameConnectionTwo, RemoteProxyConnection::ConnectionTypeTcpSocket, this); - connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrlProxyWebSocket)); - connectionOneReadySpy.wait(); - QVERIFY(connectionOneReadySpy.count() == 1); - QVERIFY(connectionOne->isConnected()); - - // Connect two - QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrlProxyTcp)); - connectionTwoReadySpy.wait(); - QVERIFY(connectionTwoReadySpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - - // Authenticate one - QSignalSpy remoteConnectionEstablishedOne(connectionOne, &RemoteProxyConnection::remoteConnectionEstablished); - 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::StateAuthenticated); - - // Authenticate two - QSignalSpy remoteConnectionEstablishedTwo(connectionTwo, &RemoteProxyConnection::remoteConnectionEstablished); - QSignalSpy connectionTwoAuthenticatedSpy(connectionTwo, &RemoteProxyConnection::authenticated); - QVERIFY(connectionTwo->authenticate(m_testToken)); - connectionTwoAuthenticatedSpy.wait(); - qDebug() << connectionTwoAuthenticatedSpy.count(); - QVERIFY(connectionTwoAuthenticatedSpy.count() == 1); - QVERIFY(connectionTwo->isConnected()); - QVERIFY(connectionTwo->isAuthenticated()); - - // Wait for both to be connected - if (remoteConnectionEstablishedOne.count() < 1) - remoteConnectionEstablishedOne.wait(); - - if (remoteConnectionEstablishedTwo.count() < 1) - remoteConnectionEstablishedTwo.wait(); - - QVERIFY(remoteConnectionEstablishedOne.count() == 1); - QVERIFY(remoteConnectionEstablishedTwo.count() == 1); - QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected); - QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected); - - QCOMPARE(connectionOne->tunnelPartnerName(), nameConnectionTwo); - QCOMPARE(QUuid(connectionOne->tunnelPartnerUuid()), uuidConnectionTwo); - QCOMPARE(connectionTwo->tunnelPartnerName(), nameConnectionOne); - QCOMPARE(QUuid(connectionTwo->tunnelPartnerUuid()), uuidConnectionOne); - - // Pipe data trought the tunnel - QSignalSpy remoteConnectionDataOne(connectionOne, &RemoteProxyConnection::dataReady); - QSignalSpy remoteConnectionDataTwo(connectionTwo, &RemoteProxyConnection::dataReady); - - connectionOne->sendData(dataOne); - remoteConnectionDataTwo.wait(); - QVERIFY(remoteConnectionDataTwo.count() == 1); - QCOMPARE(remoteConnectionDataTwo.at(0).at(0).toByteArray().trimmed(), dataOne); - - connectionTwo->sendData(dataTwo); - remoteConnectionDataOne.wait(); - QVERIFY(remoteConnectionDataOne.count() == 1); - QCOMPARE(remoteConnectionDataOne.at(0).at(0).toByteArray().trimmed(), dataTwo); - - connectionOne->deleteLater(); - connectionTwo->deleteLater(); - - // Clean up - stopServer(); -} - -QTEST_MAIN(RemoteProxyTestsProxy) diff --git a/tests/test-proxy/remoteproxytestsproxy.h b/tests/test-proxy/remoteproxytestsproxy.h deleted file mode 100644 index 43c120f..0000000 --- a/tests/test-proxy/remoteproxytestsproxy.h +++ /dev/null @@ -1,93 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef REMOTEPROXYTESTSPROXY_H -#define REMOTEPROXYTESTSPROXY_H - -#include "basetest.h" - -using namespace remoteproxy; -using namespace remoteproxyclient; - -class RemoteProxyTestsProxy : public BaseTest -{ - Q_OBJECT -public: - explicit RemoteProxyTestsProxy(QObject *parent = nullptr); - ~RemoteProxyTestsProxy() = default; - -private slots: - // Basic stuff - void startStopServer(); - void dummyAuthenticator(); - void monitorServer(); - - void configuration_data(); - void configuration(); - - // WebSocket connection - void serverPortBlocked(); - void websocketBinaryData(); - void websocketPing(); - - // WebSocket connection API - void getIntrospect(); - void getHello(); - - void apiBasicCalls_data(); - void apiBasicCalls(); - - void apiBasicCallsTcp_data(); - void apiBasicCallsTcp(); - - void authenticate_data(); - void authenticate(); - - void authenticateNonce(); - void authenticateSendData(); - - // Client lib - void clientConnectionTcpSocket(); - void clientConnectionWebSocket(); - void remoteConnection(); - void multipleRemoteConnection(); - void trippleConnection(); - void duplicateUuid(); - void sslConfigurations(); - - void inactiveTimeout(); - void jsonRpcTimeout(); - void authenticationReplyTimeout(); - void authenticationReplyConnection(); - - // TCP Websocket combinations - void tcpRemoteConnection(); - void tcpWebsocketRemoteConnection(); - -}; - -#endif // REMOTEPROXYTESTSPROXY_H diff --git a/tests/test-proxy/test-proxy.pro b/tests/test-proxy/test-proxy.pro deleted file mode 100644 index dd5a788..0000000 --- a/tests/test-proxy/test-proxy.pro +++ /dev/null @@ -1,14 +0,0 @@ -include(../../nymea-remoteproxy.pri) -include(../testbase/testbase.pri) - -CONFIG += testcase -QT += testlib - -TARGET = nymea-remoteproxy-proxy-tests - -HEADERS += remoteproxytestsproxy.h - -SOURCES += remoteproxytestsproxy.cpp - -target.path = $$[QT_INSTALL_PREFIX]/bin -INSTALLS += target diff --git a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp index d365c74..f28f287 100644 --- a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp +++ b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp @@ -27,9 +27,9 @@ #include "remoteproxyteststunnelproxy.h" + #include "engine.h" #include "loggingcategories.h" -#include "remoteproxyconnection.h" #include "../common/slipdataprocessor.h" #include "../../version.h" @@ -43,6 +43,8 @@ #include #include +using namespace remoteproxyclient; + RemoteProxyTestsTunnelProxy::RemoteProxyTestsTunnelProxy(QObject *parent) : BaseTest(parent) { @@ -51,6 +53,13 @@ RemoteProxyTestsTunnelProxy::RemoteProxyTestsTunnelProxy(QObject *parent) : void RemoteProxyTestsTunnelProxy::startStopServer() { + resetDebugCategories(); + addDebugCategory("Engine.debug=true"); + addDebugCategory("JsonRpc.debug=true"); + addDebugCategory("TcpSocketServer.debug=true"); + addDebugCategory("WebSocketServer.debug=true"); + addDebugCategory("TunnelProxyServer.debug=true"); + startServer(); stopServer(); } @@ -74,6 +83,10 @@ void RemoteProxyTestsTunnelProxy::apiBasicCallsTcp_data() void RemoteProxyTestsTunnelProxy::apiBasicCallsTcp() { + resetDebugCategories(); + addDebugCategory("Engine.debug=true"); + addDebugCategory("TcpSocketServer.debug=true"); + QFETCH(QByteArray, data); QFETCH(int, responseId); QFETCH(QString, responseStatus); @@ -81,7 +94,7 @@ void RemoteProxyTestsTunnelProxy::apiBasicCallsTcp() // Start the server startServer(); - QVariant response = injectTcpSocketProxyData(data); + QVariant response = injectTcpSocketTunnelProxyData(data); QVERIFY(!response.isNull()); qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); @@ -156,6 +169,317 @@ void RemoteProxyTestsTunnelProxy::getHello() stopServer(); } +void RemoteProxyTestsTunnelProxy::monitorServer() +{ + + // Start the server + startServer(); + + + // ** Create the server ** + QString serverName = "nymea server"; + QUuid serverUuid = QUuid::createUuid(); + + TunnelProxySocketServer *tunnelProxyServer = new TunnelProxySocketServer(serverUuid, serverName, this); + connect(tunnelProxyServer, &TunnelProxySocketServer::sslErrors, this, [=](const QList &errors){ + tunnelProxyServer->ignoreSslErrors(errors); + }); + + tunnelProxyServer->startServer(m_serverUrlTunnelProxyTcp); + + QSignalSpy serverRunningSpy(tunnelProxyServer, &TunnelProxySocketServer::runningChanged); + serverRunningSpy.wait(); + QVERIFY(serverRunningSpy.count() == 1); + QList arguments = serverRunningSpy.takeFirst(); + QVERIFY(arguments.at(0).toBool() == true); + QVERIFY(tunnelProxyServer->running()); + QCOMPARE(tunnelProxyServer->serverUrl(), m_serverUrlTunnelProxyTcp); + QCOMPARE(tunnelProxyServer->remoteProxyServer(), QString(SERVER_NAME_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyServerName(), Engine::instance()->configuration()->serverName()); + QCOMPARE(tunnelProxyServer->remoteProxyServerVersion(), QString(SERVER_VERSION_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyApiVersion(), QString(API_VERSION_STRING)); + + + // ** Remote connection 1 ** + + QString clientOneName = "Client one"; + QUuid clientOneUuid = QUuid::createUuid(); + TunnelProxyRemoteConnection *remoteConnectionOne = new TunnelProxyRemoteConnection(clientOneUuid, clientOneName, this); + connect(remoteConnectionOne, &TunnelProxyRemoteConnection::sslErrors, this, [=](const QList &errors){ + remoteConnectionOne->ignoreSslErrors(errors); + }); + + remoteConnectionOne->connectServer(m_serverUrlTunnelProxyTcp, serverUuid); + + // ** Tunnel proxy server socket 1 ** + QSignalSpy remoteConnectedOneSpy(tunnelProxyServer, &TunnelProxySocketServer::clientConnected); + QVERIFY(remoteConnectedOneSpy.wait()); + QVERIFY(remoteConnectedOneSpy.count() == 1); + arguments = remoteConnectedOneSpy.takeFirst(); + + TunnelProxySocket *tunnelProxySocketOne = arguments.at(0).value(); + QVERIFY(tunnelProxySocketOne->clientName() == clientOneName); + QVERIFY(tunnelProxySocketOne->clientUuid() == clientOneUuid); + QVERIFY(!tunnelProxySocketOne->clientPeerAddress().isNull()); + QVERIFY(tunnelProxySocketOne->socketAddress() != 0x0000 && tunnelProxySocketOne->socketAddress() != 0xFFFF); + QVERIFY(tunnelProxySocketOne->connected()); + + qDebug() << "Have socket one" << tunnelProxySocketOne; + + // ** Send data in both directions + QByteArray testData("#sdföiabi23u4b34b598gvndafjibnföQIUH34982HRIPURBFÖWLKDÜOQw9h934utbf ljBiH9FBLAJF RF AF,A§uu)(\"§)§(u$)($=$(((($((!"); + + // Socket -> Remote connection + QSignalSpy remoteConnectionOneDataSpy(remoteConnectionOne, &TunnelProxyRemoteConnection::dataReady); + tunnelProxySocketOne->writeData(testData); + QVERIFY(remoteConnectionOneDataSpy.wait()); + QVERIFY(remoteConnectionOneDataSpy.count() == 1); + arguments = remoteConnectionOneDataSpy.takeFirst(); + QByteArray receivedTestData = arguments.at(0).toByteArray(); + QVERIFY(receivedTestData == testData); + + + // Remote connection -> Socket + QByteArray testData2("The biggest decision in life is about changing your life through changing your mind. – Albert Schweitzer"); + QSignalSpy tunnelProxySocketOneDataSpy(tunnelProxySocketOne, &TunnelProxySocket::dataReceived); + remoteConnectionOne->sendData(testData2); + QVERIFY(tunnelProxySocketOneDataSpy.wait()); + QVERIFY(tunnelProxySocketOneDataSpy.count() == 1); + arguments = tunnelProxySocketOneDataSpy.takeFirst(); + QByteArray receivedTestData2 = arguments.at(0).toByteArray(); + QVERIFY(receivedTestData2 == testData2); + + + // ** Remote connection 2 ** + + QString clientTwoName = "Client two"; + QUuid clientTwoUuid = QUuid::createUuid(); + TunnelProxyRemoteConnection *remoteConnectionTwo = new TunnelProxyRemoteConnection(clientTwoUuid, clientTwoName, this); + connect(remoteConnectionTwo, &TunnelProxyRemoteConnection::sslErrors, this, [=](const QList &errors){ + remoteConnectionTwo->ignoreSslErrors(errors); + }); + + remoteConnectionTwo->connectServer(m_serverUrlTunnelProxyTcp, serverUuid); + + // ** Tunnel proxy server socket 2 ** + QSignalSpy remoteConnectedTwoSpy(tunnelProxyServer, &TunnelProxySocketServer::clientConnected); + QVERIFY(remoteConnectedTwoSpy.wait()); + QVERIFY(remoteConnectedTwoSpy.count() == 1); + arguments = remoteConnectedTwoSpy.takeFirst(); + + TunnelProxySocket *tunnelProxySocketTwo = arguments.at(0).value(); + QVERIFY(tunnelProxySocketTwo->clientName() == clientTwoName); + QVERIFY(tunnelProxySocketTwo->clientUuid() == clientTwoUuid); + QVERIFY(!tunnelProxySocketTwo->clientPeerAddress().isNull()); + QVERIFY(tunnelProxySocketTwo->socketAddress() != 0x0000 && tunnelProxySocketTwo->socketAddress() != 0xFFFF); + QVERIFY(tunnelProxySocketTwo->connected()); + + qDebug() << "Have socket two" << tunnelProxySocketTwo; + + // ** Send data in both directions + + // Socket -> Remote connection + QSignalSpy remoteConnectionTwoDataSpy(remoteConnectionTwo, &TunnelProxyRemoteConnection::dataReady); + tunnelProxySocketTwo->writeData(testData); + QVERIFY(remoteConnectionTwoDataSpy.wait()); + QVERIFY(remoteConnectionTwoDataSpy.count() == 1); + arguments = remoteConnectionTwoDataSpy.takeFirst(); + receivedTestData = arguments.at(0).toByteArray(); + QVERIFY(receivedTestData == testData); + + // Remote connection -> Socket + QSignalSpy tunnelProxySocketTwoDataSpy(tunnelProxySocketTwo, &TunnelProxySocket::dataReceived); + remoteConnectionTwo->sendData(testData2); + QVERIFY(tunnelProxySocketTwoDataSpy.wait()); + QVERIFY(tunnelProxySocketTwoDataSpy.count() == 1); + arguments = tunnelProxySocketTwoDataSpy.takeFirst(); + receivedTestData2 = arguments.at(0).toByteArray(); + QVERIFY(receivedTestData2 == testData2); + + // Get monitor data + QLocalSocket *monitor = new QLocalSocket(this); + QSignalSpy connectedSpy(monitor, &QLocalSocket::connected); + monitor->connectToServer(m_configuration->monitorSocketFileName()); + if (connectedSpy.count() < 1) connectedSpy.wait(); + QVERIFY(connectedSpy.count() == 1); + + QSignalSpy dataSpy(monitor, &QLocalSocket::readyRead); + + QVariantMap request; + request.insert("method", "refresh"); + QVariantMap params; + params.insert("printAll", true); + request.insert("params", params); + + monitor->write(QJsonDocument::fromVariant(request).toJson(QJsonDocument::Compact) + "\n"); + + if (dataSpy.count() < 1) dataSpy.wait(); + QVERIFY(dataSpy.count() == 1); + QByteArray data = monitor->readAll(); + qDebug() << data; + + // TODO: verify monitor data + + QSignalSpy disconnectedSpy(monitor, &QLocalSocket::connected); + monitor->disconnectFromServer(); + if (disconnectedSpy.count() < 1) disconnectedSpy.wait(); + + Engine::instance()->tunnelProxyServer()->stopServer(); + + QTest::qWait(100); + + QVERIFY(!tunnelProxyServer->running()); + QVERIFY(!remoteConnectionOne->remoteConnected()); + QVERIFY(!remoteConnectionTwo->remoteConnected()); + + // Clean up + tunnelProxyServer->deleteLater(); + remoteConnectionOne->deleteLater(); + remoteConnectionTwo->deleteLater(); + + resetDebugCategories(); + + stopServer(); +} + +void RemoteProxyTestsTunnelProxy::configuration_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("success"); + + QTest::newRow("valid configuration") << ":/test-configuration.conf" << true; + QTest::newRow("valid configuration chain") << ":/test-configuration-chain.conf" << true; + QTest::newRow("faulty filename") << ":/not-exisitng-test-configuration.conf" << false; + QTest::newRow("faulty certificate") << ":/test-configuration-faulty-certificate.conf" << false; + QTest::newRow("faulty key") << ":/test-configuration-faulty-key.conf" << false; + QTest::newRow("faulty chain") << ":/test-configuration-faulty-chain.conf" << false; +} + +void RemoteProxyTestsTunnelProxy::configuration() +{ + QFETCH(QString, fileName); + QFETCH(bool, success); + + ProxyConfiguration configuration; + QCOMPARE(configuration.loadConfiguration(fileName), success); +} + +void RemoteProxyTestsTunnelProxy::serverPortBlocked() +{ + cleanUpEngine(); + + m_configuration = new ProxyConfiguration(this); + loadConfiguration(":/test-configuration.conf"); + + // Create a dummy server which blocks the port + QWebSocketServer dummyServer("dummy-server", QWebSocketServer::NonSecureMode); + QVERIFY(dummyServer.listen(QHostAddress::LocalHost, m_configuration->webSocketServerTunnelProxyPort())); + + // Start proxy webserver + QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged); + Engine::instance()->start(m_configuration); + runningSpy.wait(); + QVERIFY(runningSpy.count() == 1); + + // Make sure the server is not running + QVERIFY(Engine::instance()->running()); + + // Make sure the websocket server is not running + QVERIFY(!Engine::instance()->webSocketServerTunnelProxy()->running()); + + QSignalSpy closedSpy(&dummyServer, &QWebSocketServer::closed); + dummyServer.close(); + closedSpy.wait(); + QVERIFY(closedSpy.count() == 1); + + // Try again + startServer(); + + // Clean up + stopServer(); + + // Do the same with the tcp server + cleanUpEngine(); + + m_configuration = new ProxyConfiguration(this); + loadConfiguration(":/test-configuration.conf"); + + // Create a dummy server which blocks the port + QTcpServer *tcpDummyServer = new QTcpServer(this); + QVERIFY(tcpDummyServer->listen(QHostAddress::LocalHost, m_configuration->tcpServerTunnelProxyPort())); + + // Start proxy webserver + QSignalSpy runningSpy2(Engine::instance(), &Engine::runningChanged); + Engine::instance()->start(m_configuration); + runningSpy2.wait(); + QVERIFY(runningSpy2.count() == 1); + + // Make sure the engine is running + QVERIFY(Engine::instance()->running()); + + // Make sure the TCP server is not running + QVERIFY(!Engine::instance()->tcpSocketServerTunnelProxy()->running()); + + tcpDummyServer->close(); + delete tcpDummyServer; + + // Try again + startServer(); + + // Make sure the TCP server is not running + QVERIFY(Engine::instance()->webSocketServerTunnelProxy()->running()); + QVERIFY(Engine::instance()->tcpSocketServerTunnelProxy()->running()); + + // Clean up + stopServer(); +} + +void RemoteProxyTestsTunnelProxy::websocketBinaryData() +{ + // Start the server + startServer(); + + QWebSocket *client = new QWebSocket("bad-client", QWebSocketProtocol::Version13); + connect(client, &QWebSocket::sslErrors, this, &BaseTest::sslErrors); + QSignalSpy spyConnection(client, SIGNAL(connected())); + client->open(Engine::instance()->webSocketServerTunnelProxy()->serverUrl()); + spyConnection.wait(); + + // Send binary data and make sure the server disconnects this socket + QSignalSpy spyDisconnected(client, SIGNAL(disconnected())); + client->sendBinaryMessage("trying to upload stuff...stuff...more stuff... other stuff"); + spyConnection.wait(1000); + QVERIFY(spyConnection.count() == 1); + + // Clean up + stopServer(); +} + +void RemoteProxyTestsTunnelProxy::websocketPing() +{ + // Start the server + startServer(); + + QWebSocket *client = new QWebSocket("bad-client", QWebSocketProtocol::Version13); + connect(client, &QWebSocket::sslErrors, this, &BaseTest::sslErrors); + QSignalSpy spyConnection(client, SIGNAL(connected())); + client->open(Engine::instance()->webSocketServerTunnelProxy()->serverUrl()); + spyConnection.wait(); + QVERIFY(spyConnection.count() == 1); + + QByteArray pingMessage = QByteArray("ping!"); + QSignalSpy pongSpy(client, &QWebSocket::pong); + client->ping(pingMessage); + pongSpy.wait(); + QVERIFY(pongSpy.count() == 1); + qDebug() << pongSpy.at(0).at(0) << pongSpy.at(0).at(1); + + QVERIFY(pongSpy.at(0).at(1).toByteArray() == pingMessage); + + // Clean up + stopServer(); +} + void RemoteProxyTestsTunnelProxy::apiBasicCalls_data() { QTest::addColumn("data"); diff --git a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h index 5512289..ce69a50 100644 --- a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h +++ b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h @@ -31,7 +31,6 @@ #include "basetest.h" using namespace remoteproxy; -using namespace remoteproxyclient; class RemoteProxyTestsTunnelProxy : public BaseTest { @@ -48,6 +47,16 @@ private slots: void getIntrospect(); void getHello(); + void monitorServer(); + + void configuration_data(); + void configuration(); + + void serverPortBlocked(); + + void websocketBinaryData(); + void websocketPing(); + void apiBasicCalls_data(); void apiBasicCalls(); diff --git a/tests/testbase/basetest.cpp b/tests/testbase/basetest.cpp index db1a370..6594992 100644 --- a/tests/testbase/basetest.cpp +++ b/tests/testbase/basetest.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -29,7 +29,6 @@ #include "engine.h" #include "loggingcategories.h" -#include "remoteproxyconnection.h" #include "../common/slipdataprocessor.h" @@ -78,18 +77,6 @@ void BaseTest::cleanUpEngine() QVERIFY(!Engine::exists()); } - if (m_mockAuthenticator) { - delete m_mockAuthenticator; - m_mockAuthenticator = nullptr; - } - - if (m_dummyAuthenticator) { - delete m_dummyAuthenticator; - m_dummyAuthenticator = nullptr; - } - - m_authenticator = nullptr; - if (m_configuration) { m_configuration = nullptr; } @@ -103,39 +90,26 @@ void BaseTest::restartEngine() void BaseTest::startEngine() { - m_configuration = new ProxyConfiguration(this); + if (!m_configuration) + m_configuration = new ProxyConfiguration(Engine::instance()); + loadConfiguration(":/test-configuration.conf"); - m_dummyAuthenticator = new DummyAuthenticator(this); - m_mockAuthenticator = new MockAuthenticator(this); - m_authenticator = qobject_cast(m_mockAuthenticator); - if (!Engine::exists()) { - Engine::instance()->setAuthenticator(m_authenticator); - Engine::instance()->setDeveloperModeEnabled(true); - QVERIFY(Engine::exists()); - QVERIFY(!Engine::instance()->running()); - } + QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged); + Engine::instance()->start(m_configuration); + runningSpy.wait(); + QVERIFY(runningSpy.count() == 1); + QVERIFY(Engine::instance()->running()); } void BaseTest::startServer() { restartEngine(); - if (!Engine::instance()->running()) { - QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged); - Engine::instance()->setDeveloperModeEnabled(true); - Engine::instance()->start(m_configuration); - runningSpy.wait(); - QVERIFY(runningSpy.count() == 1); - } - QVERIFY(Engine::instance()->running()); - QVERIFY(Engine::instance()->developerMode()); - QVERIFY(Engine::instance()->webSocketServerProxy()->running()); - QVERIFY(Engine::instance()->tcpSocketServerProxy()->running()); QVERIFY(Engine::instance()->webSocketServerTunnelProxy()->running()); QVERIFY(Engine::instance()->tcpSocketServerTunnelProxy()->running()); - QVERIFY(Engine::instance()->proxyServer()->running()); + QVERIFY(Engine::instance()->unixSocketServerTunnelProxy()->running()); QVERIFY(Engine::instance()->tunnelProxyServer()->running()); QVERIFY(Engine::instance()->monitorServer()->running()); } @@ -151,316 +125,6 @@ void BaseTest::stopServer() cleanUpEngine(); } -QVariant BaseTest::invokeWebSocketProxyApiCall(const QString &method, const QVariantMap params) -{ - QVariantMap request; - request.insert("id", m_commandCounter); - request.insert("method", method); - request.insert("params", params); - QJsonDocument jsonDoc = QJsonDocument::fromVariant(request); - - QWebSocket *socket = new QWebSocket("proxy-testclient", QWebSocketProtocol::Version13); - connect(socket, &QWebSocket::sslErrors, this, &BaseTest::sslErrors); - QSignalSpy spyConnection(socket, SIGNAL(connected())); - socket->open(Engine::instance()->webSocketServerProxy()->serverUrl()); - spyConnection.wait(); - if (spyConnection.count() == 0) { - return QVariant(); - } - - QSignalSpy dataSpy(socket, SIGNAL(textMessageReceived(QString))); - socket->sendTextMessage(QString(jsonDoc.toJson(QJsonDocument::Compact))); - dataSpy.wait(); - - socket->close(); - socket->deleteLater(); - - for (int i = 0; i < dataSpy.count(); i++) { - // Make sure the response ends with '}\n' - if (!dataSpy.at(i).last().toByteArray().endsWith("}\n")) { - qWarning() << "JSON data does not end with \"}\n\""; - return QVariant(); - } - - // Make sure the response it a valid JSON string - QJsonParseError error; - jsonDoc = QJsonDocument::fromJson(dataSpy.at(i).last().toByteArray(), &error); - if (error.error != QJsonParseError::NoError) { - qWarning() << "JSON parser error" << error.errorString(); - return QVariant(); - } - QVariantMap response = jsonDoc.toVariant().toMap(); - - // skip notifications - if (response.contains("notification")) - continue; - - if (response.value("id").toInt() == m_commandCounter) { - m_commandCounter++; - return jsonDoc.toVariant(); - } - } - - m_commandCounter++; - return QVariant(); -} - -QVariant BaseTest::injectWebSocketProxyData(const QByteArray &data) -{ - QWebSocket *socket = new QWebSocket("proxy-testclient", QWebSocketProtocol::Version13); - connect(socket, &QWebSocket::sslErrors, this, &BaseTest::sslErrors); - - QSignalSpy spyConnection(socket, SIGNAL(connected())); - socket->open(Engine::instance()->webSocketServerProxy()->serverUrl()); - spyConnection.wait(); - if (spyConnection.count() == 0) { - return QVariant(); - } - - QSignalSpy spy(socket, SIGNAL(textMessageReceived(QString))); - socket->sendTextMessage(QString(data)); - spy.wait(); - - socket->close(); - socket->deleteLater(); - - for (int i = 0; i < spy.count(); i++) { - // Make sure the response ends with '}\n' - if (!spy.at(i).last().toByteArray().endsWith("}\n")) { - qWarning() << "JSON data does not end with \"}\n\""; - return QVariant(); - } - - // Make sure the response it a valid JSON string - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(spy.at(i).last().toByteArray(), &error); - if (error.error != QJsonParseError::NoError) { - qWarning() << "JSON parser error" << error.errorString(); - return QVariant(); - } - return jsonDoc.toVariant(); - } - m_commandCounter++; - return QVariant(); -} - -QVariant BaseTest::invokeTcpSocketProxyApiCall(const QString &method, const QVariantMap params) -{ - QVariantMap request; - request.insert("id", m_commandCounter); - request.insert("method", method); - request.insert("params", params); - QJsonDocument jsonDoc = QJsonDocument::fromVariant(request); - - QSslSocket *socket = new QSslSocket(this); - typedef void (QSslSocket:: *sslErrorsSignal)(const QList &); - QObject::connect(socket, static_cast(&QSslSocket::sslErrors), this, &BaseTest::sslSocketSslErrors); - - QSignalSpy spyConnection(socket, &QSslSocket::connected); - socket->connectToHostEncrypted(Engine::instance()->tcpSocketServerProxy()->serverUrl().host(), - static_cast(Engine::instance()->tcpSocketServerProxy()->serverUrl().port())); - spyConnection.wait(); - if (spyConnection.count() == 0) { - return QVariant(); - } - - QSignalSpy dataSpy(socket, &QSslSocket::readyRead); - socket->write(jsonDoc.toJson(QJsonDocument::Compact) + '\n'); - dataSpy.wait(); - if (dataSpy.count() != 1) { - qWarning() << "No data received"; - return QVariant(); - } - - QByteArray data = socket->readAll(); - socket->close(); - socket->deleteLater(); - - // Make sure the response ends with '}\n' - if (!data.endsWith("}\n")) { - qWarning() << "JSON data does not end with \"}\n\""; - return QVariant(); - } - - // Make sure the response it a valid JSON string - QJsonParseError error; - jsonDoc = QJsonDocument::fromJson(data, &error); - if (error.error != QJsonParseError::NoError) { - qWarning() << "JSON parser error" << error.errorString(); - return QVariant(); - } - - QVariantMap response = jsonDoc.toVariant().toMap(); - - if (response.value("id").toInt() == m_commandCounter) { - m_commandCounter++; - return jsonDoc.toVariant(); - } - - m_commandCounter++; - return QVariant(); -} - -bool BaseTest::createRemoteConnection(const QString &token, const QString &nonce, QObject *parent) -{ - // Configure mock authenticator - m_mockAuthenticator->setTimeoutDuration(100); - m_mockAuthenticator->setExpectedAuthenticationError(); - - QString nameConnectionOne = "Test client one"; - QUuid uuidConnectionOne = QUuid::createUuid(); - - QString nameConnectionTwo = "Test client two"; - QUuid uuidConnectionTwo = QUuid::createUuid(); - - // QByteArray dataOne = "Hello from client one :-)"; - // QByteArray dataTwo = "Hello from client two :-)"; - - // Create two connection - RemoteProxyConnection *connectionOne = new RemoteProxyConnection(uuidConnectionOne, nameConnectionOne, parent); - connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(uuidConnectionTwo, nameConnectionTwo, parent); - connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - - // Connect one - QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - if (!connectionOne->connectServer(m_serverUrlProxyTcp)) { - qWarning() << "Could not connect client one"; - return false; - } - - connectionOneReadySpy.wait(); - if (connectionOneReadySpy.count() != 1) { - qWarning() << "Could not connect client one"; - return false; - } - - if (!connectionOne->isConnected()) { - qWarning() << "Could not connect client one"; - return false; - } - - // Connect two - QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - if (!connectionTwo->connectServer(m_serverUrlProxyTcp)) { - qWarning() << "Could not connect client two"; - return false; - } - - connectionTwoReadySpy.wait(); - if (connectionTwoReadySpy.count() != 1) { - qWarning() << "Could not connect client two"; - return false; - } - - if (!connectionTwo->isConnected()) { - qWarning() << "Could not connect client two"; - return false; - } - - // Authenticate one - QSignalSpy remoteConnectionEstablishedOne(connectionOne, &RemoteProxyConnection::remoteConnectionEstablished); - QSignalSpy connectionOneAuthenticatedSpy(connectionOne, &RemoteProxyConnection::authenticated); - if (!connectionOne->authenticate(token, nonce)) { - qWarning() << "Could not authenticate client one"; - return false; - } - - connectionOneAuthenticatedSpy.wait(); - if (connectionOneAuthenticatedSpy.count() != 1) { - qWarning() << "Could not authenticate client one"; - return false; - } - - if (connectionOne->state() != RemoteProxyConnection::StateAuthenticated) { - qWarning() << "Could not authenticate client one"; - return false; - } - - // Authenticate two - QSignalSpy remoteConnectionEstablishedTwo(connectionTwo, &RemoteProxyConnection::remoteConnectionEstablished); - QSignalSpy connectionTwoAuthenticatedSpy(connectionTwo, &RemoteProxyConnection::authenticated); - if (!connectionTwo->authenticate(token, nonce)) { - qWarning() << "Could not authenticate client two"; - return false; - } - - connectionTwoAuthenticatedSpy.wait(); - if (connectionTwoAuthenticatedSpy.count() != 1) { - qWarning() << "Could not authenticate client two"; - return false; - } - - if (connectionTwo->state() != RemoteProxyConnection::StateAuthenticated && connectionTwo->state() != RemoteProxyConnection::StateRemoteConnected) { - qWarning() << "Could not authenticate client two"; - return false; - } - - // Wait for both to be connected - if (remoteConnectionEstablishedOne.count() < 1) - remoteConnectionEstablishedOne.wait(); - - if (remoteConnectionEstablishedTwo.count() < 1) - remoteConnectionEstablishedTwo.wait(); - - if (remoteConnectionEstablishedOne.count() != 1 || remoteConnectionEstablishedTwo.count() != 1) { - qWarning() << "Could not establish remote connection"; - return false; - } - - if (connectionOne->state() != RemoteProxyConnection::StateRemoteConnected || connectionTwo->state() != RemoteProxyConnection::StateRemoteConnected) { - qWarning() << "Could not establish remote connection"; - return false; - } - - return true; -} - - -QVariant BaseTest::injectTcpSocketProxyData(const QByteArray &data) -{ - QSslSocket *socket = new QSslSocket(this); - typedef void (QSslSocket:: *sslErrorsSignal)(const QList &); - QObject::connect(socket, static_cast(&QSslSocket::sslErrors), this, &BaseTest::sslSocketSslErrors); - - QSignalSpy spyConnection(socket, &QSslSocket::connected); - socket->connectToHostEncrypted(Engine::instance()->tcpSocketServerProxy()->serverUrl().host(), - static_cast(Engine::instance()->tcpSocketServerProxy()->serverUrl().port())); - spyConnection.wait(); - if (spyConnection.count() == 0) { - return QVariant(); - } - - QSignalSpy dataSpy(socket, &QSslSocket::readyRead); - socket->write(data + '\n'); - dataSpy.wait(); - if (dataSpy.count() != 1) { - qWarning() << "No data received"; - return QVariant(); - } - - QByteArray socketData = socket->readAll(); - socket->close(); - socket->deleteLater(); - - // Make sure the response ends with '}\n' - if (!socketData.endsWith("}\n")) { - qWarning() << "JSON data does not end with \"}\n\""; - return QVariant(); - } - - // Make sure the response it a valid JSON string - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(socketData, &error); - if (error.error != QJsonParseError::NoError) { - qWarning() << "JSON parser error" << error.errorString(); - return QVariant(); - } - - m_commandCounter++; - return jsonDoc.toVariant(); -} QVariant BaseTest::invokeWebSocketTunnelProxyApiCall(const QString &method, const QVariantMap params) { @@ -858,22 +522,6 @@ QPair BaseTest::invokeWebSocketTunnelProxyApiCallPersist void BaseTest::initTestCase() { - qRegisterMetaType(); - qRegisterMetaType(); - - m_testToken = "eyJraWQiOiJXdnFFT3prVVh5VDlINzFyRUpoNWdxRnkxNFhnR2l3SFAzVEIzUFQ1V3ZrPSIsImFsZyI6IlJT" - "MjU2In0.eyJzdWIiOiJmZTJmZDNlNC1hMGJhLTQ1OTUtOWRiZS00ZDkxYjRiMjFlMzUiLCJhdWQiOiI4cmpoZ" - "mRsZjlqZjFzdW9rMmpjcmx0ZDZ2IiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImV2ZW50X2lkIjoiN2Y5NTRiNm" - "ItOTYyZi0xMWU4LWI0ZjItMzU5NWRiZmRiODVmIiwidG9rZW5fdXNlIjoiaWQiLCJhdXRoX3RpbWUiOjE1MzM" - "xOTkxMzgsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5ldS13ZXN0LTEuYW1hem9uYXdzLmNvbVwvZXUt" - "d2VzdC0xXzZlWDZZam1YciIsImNvZ25pdG86dXNlcm5hbWUiOiIyYzE3YzUwZC0xZDFlLTRhM2UtYmFjOS0zZ" - "DI0YjQ1MTFiYWEiLCJleHAiOjE1MzMyMDI3MzgsImlhdCI6MTUzMzE5OTEzOCwiZW1haWwiOiJqZW5raW5zQG" - "d1aC5pbyJ9.hMMSvZMx7pMvV70PaUmTZOZgdez5WGX5yagRFPZojBm8jNWZND1lUmi0RFkybeD4HonDiKHxTF" - "_psyJoBVndgHbxYBBl3Np4gn0MxECWjvLxYzGxVBBkN24SqNUyAGkr0uFcZKkBecdtJlqNQnZN8Uk49twmODf" - "raRaRmGmKmRBAK1qDITpUgP6AWqH9xoJWaoDzt0kwJ3EtPxS7vL1PHqOaN8ggXA8Eq4iTCSfXU1HAXhIWJH9Y" - "pQbj58v1vktaAEATdmKmlzmcix-HJK9wWHRSuv3TsNa8DGxvcPOoeTu8Vql7krZ-y7Zu-s2WsgeP4VxyT80VE" - "T_xh6pMkOhE6g"; - qCDebug(dcApplication()) << "Init test case done."; } diff --git a/tests/testbase/basetest.h b/tests/testbase/basetest.h index 57cebbd..3fc51c7 100644 --- a/tests/testbase/basetest.h +++ b/tests/testbase/basetest.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -38,14 +38,9 @@ #include #include "jsonrpc/jsontypes.h" -#include "mockauthenticator.h" #include "proxyconfiguration.h" -#include "remoteproxyconnection.h" -#include "authentication/aws/awsauthenticator.h" -#include "authentication/dummy/dummyauthenticator.h" using namespace remoteproxy; -using namespace remoteproxyclient; class BaseTest : public QObject { @@ -56,25 +51,16 @@ public: protected: ProxyConfiguration *m_configuration = nullptr; - QUrl m_serverUrlProxyWebSocket = QUrl("wss://127.0.0.1:1212"); - QUrl m_serverUrlProxyTcp = QUrl("ssl://127.0.0.1:1213"); - QUrl m_serverUrlTunnelProxyWebSocket = QUrl("wss://127.0.0.1:2212"); QUrl m_serverUrlTunnelProxyTcp = QUrl("ssl://127.0.0.1:2213"); QSslConfiguration m_sslConfiguration; - Authenticator *m_authenticator = nullptr; - MockAuthenticator *m_mockAuthenticator = nullptr; - DummyAuthenticator *m_dummyAuthenticator = nullptr; - AwsAuthenticator *m_awsAuthenticator = nullptr; - QString m_testToken; int m_commandCounter = 0; void loadConfiguration(const QString &fileName); - void setAuthenticator(Authenticator *authenticator); void resetDebugCategories(); void addDebugCategory(const QString &debugCategory); @@ -85,12 +71,6 @@ protected: void startServer(); void stopServer(); - QVariant invokeWebSocketProxyApiCall(const QString &method, const QVariantMap params = QVariantMap()); - QVariant injectWebSocketProxyData(const QByteArray &data); - - QVariant invokeTcpSocketProxyApiCall(const QString &method, const QVariantMap params = QVariantMap()); - QVariant injectTcpSocketProxyData(const QByteArray &data); - QVariant invokeWebSocketTunnelProxyApiCall(const QString &method, const QVariantMap params = QVariantMap()); QVariant injectWebSocketTunnelProxyData(const QByteArray &data); @@ -118,12 +98,6 @@ public slots: socket->ignoreSslErrors(); } - inline void ignoreConnectionSslError(const QList &errors) { - RemoteProxyConnection *connection = static_cast(sender()); - connection->ignoreSslErrors(errors); - connection->ignoreSslErrors(); - } - inline void verifyError(const QVariant &response, const QString &fieldName, const QString &error) { QJsonDocument jsonDoc = QJsonDocument::fromVariant(response); QVERIFY2(response.toMap().value("status").toString() == QString("success"), @@ -139,10 +113,6 @@ public slots: .toLatin1().data()); } - inline void verifyAuthenticationError(const QVariant &response, Authenticator::AuthenticationError error = Authenticator::AuthenticationErrorNoError) { - verifyError(response, "authenticationError", JsonTypes::authenticationErrorToString(error)); - } - inline void verifyTunnelProxyError(const QVariant &response, TunnelProxyServer::TunnelProxyError error = TunnelProxyServer::TunnelProxyErrorNoError) { verifyError(response, "tunnelProxyError", JsonTypes::tunnelProxyErrorToString(error)); } diff --git a/tests/testbase/mockauthenticator.cpp b/tests/testbase/mockauthenticator.cpp deleted file mode 100644 index ea6f897..0000000 --- a/tests/testbase/mockauthenticator.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "proxy/proxyclient.h" -#include "mockauthenticator.h" -#include "loggingcategories.h" -#include "authentication/authenticationreply.h" - -MockAuthenticator::MockAuthenticator(QObject *parent) : - Authenticator(parent) -{ - -} - -QString MockAuthenticator::name() const -{ - return "Mock authenticator"; -} - -void MockAuthenticator::setTimeoutDuration(int timeout) -{ - m_timeoutDuration = timeout; -} - -void MockAuthenticator::setExpectedAuthenticationError(Authenticator::AuthenticationError error) -{ - m_expectedError = error; -} - -void MockAuthenticator::replyFinished() -{ - MockAuthenticationReply *reply = static_cast(sender()); - - qCDebug(dcAuthentication()) << name() << "Authentication finished" << reply << reply->authenticationReply(); - setReplyError(reply->authenticationReply(), reply->error()); - setReplyFinished(reply->authenticationReply()); - reply->deleteLater(); -} - -AuthenticationReply *MockAuthenticator::authenticate(ProxyClient *proxyClient) -{ - qCDebug(dcAuthentication()) << name() << "Start authentication for" << proxyClient << "using token" << proxyClient->token() << "Auth duration" << m_timeoutDuration << "[ms]"; - - AuthenticationReply *authenticationReply = createAuthenticationReply(proxyClient, proxyClient); - - // Create mock authentication reply with the given configuration - MockAuthenticationReply *reply = new MockAuthenticationReply(m_timeoutDuration, m_expectedError, authenticationReply, proxyClient); - connect(reply, &MockAuthenticationReply::finished, this, &MockAuthenticator::replyFinished); - - return authenticationReply; -} - -MockAuthenticationReply::MockAuthenticationReply(int timeout, Authenticator::AuthenticationError error, AuthenticationReply *authenticationReply, QObject *parent) : - QObject(parent), - m_error(error), - m_authenticationReply(authenticationReply) - -{ - QTimer::singleShot(timeout, this, &MockAuthenticationReply::finished); -} - -MockAuthenticationReply::~MockAuthenticationReply() -{ - -} - diff --git a/tests/testbase/mockauthenticator.h b/tests/testbase/mockauthenticator.h deleted file mode 100644 index 77bae35..0000000 --- a/tests/testbase/mockauthenticator.h +++ /dev/null @@ -1,80 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under -* the terms of the GNU General Public License as published by the Free Software Foundation, -* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef MOCKAUTHENTICATOR_H -#define MOCKAUTHENTICATOR_H - -#include -#include - -#include "authentication/authenticator.h" - -using namespace remoteproxy; - -class MockAuthenticationReply : public QObject -{ - Q_OBJECT -public: - explicit MockAuthenticationReply(int timeout, Authenticator::AuthenticationError error, AuthenticationReply *authenticationReply, QObject *parent = nullptr); - ~MockAuthenticationReply(); - - AuthenticationReply *authenticationReply() const { return m_authenticationReply; } - Authenticator::AuthenticationError error() const { return m_error; } - -private: - Authenticator::AuthenticationError m_error; - AuthenticationReply *m_authenticationReply = nullptr; - -signals: - void finished(); - -}; - - -class MockAuthenticator : public Authenticator -{ - Q_OBJECT -public: - explicit MockAuthenticator(QObject *parent = nullptr); - - QString name() const override; - - void setTimeoutDuration(int timeout); - void setExpectedAuthenticationError(Authenticator::AuthenticationError error = AuthenticationErrorNoError); - -private: - int m_timeoutDuration = 500; - Authenticator::AuthenticationError m_expectedError; - -private slots: - void replyFinished(); - -public slots: - AuthenticationReply *authenticate(ProxyClient *proxyClient) override; -}; - -#endif // MOCKAUTHENTICATOR_H diff --git a/tests/testbase/testbase.pri b/tests/testbase/testbase.pri index 499da02..da2351e 100644 --- a/tests/testbase/testbase.pri +++ b/tests/testbase/testbase.pri @@ -13,10 +13,8 @@ LIBS += -L$$top_builddir/libnymea-remoteproxy/ -lnymea-remoteproxy \ -L$$top_builddir/libnymea-remoteproxyclient/ -lnymea-remoteproxyclient \ HEADERS += \ - $${PWD}/basetest.h \ - $${PWD}/mockauthenticator.h \ + $${PWD}/basetest.h SOURCES += \ - $${PWD}/basetest.cpp \ - $${PWD}/mockauthenticator.cpp \ + $${PWD}/basetest.cpp diff --git a/tests/tests.pro b/tests/tests.pro index 7d077d8..efc996a 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -1,10 +1,4 @@ include(../nymea-remoteproxy.pri) TEMPLATE=subdirs -SUBDIRS += test-proxy test-tunnelproxy - -#online { -# message("Online tests enabled") -# SUBDIRS += test-online -#} - +SUBDIRS += test-tunnelproxy diff --git a/tunnelclient/main.cpp b/tunnelclient/main.cpp index b392c95..c16485e 100644 --- a/tunnelclient/main.cpp +++ b/tunnelclient/main.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/version.h.in b/version.h.in index 19b8de2..a55cabb 100644 --- a/version.h.in +++ b/version.h.in @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2022, nymea GmbH +* Copyright 2013 - 2023, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea.