Add first client version for testing
parent
b2118c8efc
commit
2605e7a78a
307
README.md
307
README.md
|
|
@ -1,307 +0,0 @@
|
|||
# nymea remote proxy server
|
||||
----------------------------------------------
|
||||
|
||||
The nymea remote proxy server is the meeting point of nymea servers and nymea clients in order to establishing a secure remote connection.
|
||||
|
||||
# Build
|
||||
|
||||
In order to build the proxy server you need to install the qt default package.
|
||||
|
||||
apt install qt5-default
|
||||
|
||||
Change into the source directory and run following commands
|
||||
|
||||
cd nymea-remoteproxy
|
||||
mkdir build
|
||||
cd build
|
||||
qmake ../
|
||||
make -j$(nproc)
|
||||
|
||||
In the build directory you can find the resulting library and binary files.
|
||||
|
||||
If you want to start the proxy server from the build directory, you need to export the library path before starting the application:
|
||||
|
||||
|
||||
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/libnymea-remoteproxy:$(pwd)/libnymea-remoteproxyclient
|
||||
$ ./server/nymea-remoteproxy -c ../nymea-remoteproxy/tests/test-certificate.crt -k ../nymea-remoteproxy/tests/test-certificate.key
|
||||
|
||||
|
||||
## AWS SDK
|
||||
|
||||
Get the latest source code and build dependecies
|
||||
|
||||
$ apt update
|
||||
$ apt install git build-essential cmake libcurl4-openssl-dev libssl-dev uuid-dev zlib1g-dev libpulse-dev
|
||||
|
||||
$ git clone https://github.com/aws/aws-sdk-cpp.git
|
||||
|
||||
Create the build and install folder
|
||||
|
||||
$ cd aws-sdk-cpp
|
||||
$ mkdir -p build/install
|
||||
$ cd build
|
||||
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_ONLY="lambda" -DCMAKE_INSTALL_PREFIX=$(pwd)/install ../
|
||||
$ make -j$(nproc)
|
||||
|
||||
Install build output into install directory
|
||||
|
||||
$ make install
|
||||
|
||||
#### Building debian package
|
||||
|
||||
$ git clone https://github.com/aws/aws-sdk-cpp.git
|
||||
$ cd aws-sdk-cpp
|
||||
|
||||
$ git clone git@gitlab.guh.io:cloud/aws-sdk-cpp-debian.git debian
|
||||
|
||||
$ crossbuilder
|
||||
|
||||
|
||||
# Install
|
||||
|
||||
|
||||
|
||||
# Configure
|
||||
|
||||
|
||||
|
||||
# Test
|
||||
|
||||
In order to run the test, you can call `make check` in the build directory or run the resulting executable:
|
||||
|
||||
$ nymea-remoteproxy-tests
|
||||
|
||||
|
||||
## Test coverage report
|
||||
|
||||
If you want to create a line coverage report from the tests simply run following command in the source directory:
|
||||
|
||||
|
||||
$ apt install lcov gcovr
|
||||
$ ./create-coverage-html.sh
|
||||
|
||||
The resulting coverage report will be place in the `coverage-html` directory.
|
||||
|
||||
# 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.
|
||||
|
||||
Server version: 0.0.1
|
||||
API version: 0.1
|
||||
|
||||
Copyright © 2018 Simon Stürz <simon.stuerz@guh.io>
|
||||
|
||||
|
||||
Options:
|
||||
-h, --help Displays this help.
|
||||
-v, --version Displays version information.
|
||||
-l, --logging <logfile> Write log file to the given logfile.
|
||||
-s, --server <hostaddress> The server address this proxy will
|
||||
listen on. Default is 127.0.0.1
|
||||
-p, --port <port> The proxy server port. Default is
|
||||
1212
|
||||
-c, --certificate <certificate> The path to the SSL certificate used
|
||||
for this proxy server.
|
||||
-k, --certificate-key <certificate-key> The path to the SSL certificate key
|
||||
used for this proxy server.
|
||||
-a, --authentication-server <url> The server url of the AWS
|
||||
authentication server.
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
## 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.1",
|
||||
"name": "nymea-remoteproxy-testserver",
|
||||
"server": "nymea-remoteproxy",
|
||||
"version": "0.0.1"
|
||||
},
|
||||
"status": "success"
|
||||
}
|
||||
|
||||
## 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.
|
||||
|
||||
#### Request
|
||||
|
||||
{
|
||||
"id": 1,
|
||||
"method": "Authentication.Authenticate",
|
||||
"params": {
|
||||
"id": "string",
|
||||
"name": "string",
|
||||
"token": "tokenstring"
|
||||
}
|
||||
}
|
||||
|
||||
#### 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": 0,
|
||||
"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",
|
||||
"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",
|
||||
"AuthenticationErrorAuthenticationServerNotResponding"
|
||||
],
|
||||
"BasicType": [
|
||||
"Uuid",
|
||||
"String",
|
||||
"Int",
|
||||
"UInt",
|
||||
"Double",
|
||||
"Bool",
|
||||
"Variant",
|
||||
"Object"
|
||||
]
|
||||
}
|
||||
},
|
||||
"status": "success"
|
||||
}
|
||||
|
||||
|
||||
# License
|
||||
|
||||
This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
include(../nymea-remoteproxy.pri)
|
||||
include(../libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri)
|
||||
|
||||
TARGET = nymea-remoteproxy-client
|
||||
TEMPLATE = app
|
||||
|
|
|
|||
|
|
@ -1,19 +1,11 @@
|
|||
#include <QDir>
|
||||
#include <QUrl>
|
||||
#include <QtDebug>
|
||||
#include <QSslKey>
|
||||
#include <QDateTime>
|
||||
#include <QFileInfo>
|
||||
#include <QTextStream>
|
||||
#include <QMessageLogger>
|
||||
#include <QSslCertificate>
|
||||
#include <QCoreApplication>
|
||||
#include <QCoreApplication>
|
||||
#include <QLoggingCategory>
|
||||
#include <QSslConfiguration>
|
||||
#include <QCommandLineParser>
|
||||
#include <QCommandLineOption>
|
||||
|
||||
#include "proxyclient.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
|
|
@ -38,10 +30,15 @@ int main(int argc, char *argv[])
|
|||
QCommandLineOption tokenOption(QStringList() << "t" << "token", "The AWS token for authentication.", "token");
|
||||
parser.addOption(tokenOption);
|
||||
|
||||
|
||||
parser.process(application);
|
||||
|
||||
if (!parser.isSet(tokenOption)) {
|
||||
qWarning() << "Please specify the token for authentication." << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ProxyClient client;
|
||||
client.start(parser.value(tokenOption));
|
||||
|
||||
return application.exec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,34 @@
|
|||
#include "proxyclient.h"
|
||||
|
||||
ProxyClient::ProxyClient(QObject *parent) : QObject(parent)
|
||||
|
||||
ProxyClient::ProxyClient(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
m_connection = new RemoteProxyConnection(QUuid::createUuid(), "nymea-remoteproxy-client", RemoteProxyConnection::ConnectionTypeWebSocket, this);
|
||||
m_connection->setInsecureConnection(true);
|
||||
connect(m_connection, &RemoteProxyConnection::ready, this, &ProxyClient::onClientReady);
|
||||
connect(m_connection, &RemoteProxyConnection::authenticated, this, &ProxyClient::onAuthenticationFinished);
|
||||
connect(m_connection, &RemoteProxyConnection::errorOccured, this, &ProxyClient::onErrorOccured);
|
||||
|
||||
}
|
||||
|
||||
void ProxyClient::onErrorOccured(RemoteProxyConnection::Error error)
|
||||
{
|
||||
qDebug() << "Error occured" << error << m_connection->errorString();
|
||||
}
|
||||
|
||||
void ProxyClient::onClientReady()
|
||||
{
|
||||
m_connection->authenticate(m_token);
|
||||
}
|
||||
|
||||
void ProxyClient::onAuthenticationFinished()
|
||||
{
|
||||
qDebug() << "Authentication finished.";
|
||||
}
|
||||
|
||||
void ProxyClient::start(const QString &token)
|
||||
{
|
||||
m_token = token;
|
||||
m_connection->connectServer(m_hostAddress, static_cast<quint16>(m_port));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
#include "remoteproxyconnection.h"
|
||||
|
||||
using namespace remoteproxyclient;
|
||||
|
||||
class ProxyClient : public QObject
|
||||
{
|
||||
|
|
@ -10,9 +13,27 @@ class ProxyClient : public QObject
|
|||
public:
|
||||
explicit ProxyClient(QObject *parent = nullptr);
|
||||
|
||||
void setHostAddress(const QHostAddress &hostAddress);
|
||||
void setPort(const int &port);
|
||||
|
||||
private:
|
||||
QString m_token;
|
||||
QHostAddress m_hostAddress = QHostAddress::LocalHost;
|
||||
int m_port = 1212;
|
||||
|
||||
RemoteProxyConnection *m_connection = nullptr;
|
||||
|
||||
signals:
|
||||
|
||||
|
||||
private slots:
|
||||
void onErrorOccured(RemoteProxyConnection::Error error);
|
||||
void onClientReady();
|
||||
void onAuthenticationFinished();
|
||||
|
||||
public slots:
|
||||
void start(const QString &token);
|
||||
|
||||
};
|
||||
|
||||
#endif // PROXYCLIENT_H
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "loggingcategories.h"
|
||||
|
||||
#include <QUrl>
|
||||
#include <QFile>
|
||||
#include <QNetworkReply>
|
||||
#include <QJsonDocument>
|
||||
|
||||
|
|
@ -11,7 +12,9 @@ AuthenticationProcess::AuthenticationProcess(QNetworkAccessManager *manager, QOb
|
|||
QObject(parent),
|
||||
m_manager(manager)
|
||||
{
|
||||
|
||||
m_process = new QProcess(this);
|
||||
m_process->setProcessChannelMode(QProcess::MergedChannels);
|
||||
connect(m_process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &AuthenticationProcess::onProcessFinished);
|
||||
}
|
||||
|
||||
void AuthenticationProcess::useDynamicCredentials(bool dynamicCredentials)
|
||||
|
|
@ -28,20 +31,14 @@ void AuthenticationProcess::requestDynamicCredentials()
|
|||
void AuthenticationProcess::startVerificationProcess()
|
||||
{
|
||||
if (m_process->state() != QProcess::NotRunning) {
|
||||
qCWarning(dcAuthenticator()) << "Authentication process already running. Killing the running process and restart.";
|
||||
qCWarning(dcAuthenticationProcess()) << "Authentication process already running. Killing the running process and restart.";
|
||||
m_process->kill();
|
||||
m_process->deleteLater();
|
||||
m_process = nullptr;
|
||||
}
|
||||
|
||||
m_process = new QProcess(this);
|
||||
connect(m_process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &AuthenticationProcess::onProcessFinished);
|
||||
|
||||
// Create request map
|
||||
QVariantMap request;
|
||||
request.insert("token", m_token);
|
||||
|
||||
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
env.insert("AWS_DEFAULT_REGION", "eu-west-1");
|
||||
|
||||
|
|
@ -51,15 +48,15 @@ void AuthenticationProcess::startVerificationProcess()
|
|||
env.insert("AWS_SESSION_TOKEN", m_awsSessionToken);
|
||||
}
|
||||
|
||||
// Output file name
|
||||
// FIXME: check how to clean this up properly
|
||||
m_resultFileName = "/tmp/" + QUuid::createUuid().toString().remove("{").remove("}").remove("-") + ".json";
|
||||
|
||||
qCDebug(dcAuthenticator()) << "Start authenticator process and store result in" << m_resultFileName;
|
||||
qCDebug(dcAuthentication()) << "Start authenticator process and store result in" << m_resultFileName;
|
||||
|
||||
m_process->start("aws", { "lambda", "invoke",
|
||||
"--function-name", "system-services-authorizer-dev-checkToken",
|
||||
"--invocation-type", "RequestResponse",
|
||||
"--payload", QString("'%1'").arg(QString::fromUtf8(QJsonDocument::fromVariant(request).toJson())),
|
||||
"--payload", QString::fromUtf8(QJsonDocument::fromVariant(request).toJson()),
|
||||
m_resultFileName });
|
||||
|
||||
}
|
||||
|
|
@ -70,7 +67,7 @@ void AuthenticationProcess::onDynamicCredentialsReady()
|
|||
reply->deleteLater();
|
||||
|
||||
if (reply->error()) {
|
||||
qCWarning(dcAuthenticator()) << "Dynamic credentials reply error: " << reply->errorString();
|
||||
qCWarning(dcAuthenticationProcess()) << "Dynamic credentials reply error: " << reply->errorString();
|
||||
emit authenticationFinished(Authenticator::AuthenticationErrorProxyError);
|
||||
return;
|
||||
}
|
||||
|
|
@ -81,14 +78,13 @@ void AuthenticationProcess::onDynamicCredentialsReady()
|
|||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
if(error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcAuthenticator()) << "Failed to parse dynamic credentials reply data" << data << ":" << error.errorString();
|
||||
qCWarning(dcAuthenticationProcess()) << "Failed to parse dynamic credentials reply data" << data << ":" << error.errorString();
|
||||
emit authenticationFinished(Authenticator::AuthenticationErrorProxyError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QVariantMap response = jsonDoc.toVariant().toMap();
|
||||
qCDebug(dcAuthenticator()) << "-->" << response;
|
||||
qCDebug(dcAuthentication()) << "-->" << response;
|
||||
|
||||
m_awsAccessKeyId = response.value("AccessKeyId").toString();
|
||||
m_awsSecretAccessKey = response.value("SecretAccessKey").toString();
|
||||
|
|
@ -99,18 +95,75 @@ void AuthenticationProcess::onDynamicCredentialsReady()
|
|||
|
||||
void AuthenticationProcess::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
qCDebug(dcAuthenticator()) << "Authentication process finished" << exitCode << exitStatus;
|
||||
|
||||
if (exitStatus == QProcess::CrashExit) {
|
||||
qCWarning(dcAuthenticationProcess()) << "Authentication process crashed:" << endl << qUtf8Printable(m_process->readAll());
|
||||
}
|
||||
|
||||
if (exitCode != 0) {
|
||||
qCWarning(dcAuthenticationProcess()) << "The authentication process finished with error" << exitCode << endl << qUtf8Printable(m_process->readAll());
|
||||
}
|
||||
|
||||
qCDebug(dcAuthenticationProcess()) << "Finished successfully";
|
||||
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();
|
||||
|
||||
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) {
|
||||
emit authenticationFinished(Authenticator::AuthenticationErrorNoError);
|
||||
} else {
|
||||
emit authenticationFinished(Authenticator::AuthenticationErrorAuthenticationFailed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AuthenticationProcess::authenticate(const QString &token)
|
||||
{
|
||||
qCDebug(dcAuthenticator()) << "Start authentication process for token";
|
||||
qCDebug(dcAuthenticationProcess()) << "Start authentication process for token" << token;
|
||||
m_token = token;
|
||||
|
||||
if (m_dynamicCredentials) {
|
||||
// Request the access information
|
||||
requestDynamicCredentials();
|
||||
} else {
|
||||
// Direct call aws cli and assume the credentials will be provided static
|
||||
startVerificationProcess();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ private:
|
|||
|
||||
void requestDynamicCredentials();
|
||||
void startVerificationProcess();
|
||||
void cleanUp();
|
||||
|
||||
signals:
|
||||
void authenticationFinished(Authenticator::AuthenticationError error);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ void AuthenticationReply::setError(Authenticator::AuthenticationError error)
|
|||
void AuthenticationReply::setFinished()
|
||||
{
|
||||
m_timer->stop();
|
||||
emit finished();
|
||||
// emit in next event loop
|
||||
QTimer::singleShot(0, this, &AuthenticationReply::finished);
|
||||
}
|
||||
|
||||
void AuthenticationReply::onTimeout()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ AwsAuthenticator::AwsAuthenticator(QObject *parent) :
|
|||
|
||||
AwsAuthenticator::~AwsAuthenticator()
|
||||
{
|
||||
qCDebug(dcAuthenticator()) << "Shutting down" << name();
|
||||
qCDebug(dcAuthentication()) << "Shutting down" << name();
|
||||
}
|
||||
|
||||
QString AwsAuthenticator::name() const
|
||||
|
|
@ -30,12 +30,12 @@ void AwsAuthenticator::onAuthenticationProcessFinished(Authenticator::Authentica
|
|||
setReplyError(reply, error);
|
||||
setReplyFinished(reply);
|
||||
|
||||
qCDebug(dcAuthenticator()) << "" << error;
|
||||
qCDebug(dcAuthentication()) << "" << error;
|
||||
}
|
||||
|
||||
AuthenticationReply *AwsAuthenticator::authenticate(ProxyClient *proxyClient)
|
||||
{
|
||||
qCDebug(dcAuthenticator()) << name() << "Start authenticating" << proxyClient << "using token" << proxyClient->token();
|
||||
qCDebug(dcAuthentication()) << name() << "Start authenticating" << proxyClient << "using token" << proxyClient->token();
|
||||
AuthenticationReply *reply = createAuthenticationReply(proxyClient, this);
|
||||
|
||||
AuthenticationProcess *process = new AuthenticationProcess(m_manager, this);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
#include "dummyauthenticator.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
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 enabled explitly!";
|
||||
AuthenticationReply *reply = createAuthenticationReply(proxyClient, this);
|
||||
|
||||
setReplyError(reply, AuthenticationErrorNoError);
|
||||
setReplyFinished(reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef DUMMYAUTHENTICATOR_H
|
||||
#define DUMMYAUTHENTICATOR_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "proxyclient.h"
|
||||
#include "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
|
||||
|
|
@ -26,7 +26,8 @@ HEADERS += \
|
|||
authentication/authenticationreply.h \
|
||||
proxyconfiguration.h \
|
||||
tunnelconnection.h \
|
||||
authentication/authenticationprocess.h
|
||||
authentication/authenticationprocess.h \
|
||||
authentication/dummyauthenticator.h
|
||||
|
||||
SOURCES += \
|
||||
engine.cpp \
|
||||
|
|
@ -45,7 +46,8 @@ SOURCES += \
|
|||
authentication/authenticationreply.cpp \
|
||||
proxyconfiguration.cpp \
|
||||
tunnelconnection.cpp \
|
||||
authentication/authenticationprocess.cpp
|
||||
authentication/authenticationprocess.cpp \
|
||||
authentication/dummyauthenticator.cpp
|
||||
|
||||
|
||||
# install header file with relative subdirectory
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ Q_LOGGING_CATEGORY(dcJsonRpc, "JsonRpc")
|
|||
Q_LOGGING_CATEGORY(dcJsonRpcTraffic, "JsonRpcTraffic")
|
||||
Q_LOGGING_CATEGORY(dcWebSocketServer, "WebSocketServer")
|
||||
Q_LOGGING_CATEGORY(dcWebSocketServerTraffic, "WebSocketServerTraffic")
|
||||
Q_LOGGING_CATEGORY(dcAuthenticator, "Authenticator")
|
||||
Q_LOGGING_CATEGORY(dcAuthentication, "Authentication")
|
||||
Q_LOGGING_CATEGORY(dcAuthenticationProcess, "AuthenticationProcess")
|
||||
Q_LOGGING_CATEGORY(dcProxyServer, "ProxyServer")
|
||||
Q_LOGGING_CATEGORY(dcProxyServerTraffic, "ProxyServerTraffic")
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ Q_DECLARE_LOGGING_CATEGORY(dcJsonRpc)
|
|||
Q_DECLARE_LOGGING_CATEGORY(dcJsonRpcTraffic)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcWebSocketServer)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcWebSocketServerTraffic)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcAuthenticator)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcAuthentication)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcAuthenticationProcess)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcProxyServer)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcProxyServerTraffic)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "loggingcategories.h"
|
||||
#include "proxyconfiguration.h"
|
||||
#include "authentication/awsauthenticator.h"
|
||||
#include "authentication/dummyauthenticator.h"
|
||||
|
||||
using namespace remoteproxy;
|
||||
|
||||
|
|
@ -96,7 +97,7 @@ int main(int argc, char *argv[])
|
|||
s_loggingFilters.insert("JsonRpcTraffic", true);
|
||||
s_loggingFilters.insert("WebSocketServer", true);
|
||||
s_loggingFilters.insert("WebSocketServerTraffic", false);
|
||||
s_loggingFilters.insert("Authenticator", true);
|
||||
s_loggingFilters.insert("Authentication", true);
|
||||
s_loggingFilters.insert("ProxyServer", true);
|
||||
|
||||
// command line parser
|
||||
|
|
@ -120,7 +121,10 @@ int main(int argc, char *argv[])
|
|||
"assumes there are static AWS credentials provided to aws-cli.");
|
||||
parser.addOption(developmentOption);
|
||||
|
||||
QCommandLineOption configOption(QStringList() << "c" <<"config", "The path to the proxy server configuration file. The default is /etc/nymea-remoteproxy/nymea-remoteproxy.conf", "configuration");
|
||||
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 /etc/nymea-remoteproxy/nymea-remoteproxy.conf", "configuration");
|
||||
configOption.setDefaultValue("/etc/nymea-remoteproxy/nymea-remoteproxy.conf");
|
||||
parser.addOption(configOption);
|
||||
|
||||
|
|
@ -194,21 +198,26 @@ int main(int argc, char *argv[])
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
qCDebug(dcApplication()) << "==========================================================";
|
||||
qCDebug(dcApplication()) << "Starting" << application.applicationName() << application.applicationVersion();
|
||||
qCDebug(dcApplication()) << "==========================================================";
|
||||
|
||||
if (parser.isSet(developmentOption)) {
|
||||
qCWarning(dcApplication()) << "##########################################################";
|
||||
qCWarning(dcApplication()) << "# DEVELOPMENT MODE #";
|
||||
qCWarning(dcApplication()) << "##########################################################";
|
||||
}
|
||||
|
||||
qCDebug(dcApplication()) << "==========================================================";
|
||||
qCDebug(dcApplication()) << "Starting" << application.applicationName() << application.applicationVersion();
|
||||
qCDebug(dcApplication()) << "==========================================================";
|
||||
|
||||
if (s_loggingEnabled)
|
||||
qCDebug(dcApplication()) << "Logging enabled. Writing logs to" << s_logFile.fileName();
|
||||
|
||||
// Create default authenticator
|
||||
AwsAuthenticator *authenticator = new AwsAuthenticator(nullptr);
|
||||
Authenticator *authenticator = nullptr;
|
||||
if (parser.isSet(mockAuthenticatorOption)) {
|
||||
authenticator = qobject_cast<Authenticator *>(new DummyAuthenticator(nullptr));
|
||||
} else {
|
||||
// Create default authenticator
|
||||
authenticator = qobject_cast<Authenticator *>(new AwsAuthenticator(nullptr));
|
||||
}
|
||||
|
||||
// Configure and start the engines
|
||||
Engine::instance()->setConfiguration(configuration);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ void MockAuthenticator::replyFinished()
|
|||
MockAuthenticationReply *reply = static_cast<MockAuthenticationReply *>(sender());
|
||||
reply->deleteLater();
|
||||
|
||||
qCDebug(dcAuthenticator()) << name() << "Authentication finished.";
|
||||
qCDebug(dcAuthentication()) << name() << "Authentication finished.";
|
||||
|
||||
setReplyError(reply->authenticationReply(), reply->error());
|
||||
setReplyFinished(reply->authenticationReply());
|
||||
|
|
@ -37,7 +37,7 @@ void MockAuthenticator::replyFinished()
|
|||
|
||||
AuthenticationReply *MockAuthenticator::authenticate(ProxyClient *proxyClient)
|
||||
{
|
||||
qCDebug(dcAuthenticator()) << name() << "Start authentication for" << proxyClient << "using token" << proxyClient->token();
|
||||
qCDebug(dcAuthentication()) << name() << "Start authentication for" << proxyClient << "using token" << proxyClient->token();
|
||||
|
||||
AuthenticationReply *authenticationReply = createAuthenticationReply(proxyClient, this);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue