aboutsummaryrefslogtreecommitdiffstats
path: root/src/server_register.c
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-17 03:31:40 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-17 03:31:40 +0100
commit3425cddd75fa105b940c8c0afe4a63065c446515 (patch)
treef1c2840985feeb06a9187d6bd99fe8274daf5412 /src/server_register.c
parent1bbf7e6c2ff571b2e26b643a7e86e35790b91875 (diff)
downloadBobinkCOpcUa-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.c124
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);