aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-17 14:59:05 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-17 14:59:05 +0100
commit19e4a435c122a5eed34154ecfbbd3314a0789bc5 (patch)
tree67a6c2ea869189a6bba3c5b7115dbfa1174cc428
parentff1e0c9ba8e6c42457b34bfbac2bda1dbbffb91b (diff)
downloadBobinkCOpcUa-19e4a435c122a5eed34154ecfbbd3314a0789bc5.tar.gz
BobinkCOpcUa-19e4a435c122a5eed34154ecfbbd3314a0789bc5.zip
Decouple LDS and server clients in ClientFindServers
Create two independent UA_Client instances in client_find_servers.c: one for LDS discovery calls (FindServers, GetEndpoints) and one for server session calls (readServerTime). This allows different security modes, policies, auth, and trust lists for the LDS vs discovered servers. Config keys are now prefixed: discovery* for LDS connection settings, server* for discovered server settings. All config files updated accordingly with split trust lists (discoveryTrustList for LDS cert, serverTrustList for server cert).
-rw-r--r--config/client_find_servers.conf61
-rw-r--r--src/client_find_servers.c179
-rw-r--r--tests/aes128_anon/client_find_servers.conf22
-rw-r--r--tests/aes128_user/client_find_servers.conf28
-rw-r--r--tests/basic256sha256_anon/client_find_servers.conf22
-rw-r--r--tests/basic256sha256_user/client_find_servers.conf28
-rw-r--r--tests/none_anon/client_find_servers.conf22
-rw-r--r--tests/none_user/client_find_servers.conf28
8 files changed, 272 insertions, 118 deletions
diff --git a/config/client_find_servers.conf b/config/client_find_servers.conf
index a9e29c8..bc16b18 100644
--- a/config/client_find_servers.conf
+++ b/config/client_find_servers.conf
@@ -1,29 +1,50 @@
# ClientFindServers configuration
#
-# Keys:
+# Shared keys:
# discoveryEndpoint LDS endpoint URL (e.g. opc.tcp://localhost:4840)
# applicationUri OPC UA application URI
-# certificate Path to client certificate (.der)
-# privateKey Path to client private key (.der)
-# securityMode None, Sign, or SignAndEncrypt
-# securityPolicy None, Basic256Sha256, Aes256_Sha256_RsaPss,
-# Aes128_Sha256_RsaOaep, or ECC_nistP256
-# authMode "anonymous" or "user"
-# username Username (required when authMode = user)
-# password Password (required when authMode = user)
-# trustList Trusted certificate path (repeat for multiple)
+#
+# Discovery-side keys (LDS connection):
+# discoveryCertificate Path to certificate for LDS connections (.der)
+# discoveryPrivateKey Path to private key for LDS connections (.der)
+# discoverySecurityMode None, Sign, or SignAndEncrypt
+# discoverySecurityPolicy None, Basic256Sha256, Aes256_Sha256_RsaPss,
+# Aes128_Sha256_RsaOaep, or ECC_nistP256
+# discoveryAuthMode "anonymous" or "user"
+# discoveryUsername Username (required when discoveryAuthMode = user)
+# discoveryPassword Password (required when discoveryAuthMode = user)
+# discoveryTrustList Trusted certificate path (repeat for multiple)
+#
+# Server-side keys (connections to discovered servers):
+# serverCertificate Path to certificate for server connections (.der)
+# serverPrivateKey Path to private key for server connections (.der)
+# serverSecurityMode None, Sign, or SignAndEncrypt
+# serverSecurityPolicy None, Basic256Sha256, Aes256_Sha256_RsaPss,
+# Aes128_Sha256_RsaOaep, or ECC_nistP256
+# serverAuthMode "anonymous" or "user"
+# serverUsername Username (required when serverAuthMode = user)
+# serverPassword Password (required when serverAuthMode = user)
+# serverTrustList Trusted certificate path (repeat for multiple)
discoveryEndpoint = opc.tcp://localhost:4840
applicationUri = urn:bobink.ClientFindServers
-certificate = certs/ClientFindServers_cert.der
-privateKey = certs/ClientFindServers_key.der
-
-securityMode = SignAndEncrypt
-securityPolicy = Aes128_Sha256_RsaOaep
-authMode = user
-username = user
-password = password
+# Discovery (LDS) side
+discoveryCertificate = certs/ClientFindServers_cert.der
+discoveryPrivateKey = certs/ClientFindServers_key.der
+discoverySecurityMode = SignAndEncrypt
+discoverySecurityPolicy = Aes128_Sha256_RsaOaep
+discoveryAuthMode = user
+discoveryUsername = user
+discoveryPassword = password
+discoveryTrustList = certs/ServerLDS_cert.der
-trustList = certs/ServerLDS_cert.der
-trustList = certs/ServerRegister_cert.der
+# Server side
+serverCertificate = certs/ClientFindServers_cert.der
+serverPrivateKey = certs/ClientFindServers_key.der
+serverSecurityMode = SignAndEncrypt
+serverSecurityPolicy = Aes128_Sha256_RsaOaep
+serverAuthMode = user
+serverUsername = user
+serverPassword = password
+serverTrustList = certs/ServerRegister_cert.der
diff --git a/src/client_find_servers.c b/src/client_find_servers.c
index a85b63f..2212026 100644
--- a/src/client_find_servers.c
+++ b/src/client_find_servers.c
@@ -233,56 +233,110 @@ main (int argc, char **argv)
if (configLoad (argv[1], &cfg) != 0)
return EXIT_FAILURE;
+ /* ---- Shared keys ---- */
+
const char *discoveryServerEndpoint
= configRequire (&cfg, "discoveryEndpoint", "ClientFindServers");
const char *applicationUri
= configRequire (&cfg, "applicationUri", "ClientFindServers");
- const char *certPath
- = configRequire (&cfg, "certificate", "ClientFindServers");
- const char *keyPath
- = configRequire (&cfg, "privateKey", "ClientFindServers");
- const char *securityModeStr
- = configRequire (&cfg, "securityMode", "ClientFindServers");
- const char *securityPolicyStr
- = configRequire (&cfg, "securityPolicy", "ClientFindServers");
- const char *authMode = configRequire (&cfg, "authMode", "ClientFindServers");
-
- if (!discoveryServerEndpoint || !applicationUri || !certPath || !keyPath
- || !securityModeStr || !securityPolicyStr || !authMode)
+
+ if (!discoveryServerEndpoint || !applicationUri)
+ {
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ /* ---- Discovery-side config (LDS connection) ---- */
+
+ const char *discCertPath
+ = configRequire (&cfg, "discoveryCertificate", "ClientFindServers");
+ const char *discKeyPath
+ = configRequire (&cfg, "discoveryPrivateKey", "ClientFindServers");
+ const char *discSecModeStr
+ = configRequire (&cfg, "discoverySecurityMode", "ClientFindServers");
+ const char *discSecPolStr
+ = configRequire (&cfg, "discoverySecurityPolicy", "ClientFindServers");
+ const char *discAuthMode
+ = configRequire (&cfg, "discoveryAuthMode", "ClientFindServers");
+
+ if (!discCertPath || !discKeyPath || !discSecModeStr || !discSecPolStr
+ || !discAuthMode)
+ {
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ UA_MessageSecurityMode discSecMode = parseSecurityMode (discSecModeStr);
+ if (discSecMode == UA_MESSAGESECURITYMODE_INVALID)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Unknown discovery security mode: %s", discSecModeStr);
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ const char *discSecPolUri = resolveSecurityPolicyUri (discSecPolStr);
+ if (!discSecPolUri)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Unknown discovery security policy: %s", discSecPolStr);
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ /* ---- Server-side config (connections to discovered servers) ---- */
+
+ const char *srvCertPath
+ = configRequire (&cfg, "serverCertificate", "ClientFindServers");
+ const char *srvKeyPath
+ = configRequire (&cfg, "serverPrivateKey", "ClientFindServers");
+ const char *srvSecModeStr
+ = configRequire (&cfg, "serverSecurityMode", "ClientFindServers");
+ const char *srvSecPolStr
+ = configRequire (&cfg, "serverSecurityPolicy", "ClientFindServers");
+ const char *srvAuthMode
+ = configRequire (&cfg, "serverAuthMode", "ClientFindServers");
+
+ if (!srvCertPath || !srvKeyPath || !srvSecModeStr || !srvSecPolStr
+ || !srvAuthMode)
{
configFree (&cfg);
return EXIT_FAILURE;
}
- UA_MessageSecurityMode securityMode = parseSecurityMode (securityModeStr);
- if (securityMode == UA_MESSAGESECURITYMODE_INVALID)
+ UA_MessageSecurityMode srvSecMode = parseSecurityMode (srvSecModeStr);
+ if (srvSecMode == UA_MESSAGESECURITYMODE_INVALID)
{
UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown security mode: %s", securityModeStr);
+ "Unknown server security mode: %s", srvSecModeStr);
configFree (&cfg);
return EXIT_FAILURE;
}
- const char *securityPolicyUri = resolveSecurityPolicyUri (securityPolicyStr);
- if (!securityPolicyUri)
+ const char *srvSecPolUri = resolveSecurityPolicyUri (srvSecPolStr);
+ if (!srvSecPolUri)
{
UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown security policy: %s", securityPolicyStr);
+ "Unknown server security policy: %s", srvSecPolStr);
configFree (&cfg);
return EXIT_FAILURE;
}
- const char *username = NULL, *password = NULL;
+ /* ---- Server-side auth ---- */
- if (strcmp (authMode, "anonymous") == 0)
+ const char *srvUsername = NULL, *srvPassword = NULL;
+
+ if (strcmp (srvAuthMode, "anonymous") == 0)
{
/* No credentials needed */
}
- else if (strcmp (authMode, "user") == 0)
+ else if (strcmp (srvAuthMode, "user") == 0)
{
- username = configRequire (&cfg, "username", "ClientFindServers");
- password = configRequire (&cfg, "password", "ClientFindServers");
- if (!username || !password)
+ srvUsername
+ = configRequire (&cfg, "serverUsername", "ClientFindServers");
+ srvPassword
+ = configRequire (&cfg, "serverPassword", "ClientFindServers");
+ if (!srvUsername || !srvPassword)
{
configFree (&cfg);
return EXIT_FAILURE;
@@ -291,56 +345,93 @@ main (int argc, char **argv)
else
{
UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown auth mode: %s "
+ "Unknown server auth mode: %s "
"(expected 'anonymous' or 'user')",
- authMode);
+ srvAuthMode);
configFree (&cfg);
return EXIT_FAILURE;
}
- char **trustPaths = NULL;
- size_t trustSize = 0;
- configGetAll (&cfg, "trustList", &trustPaths, &trustSize);
+ /* ---- Trust lists ---- */
+
+ char **discTrustPaths = NULL;
+ size_t discTrustSize = 0;
+ configGetAll (&cfg, "discoveryTrustList", &discTrustPaths, &discTrustSize);
+
+ char **srvTrustPaths = NULL;
+ size_t srvTrustSize = 0;
+ configGetAll (&cfg, "serverTrustList", &srvTrustPaths, &srvTrustSize);
- UA_Client *client = UA_Client_new ();
+ /* ---- Create discovery client (LDS) ---- */
+
+ UA_Client *discoveryClient = UA_Client_new ();
UA_StatusCode retval = createSecureClientConfig (
- UA_Client_getConfig (client), applicationUri, certPath, keyPath,
- trustPaths, trustSize, securityMode, securityPolicyUri);
+ UA_Client_getConfig (discoveryClient), applicationUri, discCertPath,
+ discKeyPath, discTrustPaths, discTrustSize, discSecMode, discSecPolUri);
if (retval != UA_STATUSCODE_GOOD)
{
- UA_Client_delete (client);
- free (trustPaths);
+ UA_Client_delete (discoveryClient);
+ free (discTrustPaths);
+ free (srvTrustPaths);
configFree (&cfg);
return EXIT_FAILURE;
}
- UA_ClientConfig *clientConfig = UA_Client_getConfig (client);
- clientConfig->logging->context = (void *)(uintptr_t)logLevel;
+ UA_Client_getConfig (discoveryClient)->logging->context
+ = (void *)(uintptr_t)logLevel;
+
+ /* ---- Create server client (discovered servers) ---- */
+
+ UA_Client *serverClient = UA_Client_new ();
+ retval = createSecureClientConfig (
+ UA_Client_getConfig (serverClient), applicationUri, srvCertPath,
+ srvKeyPath, srvTrustPaths, srvTrustSize, srvSecMode, srvSecPolUri);
+ if (retval != UA_STATUSCODE_GOOD)
+ {
+ UA_Client_delete (discoveryClient);
+ UA_Client_delete (serverClient);
+ free (discTrustPaths);
+ free (srvTrustPaths);
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+ UA_Client_getConfig (serverClient)->logging->context
+ = (void *)(uintptr_t)logLevel;
+
+ /* ---- Discovery calls (use discoveryClient) ---- */
UA_ApplicationDescription *applicationDescriptionArray = NULL;
size_t applicationDescriptionArraySize = 0;
- retval = findServers (client, discoveryServerEndpoint,
+ retval = findServers (discoveryClient, discoveryServerEndpoint,
&applicationDescriptionArraySize,
&applicationDescriptionArray);
if (retval != UA_STATUSCODE_GOOD)
{
- UA_Client_delete (client);
- free (trustPaths);
+ UA_Client_delete (discoveryClient);
+ UA_Client_delete (serverClient);
+ free (discTrustPaths);
+ free (srvTrustPaths);
configFree (&cfg);
return EXIT_FAILURE;
}
- getServersEndpoints (client, applicationDescriptionArray,
+ getServersEndpoints (discoveryClient, applicationDescriptionArray,
applicationDescriptionArraySize);
- readServerTime (client, applicationDescriptionArray,
- applicationDescriptionArraySize, username, password);
+ /* ---- Server calls (use serverClient) ---- */
+
+ readServerTime (serverClient, applicationDescriptionArray,
+ applicationDescriptionArraySize, srvUsername, srvPassword);
+
+ /* ---- Cleanup ---- */
- UA_Client_delete (client);
+ UA_Client_delete (discoveryClient);
+ UA_Client_delete (serverClient);
UA_Array_delete (applicationDescriptionArray,
applicationDescriptionArraySize,
&UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
- free (trustPaths);
+ free (discTrustPaths);
+ free (srvTrustPaths);
configFree (&cfg);
return EXIT_SUCCESS;
diff --git a/tests/aes128_anon/client_find_servers.conf b/tests/aes128_anon/client_find_servers.conf
index 87eed56..2cc096d 100644
--- a/tests/aes128_anon/client_find_servers.conf
+++ b/tests/aes128_anon/client_find_servers.conf
@@ -2,13 +2,19 @@
discoveryEndpoint = opc.tcp://localhost:14840
applicationUri = urn:bobink.ClientFindServers
-certificate = certs/ClientFindServers_cert.der
-privateKey = certs/ClientFindServers_key.der
-securityMode = SignAndEncrypt
-securityPolicy = Aes128_Sha256_RsaOaep
+# Discovery (LDS) side
+discoveryCertificate = certs/ClientFindServers_cert.der
+discoveryPrivateKey = certs/ClientFindServers_key.der
+discoverySecurityMode = SignAndEncrypt
+discoverySecurityPolicy = Aes128_Sha256_RsaOaep
+discoveryAuthMode = anonymous
+discoveryTrustList = certs/ServerLDS_cert.der
-authMode = anonymous
-
-trustList = certs/ServerLDS_cert.der
-trustList = certs/ServerRegister_cert.der
+# Server side
+serverCertificate = certs/ClientFindServers_cert.der
+serverPrivateKey = certs/ClientFindServers_key.der
+serverSecurityMode = SignAndEncrypt
+serverSecurityPolicy = Aes128_Sha256_RsaOaep
+serverAuthMode = anonymous
+serverTrustList = certs/ServerRegister_cert.der
diff --git a/tests/aes128_user/client_find_servers.conf b/tests/aes128_user/client_find_servers.conf
index 58d7bd1..4ecff56 100644
--- a/tests/aes128_user/client_find_servers.conf
+++ b/tests/aes128_user/client_find_servers.conf
@@ -2,15 +2,23 @@
discoveryEndpoint = opc.tcp://localhost:14840
applicationUri = urn:bobink.ClientFindServers
-certificate = certs/ClientFindServers_cert.der
-privateKey = certs/ClientFindServers_key.der
-securityMode = SignAndEncrypt
-securityPolicy = Aes128_Sha256_RsaOaep
+# Discovery (LDS) side
+discoveryCertificate = certs/ClientFindServers_cert.der
+discoveryPrivateKey = certs/ClientFindServers_key.der
+discoverySecurityMode = SignAndEncrypt
+discoverySecurityPolicy = Aes128_Sha256_RsaOaep
+discoveryAuthMode = user
+discoveryUsername = user
+discoveryPassword = password
+discoveryTrustList = certs/ServerLDS_cert.der
-authMode = user
-username = user
-password = password
-
-trustList = certs/ServerLDS_cert.der
-trustList = certs/ServerRegister_cert.der
+# Server side
+serverCertificate = certs/ClientFindServers_cert.der
+serverPrivateKey = certs/ClientFindServers_key.der
+serverSecurityMode = SignAndEncrypt
+serverSecurityPolicy = Aes128_Sha256_RsaOaep
+serverAuthMode = user
+serverUsername = user
+serverPassword = password
+serverTrustList = certs/ServerRegister_cert.der
diff --git a/tests/basic256sha256_anon/client_find_servers.conf b/tests/basic256sha256_anon/client_find_servers.conf
index fb3d9d4..332c3da 100644
--- a/tests/basic256sha256_anon/client_find_servers.conf
+++ b/tests/basic256sha256_anon/client_find_servers.conf
@@ -2,13 +2,19 @@
discoveryEndpoint = opc.tcp://localhost:14840
applicationUri = urn:bobink.ClientFindServers
-certificate = certs/ClientFindServers_cert.der
-privateKey = certs/ClientFindServers_key.der
-securityMode = SignAndEncrypt
-securityPolicy = Basic256Sha256
+# Discovery (LDS) side
+discoveryCertificate = certs/ClientFindServers_cert.der
+discoveryPrivateKey = certs/ClientFindServers_key.der
+discoverySecurityMode = SignAndEncrypt
+discoverySecurityPolicy = Basic256Sha256
+discoveryAuthMode = anonymous
+discoveryTrustList = certs/ServerLDS_cert.der
-authMode = anonymous
-
-trustList = certs/ServerLDS_cert.der
-trustList = certs/ServerRegister_cert.der
+# Server side
+serverCertificate = certs/ClientFindServers_cert.der
+serverPrivateKey = certs/ClientFindServers_key.der
+serverSecurityMode = SignAndEncrypt
+serverSecurityPolicy = Basic256Sha256
+serverAuthMode = anonymous
+serverTrustList = certs/ServerRegister_cert.der
diff --git a/tests/basic256sha256_user/client_find_servers.conf b/tests/basic256sha256_user/client_find_servers.conf
index 93f511c..403dfa4 100644
--- a/tests/basic256sha256_user/client_find_servers.conf
+++ b/tests/basic256sha256_user/client_find_servers.conf
@@ -2,15 +2,23 @@
discoveryEndpoint = opc.tcp://localhost:14840
applicationUri = urn:bobink.ClientFindServers
-certificate = certs/ClientFindServers_cert.der
-privateKey = certs/ClientFindServers_key.der
-securityMode = SignAndEncrypt
-securityPolicy = Basic256Sha256
+# Discovery (LDS) side
+discoveryCertificate = certs/ClientFindServers_cert.der
+discoveryPrivateKey = certs/ClientFindServers_key.der
+discoverySecurityMode = SignAndEncrypt
+discoverySecurityPolicy = Basic256Sha256
+discoveryAuthMode = user
+discoveryUsername = user
+discoveryPassword = password
+discoveryTrustList = certs/ServerLDS_cert.der
-authMode = user
-username = user
-password = password
-
-trustList = certs/ServerLDS_cert.der
-trustList = certs/ServerRegister_cert.der
+# Server side
+serverCertificate = certs/ClientFindServers_cert.der
+serverPrivateKey = certs/ClientFindServers_key.der
+serverSecurityMode = SignAndEncrypt
+serverSecurityPolicy = Basic256Sha256
+serverAuthMode = user
+serverUsername = user
+serverPassword = password
+serverTrustList = certs/ServerRegister_cert.der
diff --git a/tests/none_anon/client_find_servers.conf b/tests/none_anon/client_find_servers.conf
index 8d874e7..6ea7d2d 100644
--- a/tests/none_anon/client_find_servers.conf
+++ b/tests/none_anon/client_find_servers.conf
@@ -2,13 +2,19 @@
discoveryEndpoint = opc.tcp://localhost:14840
applicationUri = urn:bobink.ClientFindServers
-certificate = certs/ClientFindServers_cert.der
-privateKey = certs/ClientFindServers_key.der
-securityMode = None
-securityPolicy = None
+# Discovery (LDS) side
+discoveryCertificate = certs/ClientFindServers_cert.der
+discoveryPrivateKey = certs/ClientFindServers_key.der
+discoverySecurityMode = None
+discoverySecurityPolicy = None
+discoveryAuthMode = anonymous
+discoveryTrustList = certs/ServerLDS_cert.der
-authMode = anonymous
-
-trustList = certs/ServerLDS_cert.der
-trustList = certs/ServerRegister_cert.der
+# Server side
+serverCertificate = certs/ClientFindServers_cert.der
+serverPrivateKey = certs/ClientFindServers_key.der
+serverSecurityMode = None
+serverSecurityPolicy = None
+serverAuthMode = anonymous
+serverTrustList = certs/ServerRegister_cert.der
diff --git a/tests/none_user/client_find_servers.conf b/tests/none_user/client_find_servers.conf
index 10e9888..b538952 100644
--- a/tests/none_user/client_find_servers.conf
+++ b/tests/none_user/client_find_servers.conf
@@ -2,15 +2,23 @@
discoveryEndpoint = opc.tcp://localhost:14840
applicationUri = urn:bobink.ClientFindServers
-certificate = certs/ClientFindServers_cert.der
-privateKey = certs/ClientFindServers_key.der
-securityMode = None
-securityPolicy = None
+# Discovery (LDS) side
+discoveryCertificate = certs/ClientFindServers_cert.der
+discoveryPrivateKey = certs/ClientFindServers_key.der
+discoverySecurityMode = None
+discoverySecurityPolicy = None
+discoveryAuthMode = user
+discoveryUsername = user
+discoveryPassword = password
+discoveryTrustList = certs/ServerLDS_cert.der
-authMode = user
-username = user
-password = password
-
-trustList = certs/ServerLDS_cert.der
-trustList = certs/ServerRegister_cert.der
+# Server side
+serverCertificate = certs/ClientFindServers_cert.der
+serverPrivateKey = certs/ClientFindServers_key.der
+serverSecurityMode = None
+serverSecurityPolicy = None
+serverAuthMode = user
+serverUsername = user
+serverPassword = password
+serverTrustList = certs/ServerRegister_cert.der