diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server_lds.c | 86 | ||||
| -rw-r--r-- | src/server_register.c | 88 |
2 files changed, 116 insertions, 58 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]; diff --git a/src/server_register.c b/src/server_register.c index 6e1eb6d..cea7124 100644 --- a/src/server_register.c +++ b/src/server_register.c @@ -73,22 +73,36 @@ main (int argc, char **argv) int port = configRequireInt (&serverCfg, "port", "ServerRegister"); const char *applicationUri = configRequire (&serverCfg, "applicationUri", "ServerRegister"); - const char *serverCertPath - = configRequire (&serverCfg, "certificate", "ServerRegister"); - const char *serverKeyPath - = configRequire (&serverCfg, "privateKey", "ServerRegister"); int registerInterval = configRequireInt (&serverCfg, "registerInterval", "ServerRegister"); const char *serverAuthMode = configRequire (&serverCfg, "authMode", "ServerRegister"); - if (!applicationUri || !serverCertPath || !serverKeyPath || !serverAuthMode - || port < 0 || registerInterval < 0) + if (!applicationUri || !serverAuthMode || port < 0 || registerInterval < 0) { configFree (&serverCfg); 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 *serverCertPath = configGet (&serverCfg, "certificate"); + const char *serverKeyPath = configGet (&serverCfg, "privateKey"); + const char *serverTrustStore = configGet (&serverCfg, "trustStore"); + UA_Boolean serverSecure = (serverCertPath != NULL || serverKeyPath != NULL + || serverTrustStore != NULL); + + if (serverSecure && (!serverCertPath || !serverKeyPath || !serverTrustStore)) + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Incomplete server security config: certificate, " + "privateKey, and trustStore must all be set, or all " + "omitted"); + configFree (&serverCfg); + return EXIT_FAILURE; + } + /* Parse server-side auth mode (what clients connecting to this server need). "anonymous" allows unauthenticated sessions; "user" requires a username/password pair. */ @@ -122,18 +136,11 @@ main (int argc, char **argv) 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) + if (serverSecure + && loadTrustStore (serverTrustStore, &serverTrustPaths, &serverTrustSize) + != 0) { configFree (&serverCfg); return EXIT_FAILURE; @@ -251,25 +258,48 @@ main (int argc, char **argv) /* ── Create and configure server ────────────────────────────── */ UA_StatusCode retval; - UA_Server *server = createSecureServer ( - (UA_UInt16)port, applicationUri, serverCertPath, serverKeyPath, - serverTrustPaths, serverTrustSize, &retval); - if (!server) + UA_Server *server; + + if (serverSecure) { - freeTrustStore (clientTrustPaths, clientTrustSize); - freeTrustStore (serverTrustPaths, serverTrustSize); - configFree (&clientCfg); - configFree (&serverCfg); - return EXIT_FAILURE; + server = createSecureServer ((UA_UInt16)port, applicationUri, + serverCertPath, serverKeyPath, + serverTrustPaths, serverTrustSize, &retval); + if (!server) + { + freeTrustStore (clientTrustPaths, clientTrustSize); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); + return EXIT_FAILURE; + } + } + else + { + 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); + freeTrustStore (clientTrustPaths, clientTrustSize); + freeTrustStore (serverTrustPaths, serverTrustSize); + configFree (&clientCfg); + configFree (&serverCfg); + return EXIT_FAILURE; + } + UA_String_clear (&config->applicationDescription.applicationUri); + config->applicationDescription.applicationUri + = UA_String_fromChars (applicationUri); } UA_ServerConfig *serverConfig = UA_Server_getConfig (server); serverConfig->logging->context = (void *)(uintptr_t)logLevel; - /* 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 (!serverAllowAnonymous) { UA_UsernamePasswordLogin logins[1]; |
