summaryrefslogtreecommitdiffstats
path: root/src/BobinkClient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/BobinkClient.cpp')
-rw-r--r--src/BobinkClient.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/BobinkClient.cpp b/src/BobinkClient.cpp
index a067489..565868c 100644
--- a/src/BobinkClient.cpp
+++ b/src/BobinkClient.cpp
@@ -6,6 +6,7 @@
#include "BobinkAuth.h"
#include <QDir>
+#include <QOpcUaUserTokenPolicy>
#include <QStandardPaths>
BobinkClient *BobinkClient::s_instance = nullptr;
@@ -33,6 +34,8 @@ BobinkClient::BobinkClient(QObject *parent)
{
ensurePkiDirs(m_pkiDir);
setupClient();
+ autoDetectPki();
+ applyPki();
connect(&m_discoveryTimer, &QTimer::timeout, this, &BobinkClient::doDiscovery);
}
@@ -129,6 +132,65 @@ void BobinkClient::connectToServer()
m_client->requestEndpoints(url);
}
+static QString securityPolicyUri(BobinkClient::SecurityPolicy policy)
+{
+ switch (policy) {
+ case BobinkClient::Basic256Sha256:
+ return QStringLiteral(
+ "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256");
+ case BobinkClient::Aes128_Sha256_RsaOaep:
+ return QStringLiteral(
+ "http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep");
+ case BobinkClient::Aes256_Sha256_RsaPss:
+ return QStringLiteral(
+ "http://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPss");
+ }
+ return {};
+}
+
+void BobinkClient::connectDirect(SecurityPolicy policy, SecurityMode mode)
+{
+ if (!m_client) {
+ emit connectionError(QStringLiteral("OPC UA backend not available"));
+ return;
+ }
+ if (m_serverUrl.isEmpty()) {
+ emit connectionError(QStringLiteral("No server URL set"));
+ return;
+ }
+ if (m_client->state() != QOpcUaClient::Disconnected) {
+ emit connectionError(QStringLiteral("Already connected or connecting"));
+ return;
+ }
+
+ QOpcUaEndpointDescription endpoint;
+ endpoint.setEndpointUrl(m_serverUrl);
+ endpoint.setSecurityPolicy(securityPolicyUri(policy));
+ endpoint.setSecurityMode(
+ static_cast<QOpcUaEndpointDescription::MessageSecurityMode>(mode));
+
+ QOpcUaUserTokenPolicy tokenPolicy;
+ if (m_auth) {
+ switch (m_auth->mode()) {
+ case BobinkAuth::Anonymous:
+ tokenPolicy.setTokenType(QOpcUaUserTokenPolicy::TokenType::Anonymous);
+ break;
+ case BobinkAuth::UserPass:
+ tokenPolicy.setTokenType(QOpcUaUserTokenPolicy::TokenType::Username);
+ break;
+ case BobinkAuth::Certificate:
+ tokenPolicy.setTokenType(QOpcUaUserTokenPolicy::TokenType::Certificate);
+ break;
+ }
+ m_client->setAuthenticationInformation(m_auth->toAuthenticationInformation());
+ } else {
+ tokenPolicy.setTokenType(QOpcUaUserTokenPolicy::TokenType::Anonymous);
+ }
+ endpoint.setUserIdentityTokens({tokenPolicy});
+
+ m_client->connectToEndpoint(endpoint);
+}
+
void BobinkClient::disconnectFromServer()
{
if (m_client)
@@ -223,6 +285,23 @@ void BobinkClient::setKeyFile(const QString &path)
emit keyFileChanged();
}
+void BobinkClient::autoDetectPki()
+{
+ if (m_pkiDir.isEmpty())
+ return;
+
+ QDir certDir(m_pkiDir + QStringLiteral("/own/certs"));
+ QStringList certs = certDir.entryList({QStringLiteral("*.der")}, QDir::Files);
+ if (!certs.isEmpty())
+ setCertFile(certDir.filePath(certs.first()));
+
+ QDir keyDir(m_pkiDir + QStringLiteral("/own/private"));
+ QStringList keys = keyDir.entryList(
+ {QStringLiteral("*.pem"), QStringLiteral("*.crt")}, QDir::Files);
+ if (!keys.isEmpty())
+ setKeyFile(keyDir.filePath(keys.first()));
+}
+
void BobinkClient::applyPki()
{
if (!m_client || m_pkiDir.isEmpty())