From 827e90e0daabe32e058e08dd2a253425898a7e7a Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Tue, 17 Feb 2026 19:06:22 +0100 Subject: Replace ClientFindServers with unified Client, use trust store directories Replace the single-purpose ClientFindServers program with a unified Client that supports three operations via CLI: find-servers, get-endpoints, and read-time. This simplifies the architecture by using one client binary with a single config file instead of a monolithic program that did everything in one run. Split the ServerRegister config into separate server and client config files so the LDS-registration credentials are isolated from the server's own settings. The discovery URL moves from config to a CLI argument. Replace repeated trustList config entries with a single trustStore directory path. Each program now points to a directory under certs/trust/ containing .der files, so adding or removing trust is a file-copy operation rather than editing every config file. Add loadTrustStore()/freeTrustStore() to common.c and remove the now-unused configGetAll() from the config parser. Simplify the test matrix from 6 to 4 cases (security and auth are orthogonal, so the full 3x2 matrix is unnecessary). Update run_test.sh to invoke the new Client three times and use port-polling instead of sleep. --- src/server_register.c | 227 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 152 insertions(+), 75 deletions(-) (limited to 'src/server_register.c') diff --git a/src/server_register.c b/src/server_register.c index d259961..6e1eb6d 100644 --- a/src/server_register.c +++ b/src/server_register.c @@ -42,14 +42,18 @@ main (int argc, char **argv) signal (SIGINT, stopHandler); signal (SIGTERM, stopHandler); - if (argc < 2 || argc > 3) + if (argc < 4 || argc > 5) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Usage: %s [log-level]", argv[0]); + "Usage: %s " + " [log-level]", + argv[0]); return EXIT_FAILURE; } - const char *logLevelStr = (argc == 3) ? argv[2] : "info"; + const char *discoveryEndpoint = argv[3]; + + const char *logLevelStr = (argc == 5) ? argv[4] : "info"; int logLevel = parseLogLevel (logLevelStr); if (logLevel < 0) { @@ -60,58 +64,28 @@ main (int argc, char **argv) return EXIT_FAILURE; } - Config cfg; - if (configLoad (argv[1], &cfg) != 0) + /* ── Load server config ─────────────────────────────────────── */ + + Config serverCfg; + if (configLoad (argv[1], &serverCfg) != 0) return EXIT_FAILURE; - int port = configRequireInt (&cfg, "port", "ServerRegister"); + int port = configRequireInt (&serverCfg, "port", "ServerRegister"); const char *applicationUri - = configRequire (&cfg, "applicationUri", "ServerRegister"); + = configRequire (&serverCfg, "applicationUri", "ServerRegister"); const char *serverCertPath - = configRequire (&cfg, "serverCertificate", "ServerRegister"); + = configRequire (&serverCfg, "certificate", "ServerRegister"); const char *serverKeyPath - = configRequire (&cfg, "serverPrivateKey", "ServerRegister"); - const char *clientCertPath - = configRequire (&cfg, "clientCertificate", "ServerRegister"); - const char *clientKeyPath - = configRequire (&cfg, "clientPrivateKey", "ServerRegister"); - const char *discoveryEndpoint - = configRequire (&cfg, "discoveryEndpoint", "ServerRegister"); + = configRequire (&serverCfg, "privateKey", "ServerRegister"); int registerInterval - = configRequireInt (&cfg, "registerInterval", "ServerRegister"); - const char *securityModeStr - = configRequire (&cfg, "securityMode", "ServerRegister"); - const char *securityPolicyStr - = configRequire (&cfg, "securityPolicy", "ServerRegister"); + = configRequireInt (&serverCfg, "registerInterval", "ServerRegister"); const char *serverAuthMode - = configRequire (&cfg, "serverAuthMode", "ServerRegister"); - const char *clientAuthMode - = configRequire (&cfg, "clientAuthMode", "ServerRegister"); - - if (!applicationUri || !serverCertPath || !serverKeyPath || !clientCertPath - || !clientKeyPath || !discoveryEndpoint || !securityModeStr - || !securityPolicyStr || !serverAuthMode || !clientAuthMode || port < 0 - || registerInterval < 0) - { - configFree (&cfg); - return EXIT_FAILURE; - } + = configRequire (&serverCfg, "authMode", "ServerRegister"); - UA_MessageSecurityMode securityMode = parseSecurityMode (securityModeStr); - if (securityMode == UA_MESSAGESECURITYMODE_INVALID) + if (!applicationUri || !serverCertPath || !serverKeyPath || !serverAuthMode + || port < 0 || registerInterval < 0) { - UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Unknown security mode: %s", securityModeStr); - configFree (&cfg); - return EXIT_FAILURE; - } - - const char *securityPolicyUri = resolveSecurityPolicyUri (securityPolicyStr); - if (!securityPolicyUri) - { - UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Unknown security policy: %s", securityPolicyStr); - configFree (&cfg); + configFree (&serverCfg); return EXIT_FAILURE; } @@ -129,12 +103,12 @@ main (int argc, char **argv) { serverAllowAnonymous = false; serverUsername - = configRequire (&cfg, "serverUsername", "ServerRegister"); + = configRequire (&serverCfg, "username", "ServerRegister"); serverPassword - = configRequire (&cfg, "serverPassword", "ServerRegister"); + = configRequire (&serverCfg, "password", "ServerRegister"); if (!serverUsername || !serverPassword) { - configFree (&cfg); + configFree (&serverCfg); return EXIT_FAILURE; } } @@ -144,7 +118,78 @@ main (int argc, char **argv) "Unknown server auth mode: %s " "(expected 'anonymous' or 'user')", serverAuthMode); - configFree (&cfg); + configFree (&serverCfg); + return EXIT_FAILURE; + } + + const char *serverTrustStore + = configRequire (&serverCfg, "trustStore", "ServerRegister"); + if (!serverTrustStore) + { + configFree (&serverCfg); + return EXIT_FAILURE; + } + + char **serverTrustPaths = NULL; + size_t serverTrustSize = 0; + if (loadTrustStore (serverTrustStore, &serverTrustPaths, &serverTrustSize) + != 0) + { + configFree (&serverCfg); + return EXIT_FAILURE; + } + + /* ── Load client config ─────────────────────────────────────── */ + + Config clientCfg; + if (configLoad (argv[2], &clientCfg) != 0) + { + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&serverCfg); + return EXIT_FAILURE; + } + + const char *clientAppUri + = configRequire (&clientCfg, "applicationUri", "ServerRegister"); + const char *clientCertPath + = configRequire (&clientCfg, "certificate", "ServerRegister"); + const char *clientKeyPath + = configRequire (&clientCfg, "privateKey", "ServerRegister"); + const char *securityModeStr + = configRequire (&clientCfg, "securityMode", "ServerRegister"); + const char *securityPolicyStr + = configRequire (&clientCfg, "securityPolicy", "ServerRegister"); + const char *clientAuthMode + = configRequire (&clientCfg, "authMode", "ServerRegister"); + + if (!clientAppUri || !clientCertPath || !clientKeyPath || !securityModeStr + || !securityPolicyStr || !clientAuthMode) + { + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); + return EXIT_FAILURE; + } + + UA_MessageSecurityMode securityMode = parseSecurityMode (securityModeStr); + if (securityMode == UA_MESSAGESECURITYMODE_INVALID) + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Unknown security mode: %s", securityModeStr); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); + return EXIT_FAILURE; + } + + const char *securityPolicyUri = resolveSecurityPolicyUri (securityPolicyStr); + if (!securityPolicyUri) + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Unknown security policy: %s", securityPolicyStr); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); return EXIT_FAILURE; } @@ -159,12 +204,14 @@ main (int argc, char **argv) else if (strcmp (clientAuthMode, "user") == 0) { clientUsername - = configRequire (&cfg, "clientUsername", "ServerRegister"); + = configRequire (&clientCfg, "username", "ServerRegister"); clientPassword - = configRequire (&cfg, "clientPassword", "ServerRegister"); + = configRequire (&clientCfg, "password", "ServerRegister"); if (!clientUsername || !clientPassword) { - configFree (&cfg); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); return EXIT_FAILURE; } } @@ -174,22 +221,45 @@ main (int argc, char **argv) "Unknown client auth mode: %s " "(expected 'anonymous' or 'user')", clientAuthMode); - configFree (&cfg); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); + return EXIT_FAILURE; + } + + const char *clientTrustStore + = configRequire (&clientCfg, "trustStore", "ServerRegister"); + if (!clientTrustStore) + { + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); + return EXIT_FAILURE; + } + + char **clientTrustPaths = NULL; + size_t clientTrustSize = 0; + if (loadTrustStore (clientTrustStore, &clientTrustPaths, &clientTrustSize) + != 0) + { + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); return EXIT_FAILURE; } - char **trustPaths = NULL; - size_t trustSize = 0; - configGetAll (&cfg, "trustList", &trustPaths, &trustSize); + /* ── Create and configure server ────────────────────────────── */ UA_StatusCode retval; - UA_Server *server - = createSecureServer ((UA_UInt16)port, applicationUri, serverCertPath, - serverKeyPath, trustPaths, trustSize, &retval); + UA_Server *server = createSecureServer ( + (UA_UInt16)port, applicationUri, serverCertPath, serverKeyPath, + serverTrustPaths, serverTrustSize, &retval); if (!server) { - free (trustPaths); - configFree (&cfg); + freeTrustStore (clientTrustPaths, clientTrustSize); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); return EXIT_FAILURE; } @@ -209,8 +279,10 @@ main (int argc, char **argv) if (retval != UA_STATUSCODE_GOOD) { UA_Server_delete (server); - free (trustPaths); - configFree (&cfg); + freeTrustStore (clientTrustPaths, clientTrustSize); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); return EXIT_FAILURE; } } @@ -227,14 +299,16 @@ main (int argc, char **argv) UA_ClientConfig clientConfig; memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( - &clientConfig, applicationUri, clientCertPath, clientKeyPath, trustPaths, - trustSize, securityMode, securityPolicyUri); + &clientConfig, clientAppUri, clientCertPath, clientKeyPath, + clientTrustPaths, clientTrustSize, securityMode, securityPolicyUri); if (retval != UA_STATUSCODE_GOOD) { UA_Server_run_shutdown (server); UA_Server_delete (server); - free (trustPaths); - configFree (&cfg); + freeTrustStore (clientTrustPaths, clientTrustSize); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); return EXIT_FAILURE; } clientConfig.logging->context = (void *)(uintptr_t)logLevel; @@ -263,9 +337,10 @@ main (int argc, char **argv) if (now - lastRegister >= registerInterval) { memset (&clientConfig, 0, sizeof (UA_ClientConfig)); - retval = createSecureClientConfig ( - &clientConfig, applicationUri, clientCertPath, clientKeyPath, - trustPaths, trustSize, securityMode, securityPolicyUri); + retval = createSecureClientConfig (&clientConfig, clientAppUri, + clientCertPath, clientKeyPath, + clientTrustPaths, clientTrustSize, + securityMode, securityPolicyUri); if (retval == UA_STATUSCODE_GOOD) { clientConfig.logging->context = (void *)(uintptr_t)logLevel; @@ -289,8 +364,8 @@ main (int argc, char **argv) our entry immediately rather than waiting for the cleanup timeout. */ memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( - &clientConfig, applicationUri, clientCertPath, clientKeyPath, trustPaths, - trustSize, securityMode, securityPolicyUri); + &clientConfig, clientAppUri, clientCertPath, clientKeyPath, + clientTrustPaths, clientTrustSize, securityMode, securityPolicyUri); if (retval == UA_STATUSCODE_GOOD) { clientConfig.logging->context = (void *)(uintptr_t)logLevel; @@ -308,7 +383,9 @@ main (int argc, char **argv) UA_Server_run_shutdown (server); UA_Server_delete (server); - free (trustPaths); - configFree (&cfg); + freeTrustStore (clientTrustPaths, clientTrustSize); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); return EXIT_SUCCESS; } -- cgit v1.2.3