From a54421dd976fd8081e96c11c2621076876c9986b Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Tue, 17 Feb 2026 11:07:37 +0100 Subject: Replace CLI arguments with config-file parser and add integration tests Introduce a reusable key=value config parser (config.h/c) and convert all three programs to read their settings from config files instead of positional command-line arguments. Add example config files in config/ and 6 CTest integration tests covering None/Basic256Sha256/Aes128 with anonymous and user authentication. Remove the now-obsolete launch.sh. --- src/server_lds.c | 74 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 27 deletions(-) (limited to 'src/server_lds.c') diff --git a/src/server_lds.c b/src/server_lds.c index fc51596..c6960d5 100644 --- a/src/server_lds.c +++ b/src/server_lds.c @@ -9,6 +9,7 @@ */ #include "common.h" +#include "config.h" #include #include @@ -17,6 +18,7 @@ #include #include +#include UA_Boolean running = true; @@ -33,23 +35,31 @@ main (int argc, char *argv[]) signal (SIGINT, stopHandler); signal (SIGTERM, stopHandler); - if (argc < 7) + if (argc != 2) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Usage: %s\n" - " \n" - " \n" - " \n" - " [ ]\n" - " [, ...]\n" - "\n" - "Auth modes: anonymous, user", - argv[0]); + "Usage: %s ", argv[0]); return EXIT_FAILURE; } - UA_UInt16 port = (UA_UInt16)atoi (argv[1]); - int cleanupTimeout = atoi (argv[5]); + Config cfg; + if (configLoad (argv[1], &cfg) != 0) + return EXIT_FAILURE; + + int port = configRequireInt (&cfg, "port", "ServerLDS"); + const char *applicationUri + = configRequire (&cfg, "applicationUri", "ServerLDS"); + const char *certPath = configRequire (&cfg, "certificate", "ServerLDS"); + const char *keyPath = configRequire (&cfg, "privateKey", "ServerLDS"); + int cleanupTimeout = configRequireInt (&cfg, "cleanupTimeout", "ServerLDS"); + const char *authMode = configRequire (&cfg, "authMode", "ServerLDS"); + + if (!applicationUri || !certPath || !keyPath || !authMode || port < 0 + || cleanupTimeout < 0) + { + configFree (&cfg); + return EXIT_FAILURE; + } /* The OPC UA specification requires the cleanup timeout to exceed the register-server interval. open62541 enforces a floor of 10 seconds. */ @@ -58,13 +68,12 @@ main (int argc, char *argv[]) UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Cleanup timeout must be > 10 seconds (got %d)", cleanupTimeout); + configFree (&cfg); return EXIT_FAILURE; } - int idx = 6; - const char *authMode = argv[idx++]; UA_Boolean allowAnonymous; - char *username = NULL, *password = NULL; + const char *username = NULL, *password = NULL; if (strcmp (authMode, "anonymous") == 0) { @@ -72,15 +81,14 @@ main (int argc, char *argv[]) } else if (strcmp (authMode, "user") == 0) { - if (idx + 2 > argc) + allowAnonymous = false; + username = configRequire (&cfg, "username", "ServerLDS"); + password = configRequire (&cfg, "password", "ServerLDS"); + if (!username || !password) { - UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Auth mode 'user' requires "); + configFree (&cfg); return EXIT_FAILURE; } - allowAnonymous = false; - username = argv[idx++]; - password = argv[idx++]; } else { @@ -88,16 +96,24 @@ main (int argc, char *argv[]) "Unknown auth mode: %s " "(expected 'anonymous' or 'user')", authMode); + configFree (&cfg); return EXIT_FAILURE; } - size_t trustSize = (idx < argc) ? (size_t)(argc - idx) : 0; + char **trustPaths = NULL; + size_t trustSize = 0; + configGetAll (&cfg, "trustList", &trustPaths, &trustSize); UA_StatusCode retval; - UA_Server *server = createSecureServer (port, argv[2], argv[3], argv[4], - argv + idx, trustSize, &retval); + UA_Server *server + = createSecureServer ((UA_UInt16)port, applicationUri, certPath, keyPath, + trustPaths, trustSize, &retval); if (!server) - return EXIT_FAILURE; + { + free (trustPaths); + configFree (&cfg); + return EXIT_FAILURE; + } UA_ServerConfig *serverConfig = UA_Server_getConfig (server); @@ -108,12 +124,14 @@ main (int argc, char *argv[]) if (!allowAnonymous) { UA_UsernamePasswordLogin logins[1]; - logins[0].username = UA_STRING (username); - logins[0].password = UA_STRING (password); + logins[0].username = UA_STRING ((char *)username); + logins[0].password = UA_STRING ((char *)password); retval = UA_AccessControl_default (serverConfig, false, NULL, 1, logins); if (retval != UA_STATUSCODE_GOOD) { UA_Server_delete (server); + free (trustPaths); + configFree (&cfg); return EXIT_FAILURE; } } @@ -129,5 +147,7 @@ main (int argc, char *argv[]) retval = UA_Server_run (server, &running); UA_Server_delete (server); + free (trustPaths); + configFree (&cfg); return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE; } -- cgit v1.2.3