diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-17 23:11:29 +0100 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-17 23:27:11 +0100 |
| commit | b2002d96f495dcb3bd2f5a738ec1615034ca876f (patch) | |
| tree | aee665fb83cedebaa8ad093d0a2896a1a83881eb /src/server_lds.c | |
| parent | 229a536a87f6b2075000e659219e0567b45345c5 (diff) | |
| download | BobinkCOpcUa-b2002d96f495dcb3bd2f5a738ec1615034ca876f.tar.gz BobinkCOpcUa-b2002d96f495dcb3bd2f5a738ec1615034ca876f.zip | |
Make LDS security config optional, add nosec_anon test
ServerLDS and ServerRegister can now run without encryption when
certificate, privateKey, and trustStore are all omitted from the
server config file. When any of the three is present, all three are
still required. The unsecured server uses UA_ServerConfig_setMinimal
with SecurityPolicy#None only.
Add nosec_anon integration test covering the LDS unsecured path.
Update readme: use symlinks instead of copies for trust stores, note
that ServerLDS and ServerRegister support running without certs.
Diffstat (limited to 'src/server_lds.c')
| -rw-r--r-- | src/server_lds.c | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/src/server_lds.c b/src/server_lds.c index a9a68bc..e3407d5 100644 --- a/src/server_lds.c +++ b/src/server_lds.c @@ -2,8 +2,10 @@ * @file server_lds.c * @brief Local Discovery Server implementation. * - * This program runs an OPC UA Local Discovery Server (LDS) configured with - * encryption and a configurable cleanup timeout. Other OPC UA servers register + * This program runs an OPC UA Local Discovery Server (LDS) with a configurable + * cleanup timeout. Encryption is optional: when certificate, privateKey, and + * trustStore are provided, the server offers all security policies; otherwise + * it runs with SecurityPolicy#None only. Other OPC UA servers register * with this LDS using the RegisterServer2 service. Clients can query this LDS * using the FindServers service to discover registered servers. */ @@ -60,18 +62,33 @@ main (int argc, char *argv[]) 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) + if (!applicationUri || !authMode || port < 0 || cleanupTimeout < 0) { configFree (&cfg); return EXIT_FAILURE; } + /* Security configuration (optional). When certificate, privateKey, and + trustStore are all omitted the server runs with SecurityPolicy#None + only. When any of the three is present, all three are required. */ + const char *certPath = configGet (&cfg, "certificate"); + const char *keyPath = configGet (&cfg, "privateKey"); + const char *trustStore = configGet (&cfg, "trustStore"); + UA_Boolean secure + = (certPath != NULL || keyPath != NULL || trustStore != NULL); + + if (secure && (!certPath || !keyPath || !trustStore)) + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Incomplete security config: certificate, privateKey, and " + "trustStore must all be set, or all omitted"); + 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. */ if (cleanupTimeout <= 10) @@ -111,30 +128,41 @@ main (int argc, char *argv[]) return EXIT_FAILURE; } - const char *trustStore = configRequire (&cfg, "trustStore", "ServerLDS"); - if (!trustStore) - { - configFree (&cfg); - return EXIT_FAILURE; - } - char **trustPaths = NULL; size_t trustSize = 0; - if (loadTrustStore (trustStore, &trustPaths, &trustSize) != 0) + UA_StatusCode retval; + UA_Server *server; + + if (secure) { - configFree (&cfg); - return EXIT_FAILURE; + if (loadTrustStore (trustStore, &trustPaths, &trustSize) != 0) + { + configFree (&cfg); + return EXIT_FAILURE; + } + server = createSecureServer ((UA_UInt16)port, applicationUri, certPath, + keyPath, trustPaths, trustSize, &retval); + if (!server) + { + freeTrustStore (trustPaths, trustSize); + configFree (&cfg); + return EXIT_FAILURE; + } } - - UA_StatusCode retval; - UA_Server *server - = createSecureServer ((UA_UInt16)port, applicationUri, certPath, keyPath, - trustPaths, trustSize, &retval); - if (!server) + else { - freeTrustStore (trustPaths, trustSize); - configFree (&cfg); - return EXIT_FAILURE; + server = UA_Server_new (); + UA_ServerConfig *config = UA_Server_getConfig (server); + retval = UA_ServerConfig_setMinimal (config, (UA_UInt16)port, NULL); + if (retval != UA_STATUSCODE_GOOD) + { + UA_Server_delete (server); + configFree (&cfg); + return EXIT_FAILURE; + } + UA_String_clear (&config->applicationDescription.applicationUri); + config->applicationDescription.applicationUri + = UA_String_fromChars (applicationUri); } UA_ServerConfig *serverConfig = UA_Server_getConfig (server); @@ -145,10 +173,10 @@ main (int argc, char *argv[]) Downgrade to a warning so third-party servers can still register. */ serverConfig->verifyRequestTimestamp = UA_RULEHANDLING_WARN; - /* Configure access control after server creation because - UA_ServerConfig_setDefaultWithSecurityPolicies (called by - createSecureServer) resets the access control plugin. The credential - list is deep-copied by UA_AccessControl_default. */ + /* Configure access control after server creation because both + UA_ServerConfig_setDefaultWithSecurityPolicies and + UA_ServerConfig_setMinimal reset the access control plugin. The + credential list is deep-copied by UA_AccessControl_default. */ if (!allowAnonymous) { UA_UsernamePasswordLogin logins[1]; |
