Add insecure websocket support and start with tcp server support
This commit is contained in:
parent
df5a240189
commit
9fd2a3440f
@ -72,10 +72,10 @@ void Engine::start(ProxyConfiguration *configuration)
|
||||
Q_ASSERT_X(m_authenticator != nullptr, "Engine", "There is no authenticator registerd.");
|
||||
|
||||
m_proxyServer = new ProxyServer(this);
|
||||
m_webSocketServer = new WebSocketServer(m_configuration->sslConfiguration(), this);
|
||||
m_webSocketServer = new WebSocketServer(m_configuration->sslEnabled(), m_configuration->sslConfiguration(), this);
|
||||
|
||||
QUrl websocketServerUrl;
|
||||
websocketServerUrl.setScheme("wss");
|
||||
websocketServerUrl.setScheme(m_configuration->sslEnabled() ? "wss" : "ws");
|
||||
websocketServerUrl.setHost(m_configuration->webSocketServerHost().toString());
|
||||
websocketServerUrl.setPort(m_configuration->webSocketServerPort());
|
||||
|
||||
|
||||
@ -71,6 +71,7 @@ bool ProxyConfiguration::loadConfiguration(const QString &fileName)
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("SSL");
|
||||
setSslEnabled(settings.value("enabled", true).toBool());
|
||||
setSslCertificateFileName(settings.value("certificate", "/etc/ssl/certs/ssl-cert-snakeoil.pem").toString());
|
||||
setSslCertificateKeyFileName(settings.value("certificateKey", "/etc/ssl/private/ssl-cert-snakeoil.key").toString());
|
||||
setSslCertificateChainFileName(settings.value("certificateChain", "").toString());
|
||||
@ -256,6 +257,16 @@ void ProxyConfiguration::setAwsCredentialsUrl(const QUrl &url)
|
||||
m_awsCredentialsUrl = url;
|
||||
}
|
||||
|
||||
bool ProxyConfiguration::sslEnabled() const
|
||||
{
|
||||
return m_sslEnabled;
|
||||
}
|
||||
|
||||
void ProxyConfiguration::setSslEnabled(bool enabled)
|
||||
{
|
||||
m_sslEnabled = enabled;
|
||||
}
|
||||
|
||||
QString ProxyConfiguration::sslCertificateFileName() const
|
||||
{
|
||||
return m_sslCertificateFileName;
|
||||
@ -349,6 +360,7 @@ QDebug operator<<(QDebug debug, ProxyConfiguration *configuration)
|
||||
debug.nospace() << " - Authorizer lambda function:" << configuration->awsAuthorizerLambdaFunctionName() << endl;
|
||||
debug.nospace() << " - Credentials URL:" << configuration->awsCredentialsUrl().toString() << endl;
|
||||
debug.nospace() << "SSL configuration" << endl;
|
||||
debug.nospace() << " - Enabled:" << configuration->sslEnabled() << endl;
|
||||
debug.nospace() << " - Certificate:" << configuration->sslCertificateFileName() << endl;
|
||||
debug.nospace() << " - Certificate key:" << configuration->sslCertificateKeyFileName() << endl;
|
||||
debug.nospace() << " - Certificate chain:" << configuration->sslCertificateChainFileName() << endl;
|
||||
|
||||
@ -85,6 +85,9 @@ public:
|
||||
void setAwsCredentialsUrl(const QUrl &url);
|
||||
|
||||
// Ssl
|
||||
bool sslEnabled() const;
|
||||
void setSslEnabled(bool enabled);
|
||||
|
||||
QString sslCertificateFileName() const;
|
||||
void setSslCertificateFileName(const QString &fileName);
|
||||
|
||||
@ -130,6 +133,7 @@ private:
|
||||
QUrl m_awsCredentialsUrl;
|
||||
|
||||
// Ssl
|
||||
bool m_sslEnabled = true;
|
||||
QString m_sslCertificateFileName = "/etc/ssl/certs/ssl-cert-snakeoil.pem";
|
||||
QString m_sslCertificateKeyFileName = "/etc/ssl/private/ssl-cert-snakeoil.key";
|
||||
QString m_sslCertificateChainFileName;
|
||||
|
||||
@ -32,8 +32,9 @@
|
||||
|
||||
namespace remoteproxy {
|
||||
|
||||
WebSocketServer::WebSocketServer(const QSslConfiguration &sslConfiguration, QObject *parent) :
|
||||
WebSocketServer::WebSocketServer(bool sslEnabled, const QSslConfiguration &sslConfiguration, QObject *parent) :
|
||||
TransportInterface(parent),
|
||||
m_sslEnabled(sslEnabled),
|
||||
m_sslConfiguration(sslConfiguration)
|
||||
{
|
||||
m_serverName = "Websocket server";
|
||||
@ -181,8 +182,12 @@ void WebSocketServer::onServerError(QWebSocketProtocol::CloseCode closeCode)
|
||||
|
||||
bool WebSocketServer::startServer()
|
||||
{
|
||||
m_server = new QWebSocketServer(QCoreApplication::applicationName(), QWebSocketServer::SecureMode, this);
|
||||
m_server->setSslConfiguration(sslConfiguration());
|
||||
if (m_sslEnabled) {
|
||||
m_server = new QWebSocketServer(QCoreApplication::applicationName(), QWebSocketServer::SecureMode, this);
|
||||
m_server->setSslConfiguration(sslConfiguration());
|
||||
} else {
|
||||
m_server = new QWebSocketServer(QCoreApplication::applicationName(), QWebSocketServer::NonSecureMode, this);
|
||||
}
|
||||
|
||||
connect (m_server, &QWebSocketServer::newConnection, this, &WebSocketServer::onClientConnected);
|
||||
connect (m_server, &QWebSocketServer::acceptError, this, &WebSocketServer::onAcceptError);
|
||||
|
||||
@ -43,7 +43,7 @@ class WebSocketServer : public TransportInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WebSocketServer(const QSslConfiguration &sslConfiguration, QObject *parent = nullptr);
|
||||
explicit WebSocketServer(bool sslEnabled, const QSslConfiguration &sslConfiguration, QObject *parent = nullptr);
|
||||
~WebSocketServer() override;
|
||||
|
||||
QUrl serverUrl() const;
|
||||
@ -59,6 +59,7 @@ public:
|
||||
private:
|
||||
QUrl m_serverUrl;
|
||||
QWebSocketServer *m_server = nullptr;
|
||||
bool m_sslEnabled;
|
||||
QSslConfiguration m_sslConfiguration;
|
||||
bool m_enabled = false;
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
INCLUDEPATH += $${PWD}
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/tcpsocketconnection.h \
|
||||
$${PWD}/proxyjsonrpcclient.h \
|
||||
$${PWD}/jsonreply.h \
|
||||
$${PWD}/remoteproxyconnection.h \
|
||||
@ -8,6 +9,7 @@ HEADERS += \
|
||||
$${PWD}/websocketconnection.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/tcpsocketconnection.cpp \
|
||||
$${PWD}/proxyjsonrpcclient.cpp \
|
||||
$${PWD}/jsonreply.cpp \
|
||||
$${PWD}/remoteproxyconnection.cpp \
|
||||
|
||||
@ -34,6 +34,11 @@ ProxyConnection::ProxyConnection(QObject *parent) : QObject(parent)
|
||||
|
||||
}
|
||||
|
||||
QUrl ProxyConnection::serverUrl() const
|
||||
{
|
||||
return m_serverUrl;
|
||||
}
|
||||
|
||||
bool ProxyConnection::connected()
|
||||
{
|
||||
return m_connected;
|
||||
@ -48,6 +53,11 @@ void ProxyConnection::setConnected(bool connected)
|
||||
emit connectedChanged(m_connected);
|
||||
}
|
||||
|
||||
void ProxyConnection::setServerUrl(const QUrl &serverUrl)
|
||||
{
|
||||
m_serverUrl = serverUrl;
|
||||
}
|
||||
|
||||
ProxyConnection::~ProxyConnection()
|
||||
{
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#ifndef SOCKETCONNECTOR_H
|
||||
#define SOCKETCONNECTOR_H
|
||||
|
||||
#include <QUrl>
|
||||
#include <QObject>
|
||||
#include <QSslError>
|
||||
#include <QHostAddress>
|
||||
@ -43,7 +44,7 @@ public:
|
||||
|
||||
virtual void sendData(const QByteArray &data) = 0;
|
||||
|
||||
virtual QUrl serverUrl() const = 0;
|
||||
QUrl serverUrl() const;
|
||||
|
||||
virtual void ignoreSslErrors() = 0;
|
||||
virtual void ignoreSslErrors(const QList<QSslError> &errors) = 0;
|
||||
@ -52,9 +53,11 @@ public:
|
||||
|
||||
private:
|
||||
bool m_connected = false;
|
||||
QUrl m_serverUrl;
|
||||
|
||||
protected:
|
||||
void setConnected(bool connected);
|
||||
void setServerUrl(const QUrl &serverUrl);
|
||||
|
||||
signals:
|
||||
void connectedChanged(bool connected);
|
||||
|
||||
@ -43,6 +43,15 @@ RemoteProxyConnection::RemoteProxyConnection(const QUuid &clientUuid, const QStr
|
||||
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
|
||||
@ -69,6 +69,7 @@ public:
|
||||
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;
|
||||
@ -94,9 +95,9 @@ public:
|
||||
QString tunnelPartnerUuid() const;
|
||||
|
||||
private:
|
||||
ConnectionType m_connectionType = ConnectionTypeWebSocket;
|
||||
QUuid m_clientUuid;
|
||||
QString m_clientName;
|
||||
ConnectionType m_connectionType = ConnectionTypeWebSocket;
|
||||
|
||||
QUrl m_serverUrl;
|
||||
|
||||
|
||||
95
libnymea-remoteproxyclient/tcpsocketconnection.cpp
Normal file
95
libnymea-remoteproxyclient/tcpsocketconnection.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
#include "tcpsocketconnection.h"
|
||||
Q_LOGGING_CATEGORY(dcRemoteProxyClientTcpSocket, "RemoteProxyClientTcpSocket")
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
TcpSocketConnection::TcpSocketConnection(QObject *parent) :
|
||||
ProxyConnection(parent)
|
||||
{
|
||||
m_tcpSocket = new QSslSocket(this);
|
||||
|
||||
connect(m_tcpSocket, &QSslSocket::disconnected, this, &TcpSocketConnection::onDisconnected);
|
||||
connect(m_tcpSocket, &QSslSocket::encrypted, this, &TcpSocketConnection::onEncrypted);
|
||||
connect(m_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
|
||||
connect(m_tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
|
||||
connect(m_tcpSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SIGNAL(sslErrors(QList<QSslError>)));
|
||||
}
|
||||
|
||||
TcpSocketConnection::~TcpSocketConnection()
|
||||
{
|
||||
m_tcpSocket->close();
|
||||
}
|
||||
|
||||
void TcpSocketConnection::sendData(const QByteArray &data)
|
||||
{
|
||||
m_tcpSocket->write(data);
|
||||
}
|
||||
|
||||
void TcpSocketConnection::ignoreSslErrors()
|
||||
{
|
||||
m_tcpSocket->ignoreSslErrors();
|
||||
}
|
||||
|
||||
void TcpSocketConnection::ignoreSslErrors(const QList<QSslError> &errors)
|
||||
{
|
||||
m_tcpSocket->ignoreSslErrors(errors);
|
||||
}
|
||||
|
||||
void TcpSocketConnection::onDisconnected()
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientTcpSocket()) << "Disconnected from" << serverUrl().toString();
|
||||
setConnected(false);
|
||||
}
|
||||
|
||||
void TcpSocketConnection::onEncrypted()
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientTcpSocket()) << "Connection encrypted";
|
||||
}
|
||||
|
||||
void TcpSocketConnection::onError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientTcpSocket()) << "Socket error occured" << error << m_tcpSocket->errorString();
|
||||
emit errorOccured(error);
|
||||
}
|
||||
|
||||
void TcpSocketConnection::onStateChanged(QAbstractSocket::SocketState state)
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientTcpSocket()) << "Socket state changed" << state;
|
||||
|
||||
switch (state) {
|
||||
case QAbstractSocket::ConnectedState:
|
||||
qCDebug(dcRemoteProxyClientTcpSocket()) << "Connected with" << serverUrl().toString();
|
||||
setConnected(true);
|
||||
break;
|
||||
default:
|
||||
setConnected(false);
|
||||
break;
|
||||
}
|
||||
|
||||
emit stateChanged(state);
|
||||
}
|
||||
|
||||
void TcpSocketConnection::onReadyRead()
|
||||
{
|
||||
emit dataReceived(m_tcpSocket->readAll());
|
||||
}
|
||||
|
||||
void TcpSocketConnection::connectServer(const QUrl &serverUrl)
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientTcpSocket()) << "Connecting to" << this->serverUrl().toString();
|
||||
setServerUrl(serverUrl);
|
||||
|
||||
if (serverUrl.scheme() == "tcp") {
|
||||
m_tcpSocket->connectToHost(QHostAddress(this->serverUrl().host()), static_cast<quint16>(this->serverUrl().port()));
|
||||
} else {
|
||||
m_tcpSocket->connectToHostEncrypted(this->serverUrl().host(), static_cast<quint16>(this->serverUrl().port()));
|
||||
}
|
||||
}
|
||||
|
||||
void TcpSocketConnection::disconnectServer()
|
||||
{
|
||||
qCDebug(dcRemoteProxyClientTcpSocket()) << "Disconnecting from" << serverUrl().toString();
|
||||
m_tcpSocket->close();
|
||||
}
|
||||
|
||||
}
|
||||
46
libnymea-remoteproxyclient/tcpsocketconnection.h
Normal file
46
libnymea-remoteproxyclient/tcpsocketconnection.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef TCPSOCKETCONNECTION_H
|
||||
#define TCPSOCKETCONNECTION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTcpSocket>
|
||||
#include <QSslSocket>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include "proxyconnection.h"
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyClienTcpSocket)
|
||||
|
||||
namespace remoteproxyclient {
|
||||
|
||||
class TcpSocketConnection : public ProxyConnection
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TcpSocketConnection(QObject *parent = nullptr);
|
||||
~TcpSocketConnection() override;
|
||||
|
||||
void sendData(const QByteArray &data) override;
|
||||
|
||||
void ignoreSslErrors() override;
|
||||
void ignoreSslErrors(const QList<QSslError> &errors) override;
|
||||
|
||||
private:
|
||||
QSslSocket *m_tcpSocket = nullptr;
|
||||
|
||||
private slots:
|
||||
void onDisconnected();
|
||||
void onEncrypted();
|
||||
void onError(QAbstractSocket::SocketError error);
|
||||
void onStateChanged(QAbstractSocket::SocketState state);
|
||||
void onReadyRead();
|
||||
|
||||
public slots:
|
||||
void connectServer(const QUrl &serverUrl) override;
|
||||
void disconnectServer() override;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TCPSOCKETCONNECTION_H
|
||||
@ -49,11 +49,6 @@ WebSocketConnection::~WebSocketConnection()
|
||||
m_webSocket->close();
|
||||
}
|
||||
|
||||
QUrl WebSocketConnection::serverUrl() const
|
||||
{
|
||||
return m_serverUrl;
|
||||
}
|
||||
|
||||
void WebSocketConnection::sendData(const QByteArray &data)
|
||||
{
|
||||
m_webSocket->sendTextMessage(QString::fromUtf8(data + '\n'));
|
||||
@ -108,10 +103,10 @@ void WebSocketConnection::connectServer(const QUrl &serverUrl)
|
||||
if (connected()) {
|
||||
m_webSocket->close();
|
||||
}
|
||||
setServerUrl(serverUrl);
|
||||
|
||||
m_serverUrl = serverUrl;
|
||||
qCDebug(dcRemoteProxyClientWebSocket()) << "Connecting to" << m_serverUrl.toString();
|
||||
m_webSocket->open(m_serverUrl);
|
||||
qCDebug(dcRemoteProxyClientWebSocket()) << "Connecting to" << this->serverUrl().toString();
|
||||
m_webSocket->open(this->serverUrl());
|
||||
}
|
||||
|
||||
void WebSocketConnection::disconnectServer()
|
||||
|
||||
@ -46,15 +46,12 @@ public:
|
||||
explicit WebSocketConnection(QObject *parent = nullptr);
|
||||
~WebSocketConnection() override;
|
||||
|
||||
QUrl serverUrl() const override;
|
||||
|
||||
void sendData(const QByteArray &data) override;
|
||||
|
||||
void ignoreSslErrors() override;
|
||||
void ignoreSslErrors(const QList<QSslError> &errors) override;
|
||||
|
||||
private:
|
||||
QUrl m_serverUrl;
|
||||
QWebSocket *m_webSocket = nullptr;
|
||||
|
||||
private slots:
|
||||
|
||||
@ -15,6 +15,7 @@ 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=true
|
||||
certificate=/etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
certificateKey=/etc/ssl/private/ssl-cert-snakeoil.key
|
||||
certificateChain=
|
||||
|
||||
@ -186,9 +186,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Verify SSL configuration
|
||||
if (configuration->sslConfiguration().isNull()) {
|
||||
qCCritical(dcApplication()) << "No SSL configuration specified. The server does not suppoert insecure connections.";
|
||||
if (configuration->sslEnabled() && configuration->sslConfiguration().isNull()) {
|
||||
qCCritical(dcApplication()) << "SSL is enabled but no SSL configuration specified.";
|
||||
exit(-1);
|
||||
} else {
|
||||
qCDebug(dcApplication()) << "Using SSL version:" << QSslSocket::sslLibraryVersionString();
|
||||
}
|
||||
|
||||
qCDebug(dcApplication()) << "==========================================================";
|
||||
@ -203,7 +205,6 @@ int main(int argc, char *argv[])
|
||||
if (s_loggingEnabled)
|
||||
qCDebug(dcApplication()) << "Logging enabled. Writing logs to" << s_logFile.fileName();
|
||||
|
||||
qCDebug(dcApplication()) << "Using SSL version:" << QSslSocket::sslLibraryVersionString();
|
||||
|
||||
Authenticator *authenticator = nullptr;
|
||||
if (parser.isSet(mockAuthenticatorOption)) {
|
||||
|
||||
Reference in New Issue
Block a user