diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-17 03:31:40 +0100 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-17 03:31:40 +0100 |
| commit | 3425cddd75fa105b940c8c0afe4a63065c446515 (patch) | |
| tree | f1c2840985feeb06a9187d6bd99fe8274daf5412 /src/server_register.c | |
| parent | 1bbf7e6c2ff571b2e26b643a7e86e35790b91875 (diff) | |
| download | BobinkCOpcUa-3425cddd75fa105b940c8c0afe4a63065c446515.tar.gz BobinkCOpcUa-3425cddd75fa105b940c8c0afe4a63065c446515.zip | |
Make authentication mode and credentials configurable via CLI
Replace hardcoded user/password credentials with a new <auth-mode>
parameter that accepts "anonymous" or "user". When "user" is chosen,
two additional <username> <password> arguments are required.
ServerRegister accepts two independent auth modes: one for its own
server-side access control and one for authenticating to the LDS when
registering. ClientFindServers passes credentials to readServerTime,
which selects UA_Client_connectUsername or UA_Client_connect accordingly.
Update CLAUDE.md running examples and add an auth modes table.
Diffstat (limited to 'src/server_register.c')
| -rw-r--r-- | src/server_register.c | 124 |
1 files changed, 102 insertions, 22 deletions
diff --git a/src/server_register.c b/src/server_register.c index 8b750fe..c90fc31 100644 --- a/src/server_register.c +++ b/src/server_register.c @@ -41,7 +41,7 @@ main (int argc, char **argv) signal (SIGINT, stopHandler); signal (SIGTERM, stopHandler); - if (argc < 11) + if (argc < 13) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Usage: %s\n" @@ -51,12 +51,15 @@ main (int argc, char **argv) " <discovery-server-endpoint>\n" " <register-interval-seconds>\n" " <security-mode> <security-policy>\n" + " <server-auth-mode> [<server-user> <server-pass>]\n" + " <client-auth-mode> [<client-user> <client-pass>]\n" " [<trustlist1.der>, ...]\n" "\n" "Security modes : None, Sign, SignAndEncrypt\n" "Security policies: None, Basic256Sha256, " "Aes256_Sha256_RsaPss,\n" - " Aes128_Sha256_RsaOaep, ECC_nistP256", + " Aes128_Sha256_RsaOaep, ECC_nistP256\n" + "Auth modes : anonymous, user", argv[0]); return EXIT_FAILURE; } @@ -84,27 +87,101 @@ main (int argc, char **argv) return EXIT_FAILURE; } - size_t trustSize = (argc > 11) ? (size_t)argc - 11 : 0; + /* Parse server-side auth mode (what clients connecting to this server + need). "anonymous" allows unauthenticated sessions; "user" requires + a username/password pair. */ + int idx = 11; + const char *serverAuthMode = argv[idx++]; + UA_Boolean serverAllowAnonymous; + char *serverUsername = NULL, *serverPassword = NULL; + + if (strcmp (serverAuthMode, "anonymous") == 0) + { + serverAllowAnonymous = true; + } + else if (strcmp (serverAuthMode, "user") == 0) + { + if (idx + 2 > argc) + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Server auth mode 'user' requires " + "<username> <password>"); + return EXIT_FAILURE; + } + serverAllowAnonymous = false; + serverUsername = argv[idx++]; + serverPassword = argv[idx++]; + } + else + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Unknown server auth mode: %s " + "(expected 'anonymous' or 'user')", + serverAuthMode); + return EXIT_FAILURE; + } + + /* Parse client-side auth mode (how this server authenticates to the + LDS when registering). */ + if (idx >= argc) + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Missing client auth mode"); + return EXIT_FAILURE; + } + const char *clientAuthMode = argv[idx++]; + char *clientUsername = NULL, *clientPassword = NULL; + + if (strcmp (clientAuthMode, "anonymous") == 0) + { + /* No extra args needed */ + } + else if (strcmp (clientAuthMode, "user") == 0) + { + if (idx + 2 > argc) + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Client auth mode 'user' requires " + "<username> <password>"); + return EXIT_FAILURE; + } + clientUsername = argv[idx++]; + clientPassword = argv[idx++]; + } + else + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Unknown client auth mode: %s " + "(expected 'anonymous' or 'user')", + clientAuthMode); + return EXIT_FAILURE; + } + + size_t trustSize = (idx < argc) ? (size_t)(argc - idx) : 0; UA_StatusCode retval; UA_Server *server = createSecureServer ( - port, applicationUri, argv[3], argv[4], argv + 11, trustSize, &retval); + port, applicationUri, argv[3], argv[4], argv + idx, trustSize, &retval); if (!server) return EXIT_FAILURE; UA_ServerConfig *serverConfig = UA_Server_getConfig (server); - /* Disallow anonymous sessions. + /* Configure access control after server creation because UA_ServerConfig_setDefaultWithSecurityPolicies (called by - createSecureServer) resets access control, so this must come after server - creation. The static credential list is deep-copied. */ - UA_UsernamePasswordLogin logins[] - = { { UA_STRING_STATIC ("user"), UA_STRING_STATIC ("password") } }; - retval = UA_AccessControl_default (serverConfig, false, NULL, 1, logins); - if (retval != UA_STATUSCODE_GOOD) + createSecureServer) resets the access control plugin. The credential + list is deep-copied by UA_AccessControl_default. */ + if (!serverAllowAnonymous) { - UA_Server_delete (server); - return EXIT_FAILURE; + UA_UsernamePasswordLogin logins[1]; + logins[0].username = UA_STRING (serverUsername); + logins[0].password = UA_STRING (serverPassword); + retval = UA_AccessControl_default (serverConfig, false, NULL, 1, logins); + if (retval != UA_STATUSCODE_GOOD) + { + UA_Server_delete (server); + return EXIT_FAILURE; + } } serverConfig->applicationDescription.applicationType @@ -117,7 +194,7 @@ main (int argc, char **argv) UA_ClientConfig clientConfig; memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( - &clientConfig, applicationUri, clientCertPath, clientKeyPath, argv + 11, + &clientConfig, applicationUri, clientCertPath, clientKeyPath, argv + idx, trustSize, securityMode, securityPolicyUri); if (retval != UA_STATUSCODE_GOOD) { @@ -125,8 +202,9 @@ main (int argc, char **argv) UA_Server_delete (server); return EXIT_FAILURE; } - UA_ClientConfig_setAuthenticationUsername (&clientConfig, "user", - "password"); + if (clientUsername) + UA_ClientConfig_setAuthenticationUsername (&clientConfig, clientUsername, + clientPassword); UA_String discoveryUrl = UA_STRING_ALLOC (discoveryEndpoint); retval = UA_Server_registerDiscovery (server, &clientConfig, discoveryUrl, @@ -149,11 +227,12 @@ main (int argc, char **argv) memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( &clientConfig, applicationUri, clientCertPath, clientKeyPath, - argv + 11, trustSize, securityMode, securityPolicyUri); + argv + idx, trustSize, securityMode, securityPolicyUri); if (retval == UA_STATUSCODE_GOOD) { - UA_ClientConfig_setAuthenticationUsername (&clientConfig, "user", - "password"); + if (clientUsername) + UA_ClientConfig_setAuthenticationUsername ( + &clientConfig, clientUsername, clientPassword); UA_String reregUrl = UA_STRING_ALLOC (discoveryEndpoint); retval = UA_Server_registerDiscovery (server, &clientConfig, reregUrl, UA_STRING_NULL); @@ -169,12 +248,13 @@ main (int argc, char **argv) memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( - &clientConfig, applicationUri, clientCertPath, clientKeyPath, argv + 11, + &clientConfig, applicationUri, clientCertPath, clientKeyPath, argv + idx, trustSize, securityMode, securityPolicyUri); if (retval == UA_STATUSCODE_GOOD) { - UA_ClientConfig_setAuthenticationUsername (&clientConfig, "user", - "password"); + if (clientUsername) + UA_ClientConfig_setAuthenticationUsername ( + &clientConfig, clientUsername, clientPassword); UA_String deregUrl = UA_STRING_ALLOC (discoveryEndpoint); retval = UA_Server_deregisterDiscovery (server, &clientConfig, deregUrl); UA_String_clear (&deregUrl); |
