Work on ssl socket fixes
This commit is contained in:
parent
b9ebc345a5
commit
f4b5fba91d
@ -1,5 +1,6 @@
|
|||||||
include(../nymea-remoteproxy.pri)
|
include(../nymea-remoteproxy.pri)
|
||||||
include(../libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri)
|
include(../libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri)
|
||||||
|
include(../common/common.pri)
|
||||||
|
|
||||||
TARGET = nymea-remoteproxy-client
|
TARGET = nymea-remoteproxy-client
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|||||||
@ -127,6 +127,9 @@ int main(int argc, char *argv[])
|
|||||||
QCommandLineOption uuidOption(QStringList() << "uuid", "The uuid of the client. If not specified, a new one will be created", "uuid");
|
QCommandLineOption uuidOption(QStringList() << "uuid", "The uuid of the client. If not specified, a new one will be created", "uuid");
|
||||||
parser.addOption(uuidOption);
|
parser.addOption(uuidOption);
|
||||||
|
|
||||||
|
QCommandLineOption tcpOption(QStringList() << "tcp", "Use TCP as tronsport instead of web sockets.");
|
||||||
|
parser.addOption(tcpOption);
|
||||||
|
|
||||||
QCommandLineOption verboseOption(QStringList() << "verbose", "Print more information about the connection.");
|
QCommandLineOption verboseOption(QStringList() << "verbose", "Print more information about the connection.");
|
||||||
parser.addOption(verboseOption);
|
parser.addOption(verboseOption);
|
||||||
|
|
||||||
@ -165,10 +168,17 @@ int main(int argc, char *argv[])
|
|||||||
uuid = QUuid::createUuid();
|
uuid = QUuid::createUuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyClient client(parser.value(nameOption), uuid);
|
if (parser.isSet(tcpOption)) {
|
||||||
client.setInsecure(parser.isSet(insecureOption));
|
ProxyClient client(parser.value(nameOption), uuid, RemoteProxyConnection::ConnectionTypeTcpSocket);
|
||||||
client.setPingpong(parser.isSet(pingPongOption));
|
client.setInsecure(parser.isSet(insecureOption));
|
||||||
client.start(serverUrl, parser.value(tokenOption), parser.value(nonceOption));
|
client.setPingpong(parser.isSet(pingPongOption));
|
||||||
|
client.start(serverUrl, parser.value(tokenOption), parser.value(nonceOption));
|
||||||
|
} else {
|
||||||
|
ProxyClient client(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));
|
||||||
|
}
|
||||||
|
|
||||||
return application.exec();
|
return application.exec();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,12 +31,12 @@
|
|||||||
|
|
||||||
Q_LOGGING_CATEGORY(dcProxyClient, "ProxyClient")
|
Q_LOGGING_CATEGORY(dcProxyClient, "ProxyClient")
|
||||||
|
|
||||||
ProxyClient::ProxyClient(const QString &name, const QUuid &uuid, QObject *parent) :
|
ProxyClient::ProxyClient(const QString &name, const QUuid &uuid, RemoteProxyConnection::ConnectionType connectionType, QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_name(name),
|
m_name(name),
|
||||||
m_uuid(uuid)
|
m_uuid(uuid)
|
||||||
{
|
{
|
||||||
m_connection = new RemoteProxyConnection(m_uuid, m_name, this);
|
m_connection = new RemoteProxyConnection(m_uuid, m_name, connectionType, this);
|
||||||
qCDebug(dcProxyClient()) << "Creating remote proxy connection" << m_name << m_uuid.toString();
|
qCDebug(dcProxyClient()) << "Creating remote proxy connection" << m_name << m_uuid.toString();
|
||||||
connect(m_connection, &RemoteProxyConnection::ready, this, &ProxyClient::onClientReady);
|
connect(m_connection, &RemoteProxyConnection::ready, this, &ProxyClient::onClientReady);
|
||||||
connect(m_connection, &RemoteProxyConnection::authenticated, this, &ProxyClient::onAuthenticationFinished);
|
connect(m_connection, &RemoteProxyConnection::authenticated, this, &ProxyClient::onAuthenticationFinished);
|
||||||
|
|||||||
@ -41,7 +41,7 @@ class ProxyClient : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ProxyClient(const QString &name, const QUuid &uuid, QObject *parent = nullptr);
|
explicit ProxyClient(const QString &name, const QUuid &uuid, RemoteProxyConnection::ConnectionType connectionType, QObject *parent = nullptr);
|
||||||
|
|
||||||
void setInsecure(bool insecure);
|
void setInsecure(bool insecure);
|
||||||
void setPingpong(bool enable);
|
void setPingpong(bool enable);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
INCLUDEPATH += $$PWD
|
#INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/slipdataprocessor.h
|
$$PWD/slipdataprocessor.h
|
||||||
|
|||||||
9
debian/control
vendored
9
debian/control
vendored
@ -55,6 +55,15 @@ Description: The nymea remote proxy client for testing
|
|||||||
The nymea remote proxy client for testing
|
The nymea remote proxy client for testing
|
||||||
|
|
||||||
|
|
||||||
|
Package: nymea-remoteproxy-tunnelclient
|
||||||
|
Architecture: any
|
||||||
|
Section: libs
|
||||||
|
Depends: ${shlibs:Depends},
|
||||||
|
${misc:Depends},
|
||||||
|
Description: The nymea remote proxy tunnel client for testing
|
||||||
|
The nymea remote proxy tunnel client for testing
|
||||||
|
|
||||||
|
|
||||||
Package: libnymea-remoteproxyclient
|
Package: libnymea-remoteproxyclient
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: libs
|
Section: libs
|
||||||
|
|||||||
1
debian/nymea-remoteproxy-tunnelclient.install.in
vendored
Normal file
1
debian/nymea-remoteproxy-tunnelclient.install.in
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
usr/bin/nymea-remoteproxy-tunnelclient
|
||||||
@ -151,11 +151,21 @@ void SslServer::incomingConnection(qintptr socketDescriptor)
|
|||||||
qCDebug(dcTcpSocketServer()) << "Incomming connection" << sslSocket;
|
qCDebug(dcTcpSocketServer()) << "Incomming connection" << sslSocket;
|
||||||
connect(sslSocket, &QSslSocket::readyRead, this, &SslServer::onSocketReadyRead);
|
connect(sslSocket, &QSslSocket::readyRead, this, &SslServer::onSocketReadyRead);
|
||||||
connect(sslSocket, &QSslSocket::disconnected, this, &SslServer::onClientDisconnected);
|
connect(sslSocket, &QSslSocket::disconnected, this, &SslServer::onClientDisconnected);
|
||||||
|
connect(sslSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
|
||||||
connect(sslSocket, &QSslSocket::encrypted, this, [this, sslSocket](){
|
connect(sslSocket, &QSslSocket::encrypted, this, [this, sslSocket](){
|
||||||
qCDebug(dcTcpSocketServer()) << "SSL encryption established for" << sslSocket;
|
qCDebug(dcTcpSocketServer()) << "SSL encryption established for" << sslSocket;
|
||||||
emit clientConnected(sslSocket);
|
emit clientConnected(sslSocket);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (QSslSocket:: *sslErrorsSignal)(const QList<QSslError> &);
|
||||||
|
connect(sslSocket, static_cast<sslErrorsSignal>(&QSslSocket::sslErrors), this, [](const QList<QSslError> &errors) {
|
||||||
|
qCWarning(dcTcpSocketServer()) << "SSL Errors happened in the client connections:";
|
||||||
|
foreach (const QSslError &error, errors) {
|
||||||
|
qCWarning(dcTcpSocketServer()) << "SSL Error:" << error.error() << error.errorString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!sslSocket->setSocketDescriptor(socketDescriptor)) {
|
if (!sslSocket->setSocketDescriptor(socketDescriptor)) {
|
||||||
qCWarning(dcTcpSocketServer()) << "Failed to set SSL socket descriptor.";
|
qCWarning(dcTcpSocketServer()) << "Failed to set SSL socket descriptor.";
|
||||||
delete sslSocket;
|
delete sslSocket;
|
||||||
@ -163,8 +173,9 @@ void SslServer::incomingConnection(qintptr socketDescriptor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_sslEnabled) {
|
if (m_sslEnabled) {
|
||||||
sslSocket->setSslConfiguration(m_config);
|
|
||||||
qCDebug(dcTcpSocketServer()) << "Start SSL encryption for" << sslSocket;
|
qCDebug(dcTcpSocketServer()) << "Start SSL encryption for" << sslSocket;
|
||||||
|
sslSocket->setSslConfiguration(m_config);
|
||||||
|
addPendingConnection(sslSocket);
|
||||||
sslSocket->startServerEncryption();
|
sslSocket->startServerEncryption();
|
||||||
} else {
|
} else {
|
||||||
emit clientConnected(sslSocket);
|
emit clientConnected(sslSocket);
|
||||||
@ -187,4 +198,9 @@ void SslServer::onSocketReadyRead()
|
|||||||
emit dataAvailable(sslSocket, data);
|
emit dataAvailable(sslSocket, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SslServer::onSocketError(QAbstractSocket::SocketError error)
|
||||||
|
{
|
||||||
|
qCWarning(dcTcpSocketServer()) << "Socket error occured" << error;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,7 @@ protected:
|
|||||||
private slots:
|
private slots:
|
||||||
void onClientDisconnected();
|
void onClientDisconnected();
|
||||||
void onSocketReadyRead();
|
void onSocketReadyRead();
|
||||||
|
void onSocketError(QAbstractSocket::SocketError);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
include(../common/common.pri)
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
|||||||
@ -4,10 +4,13 @@ TEMPLATE = lib
|
|||||||
TARGET = nymea-remoteproxyclient
|
TARGET = nymea-remoteproxyclient
|
||||||
target.path = $$[QT_INSTALL_LIBS]
|
target.path = $$[QT_INSTALL_LIBS]
|
||||||
|
|
||||||
include(../common/common.pri)
|
|
||||||
include(libnymea-remoteproxyclient.pri)
|
include(libnymea-remoteproxyclient.pri)
|
||||||
|
|
||||||
installheaders.files = remoteproxyconnection.h
|
installheaders.files = \
|
||||||
|
remoteproxyconnection.h \
|
||||||
|
tunnelproxy/tunnelproxyremoteconnection.h \
|
||||||
|
tunnelproxy/tunnelproxysocket.h \
|
||||||
|
tcpsocketconnection.h
|
||||||
installheaders.path = $$[QT_INSTALL_PREFIX]/include/nymea-remoteproxyclient/
|
installheaders.path = $$[QT_INSTALL_PREFIX]/include/nymea-remoteproxyclient/
|
||||||
|
|
||||||
INSTALLS += target installheaders
|
INSTALLS += target installheaders
|
||||||
|
|||||||
@ -39,9 +39,11 @@ TcpSocketConnection::TcpSocketConnection(QObject *parent) :
|
|||||||
connect(m_tcpSocket, &QSslSocket::disconnected, this, &TcpSocketConnection::onDisconnected);
|
connect(m_tcpSocket, &QSslSocket::disconnected, this, &TcpSocketConnection::onDisconnected);
|
||||||
connect(m_tcpSocket, &QSslSocket::encrypted, this, &TcpSocketConnection::onEncrypted);
|
connect(m_tcpSocket, &QSslSocket::encrypted, this, &TcpSocketConnection::onEncrypted);
|
||||||
connect(m_tcpSocket, &QSslSocket::readyRead, this, &TcpSocketConnection::onReadyRead);
|
connect(m_tcpSocket, &QSslSocket::readyRead, this, &TcpSocketConnection::onReadyRead);
|
||||||
connect(m_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
|
typedef void (QSslSocket:: *errorSignal)(QAbstractSocket::SocketError);
|
||||||
connect(m_tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
|
connect(m_tcpSocket, static_cast<errorSignal>(&QSslSocket::error), this, &TcpSocketConnection::onError);
|
||||||
connect(m_tcpSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SIGNAL(sslErrors(QList<QSslError>)));
|
connect(m_tcpSocket, &QSslSocket::stateChanged, this, &TcpSocketConnection::onStateChanged);
|
||||||
|
typedef void (QSslSocket:: *sslErrorsSignal)(const QList<QSslError> &);
|
||||||
|
QObject::connect(m_tcpSocket, static_cast<sslErrorsSignal>(&QSslSocket::sslErrors), this, &TcpSocketConnection::sslErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpSocketConnection::~TcpSocketConnection()
|
TcpSocketConnection::~TcpSocketConnection()
|
||||||
@ -109,12 +111,12 @@ void TcpSocketConnection::onReadyRead()
|
|||||||
void TcpSocketConnection::connectServer(const QUrl &serverUrl)
|
void TcpSocketConnection::connectServer(const QUrl &serverUrl)
|
||||||
{
|
{
|
||||||
setServerUrl(serverUrl);
|
setServerUrl(serverUrl);
|
||||||
qCDebug(dcRemoteProxyClientTcpSocket()) << "Connecting to" << this->serverUrl().toString();
|
|
||||||
|
|
||||||
if (serverUrl.scheme() == "tcp") {
|
if (serverUrl.scheme() == "tcp") {
|
||||||
|
qCDebug(dcRemoteProxyClientTcpSocket()) << "Connecting to" << this->serverUrl().toString();
|
||||||
m_tcpSocket->connectToHost(QHostAddress(this->serverUrl().host()), static_cast<quint16>(this->serverUrl().port()));
|
m_tcpSocket->connectToHost(QHostAddress(this->serverUrl().host()), static_cast<quint16>(this->serverUrl().port()));
|
||||||
} else {
|
} else {
|
||||||
m_ssl = true;
|
m_ssl = true;
|
||||||
|
qCDebug(dcRemoteProxyClientTcpSocket()) << "Connecting encrypted to" << this->serverUrl().toString();
|
||||||
m_tcpSocket->connectToHostEncrypted(this->serverUrl().host(), static_cast<quint16>(this->serverUrl().port()));
|
m_tcpSocket->connectToHostEncrypted(this->serverUrl().host(), static_cast<quint16>(this->serverUrl().port()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
#include "tcpsocketconnection.h"
|
#include "tcpsocketconnection.h"
|
||||||
#include "websocketconnection.h"
|
#include "websocketconnection.h"
|
||||||
#include "proxyjsonrpcclient.h"
|
#include "proxyjsonrpcclient.h"
|
||||||
#include "../common/slipdataprocessor.h"
|
#include "../../common/slipdataprocessor.h"
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(dcTunnelProxySocketServer, "dcTunnelProxySocketServer")
|
Q_LOGGING_CATEGORY(dcTunnelProxySocketServer, "dcTunnelProxySocketServer")
|
||||||
Q_LOGGING_CATEGORY(dcTunnelProxySocketServerTraffic, "dcTunnelProxySocketServerTraffic")
|
Q_LOGGING_CATEGORY(dcTunnelProxySocketServerTraffic, "dcTunnelProxySocketServerTraffic")
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
include(nymea-remoteproxy.pri)
|
include(nymea-remoteproxy.pri)
|
||||||
|
|
||||||
TEMPLATE=subdirs
|
TEMPLATE=subdirs
|
||||||
SUBDIRS += server client libnymea-remoteproxy libnymea-remoteproxyclient
|
SUBDIRS += server client tunnelclient libnymea-remoteproxy libnymea-remoteproxyclient
|
||||||
|
|
||||||
!disabletests {
|
!disabletests {
|
||||||
SUBDIRS += tests
|
SUBDIRS += tests
|
||||||
@ -13,6 +13,7 @@ SUBDIRS += server client libnymea-remoteproxy libnymea-remoteproxyclient
|
|||||||
|
|
||||||
server.depends = libnymea-remoteproxy
|
server.depends = libnymea-remoteproxy
|
||||||
client.depends = libnymea-remoteproxyclient
|
client.depends = libnymea-remoteproxyclient
|
||||||
|
tunnelclient.depends = libnymea-remoteproxyclient
|
||||||
tests.depends = libnymea-remoteproxy libnymea-remoteproxyclient
|
tests.depends = libnymea-remoteproxy libnymea-remoteproxyclient
|
||||||
|
|
||||||
test.commands = LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$$top_builddir/libnymea-remoteproxy:$$top_builddir/libnymea-remoteproxyclient \
|
test.commands = LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$$top_builddir/libnymea-remoteproxy:$$top_builddir/libnymea-remoteproxyclient \
|
||||||
|
|||||||
@ -923,7 +923,6 @@ void RemoteProxyTestsTunnelProxy::tunnelProxyEndToEndTest()
|
|||||||
QVERIFY(receivedTestData2 == testData2);
|
QVERIFY(receivedTestData2 == testData2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ** Remote connection 2 **
|
// ** Remote connection 2 **
|
||||||
|
|
||||||
QString clientTwoName = "Client two";
|
QString clientTwoName = "Client two";
|
||||||
@ -978,7 +977,6 @@ void RemoteProxyTestsTunnelProxy::tunnelProxyEndToEndTest()
|
|||||||
QVERIFY(!remoteConnectionOne->remoteConnected());
|
QVERIFY(!remoteConnectionOne->remoteConnected());
|
||||||
QVERIFY(!remoteConnectionTwo->remoteConnected());
|
QVERIFY(!remoteConnectionTwo->remoteConnected());
|
||||||
|
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
tunnelProxyServer->deleteLater();
|
tunnelProxyServer->deleteLater();
|
||||||
remoteConnectionOne->deleteLater();
|
remoteConnectionOne->deleteLater();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
RESOURCES += ../resources/resources.qrc
|
RESOURCES += ../resources/resources.qrc
|
||||||
|
|
||||||
include(../common/common.pri)
|
include(../../common/common.pri)
|
||||||
|
|
||||||
CONFIG += testcase
|
CONFIG += testcase
|
||||||
QT += testlib
|
QT += testlib
|
||||||
|
|||||||
6
tunnelclient/clientconnection.cpp
Normal file
6
tunnelclient/clientconnection.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "clientconnection.h"
|
||||||
|
|
||||||
|
ClientConnection::ClientConnection(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
16
tunnelclient/clientconnection.h
Normal file
16
tunnelclient/clientconnection.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef CLIENTCONNECTION_H
|
||||||
|
#define CLIENTCONNECTION_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class ClientConnection : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ClientConnection(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CLIENTCONNECTION_H
|
||||||
218
tunnelclient/main.cpp
Normal file
218
tunnelclient/main.cpp
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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 <QUrl>
|
||||||
|
#include <QUuid>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <QCommandLineOption>
|
||||||
|
|
||||||
|
#include "serverconnection.h"
|
||||||
|
#include "clientconnection.h"
|
||||||
|
|
||||||
|
static QHash<QString, bool> 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 tunnel client application. This application allowes to register as client"
|
||||||
|
"or server on the tunnel proxy interface.\n\n"
|
||||||
|
"Version: %1\n"
|
||||||
|
"API version: %2\n\n"
|
||||||
|
"Copyright %3 2021 nymea GmbH <developer@nymea.io>\n")
|
||||||
|
.arg(SERVER_VERSION_STRING)
|
||||||
|
.arg(API_VERSION_STRING)
|
||||||
|
.arg(QChar(0xA9)));
|
||||||
|
|
||||||
|
QCommandLineOption urlOption(QStringList() << "u" << "url", "The proxy server url. Default ssl://dev-remoteproxy.nymea.io:2213", "url");
|
||||||
|
urlOption.setDefaultValue("ssl://dev-remoteproxy.nymea.io:2213");
|
||||||
|
parser.addOption(urlOption);
|
||||||
|
|
||||||
|
QCommandLineOption insecureOption(QStringList() << "i" << "igore-ssl", "Ignore SSL certificate errors.");
|
||||||
|
parser.addOption(insecureOption);
|
||||||
|
|
||||||
|
QCommandLineOption serverOption(QStringList() << "s" << "server", "Connect as tunnel proxy server connection.");
|
||||||
|
parser.addOption(serverOption);
|
||||||
|
|
||||||
|
QCommandLineOption clientOption(QStringList() << "c" << "client", "Connect as tunnel proxy client connection. The server uuid is required.");
|
||||||
|
parser.addOption(clientOption);
|
||||||
|
|
||||||
|
QCommandLineOption nameOption(QStringList() << "n" << "name", "The name of the connecting client.", "name");
|
||||||
|
parser.addOption(nameOption);
|
||||||
|
|
||||||
|
QCommandLineOption uuidOption(QStringList() << "u" << "uuid", "The uuid of the connecting client. If not specified, a new one will be created", "uuid");
|
||||||
|
parser.addOption(uuidOption);
|
||||||
|
|
||||||
|
QCommandLineOption serverUuidOption(QStringList() << "server-uuid", "The uuid of the server you want to connect to as client connection.");
|
||||||
|
parser.addOption(serverUuidOption);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Make sure not server and client given
|
||||||
|
if (parser.isSet(serverOption) && parser.isSet(clientOption)) {
|
||||||
|
qCritical() << "Please specify either beeing a client or a server connection, not both.";
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the uuid to pick for the connection
|
||||||
|
QUuid uuid(parser.value(uuidOption));
|
||||||
|
if (uuid.isNull()) {
|
||||||
|
uuid = QUuid::createUuid();
|
||||||
|
qDebug() << "Picking automatic UUID" << uuid.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl serverUrl(parser.value(urlOption));
|
||||||
|
if (!serverUrl.isValid()) {
|
||||||
|
qCritical() << "Invalid proxy server url passed." << parser.value(urlOption);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server, or if not specified server too
|
||||||
|
if (parser.isSet(serverOption) || (!parser.isSet(serverOption) && !parser.isSet(clientOption))) {
|
||||||
|
QString name = parser.value("name");
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
name = "Server connection";
|
||||||
|
qDebug() << "Picking automatic name" << name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable verbose
|
||||||
|
if (parser.isSet(verboseOption) || parser.isSet(veryVerboseOption)) {
|
||||||
|
s_loggingFilters["default"] = true;
|
||||||
|
s_loggingFilters["TunnelProxySocketServer"] = true;
|
||||||
|
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["TunnelProxySocketServerTraffic"] = true;
|
||||||
|
}
|
||||||
|
QLoggingCategory::installFilter(loggingCategoryFilter);
|
||||||
|
|
||||||
|
|
||||||
|
// Create the server connection
|
||||||
|
ServerConnection server(serverUrl, name, uuid, parser.isSet(insecureOption));
|
||||||
|
|
||||||
|
server.startServer();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Client
|
||||||
|
QString name = parser.value("name");
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
name = "Client connection";
|
||||||
|
qDebug() << "Picking automatic name" << name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parser.isSet(serverUuidOption)) {
|
||||||
|
qCritical() << "Please specify the server UUID you want to connect to using the --server-uuid parameter.";
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable verbose
|
||||||
|
if (parser.isSet(verboseOption) || parser.isSet(veryVerboseOption)) {
|
||||||
|
s_loggingFilters["default"] = true;
|
||||||
|
s_loggingFilters["TunnelProxyRemoteConnection"] = true;
|
||||||
|
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["TunnelProxySocketServerTraffic"] = true;
|
||||||
|
}
|
||||||
|
QLoggingCategory::installFilter(loggingCategoryFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return application.exec();
|
||||||
|
}
|
||||||
45
tunnelclient/serverconnection.cpp
Normal file
45
tunnelclient/serverconnection.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "serverconnection.h"
|
||||||
|
|
||||||
|
ServerConnection::ServerConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, bool insecure, QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
m_serverUrl(serverUrl),
|
||||||
|
m_name(name),
|
||||||
|
m_uuid(uuid),
|
||||||
|
m_insecure(insecure)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_socketServer = new TunnelProxySocketServer(m_uuid, m_name, this);
|
||||||
|
|
||||||
|
connect(m_socketServer, &TunnelProxySocketServer::clientConnected, this, [=](TunnelProxySocket *tunnelProxySocket){
|
||||||
|
qDebug() << "[+] Client connected" << tunnelProxySocket;
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_socketServer, &TunnelProxySocketServer::clientDisconnected, this, [=](TunnelProxySocket *tunnelProxySocket){
|
||||||
|
qDebug() << "[-] Client disconnected" << tunnelProxySocket;
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_socketServer, &TunnelProxySocketServer::runningChanged, this, [=](bool running){
|
||||||
|
qDebug() << "--> Server is" << (running ? "running" : "not running any more");
|
||||||
|
if (running) {
|
||||||
|
qDebug() << "--> Connected with" << m_socketServer->remoteProxyServer() << m_socketServer->remoteProxyServerName() << m_socketServer->remoteProxyServerVersion() << m_socketServer->remoteProxyApiVersion();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_socketServer, &TunnelProxySocketServer::sslErrors, this, [=](const QList<QSslError> &errors){
|
||||||
|
if (m_insecure) {
|
||||||
|
qDebug() << "SSL errors occured. Ignoring because explicit specified.";
|
||||||
|
m_socketServer->ignoreSslErrors();
|
||||||
|
} else {
|
||||||
|
qWarning() << "SSL errors occured:";
|
||||||
|
foreach (const QSslError &sslError, errors) {
|
||||||
|
qWarning() << " --> " << sslError.errorString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerConnection::startServer()
|
||||||
|
{
|
||||||
|
m_socketServer->startServer(m_serverUrl);
|
||||||
|
}
|
||||||
28
tunnelclient/serverconnection.h
Normal file
28
tunnelclient/serverconnection.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef SERVERCONNECTION_H
|
||||||
|
#define SERVERCONNECTION_H
|
||||||
|
|
||||||
|
#include <QUuid>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "tunnelproxy/tunnelproxysocketserver.h"
|
||||||
|
|
||||||
|
using namespace remoteproxyclient;
|
||||||
|
|
||||||
|
class ServerConnection : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ServerConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, bool insecure, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
void startServer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUrl m_serverUrl;
|
||||||
|
QString m_name;
|
||||||
|
QUuid m_uuid;
|
||||||
|
bool m_insecure = false;
|
||||||
|
|
||||||
|
TunnelProxySocketServer *m_socketServer = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SERVERCONNECTION_H
|
||||||
20
tunnelclient/tunnelclient.pro
Normal file
20
tunnelclient/tunnelclient.pro
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
include(../nymea-remoteproxy.pri)
|
||||||
|
include(../libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri)
|
||||||
|
|
||||||
|
TARGET = nymea-remoteproxy-tunnelclient
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
INCLUDEPATH += ../libnymea-remoteproxy
|
||||||
|
|
||||||
|
LIBS += -L$$top_builddir/libnymea-remoteproxyclient/ -lnymea-remoteproxyclient
|
||||||
|
|
||||||
|
SOURCES += main.cpp \
|
||||||
|
clientconnection.cpp \
|
||||||
|
serverconnection.cpp
|
||||||
|
|
||||||
|
target.path = $$[QT_INSTALL_PREFIX]/bin
|
||||||
|
INSTALLS += target
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
clientconnection.h \
|
||||||
|
serverconnection.h
|
||||||
Reference in New Issue
Block a user