diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/client_find_servers.c | 80 | ||||
| -rw-r--r-- | src/config.c | 252 | ||||
| -rw-r--r-- | src/config.h | 120 | ||||
| -rw-r--r-- | src/server_lds.c | 74 | ||||
| -rw-r--r-- | src/server_register.c | 145 |
5 files changed, 551 insertions, 120 deletions
diff --git a/src/client_find_servers.c b/src/client_find_servers.c index 21d48ca..e50623f 100644 --- a/src/client_find_servers.c +++ b/src/client_find_servers.c @@ -10,6 +10,7 @@ */ #include "common.h" +#include "config.h" #include <open62541/client_highlevel.h> #include <open62541/plugin/log_stdout.h> @@ -210,64 +211,71 @@ readServerTime (UA_Client *client, int main (int argc, char **argv) { - if (argc < 8) + if (argc != 2) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Usage: %s <discovery-server-endpoint>\n" - " <applicationUri>\n" - " <certificate.der> <private-key.der>\n" - " <security-mode> <security-policy>\n" - " <auth-mode> [<username> <password>]\n" - " [<trustlist1.der>, ...]\n" - "\n" - "Security modes : None, Sign, SignAndEncrypt\n" - "Security policies: None, Basic256Sha256, " - "Aes256_Sha256_RsaPss,\n" - " Aes128_Sha256_RsaOaep, ECC_nistP256\n" - "Auth modes : anonymous, user", - argv[0]); + "Usage: %s <config-file>", argv[0]); return EXIT_FAILURE; } - const char *discoveryServerEndpoint = argv[1]; - const char *applicationUri = argv[2]; - const char *certPath = argv[3]; - const char *keyPath = argv[4]; + Config cfg; + if (configLoad (argv[1], &cfg) != 0) + return EXIT_FAILURE; + + const char *discoveryServerEndpoint + = configRequire (&cfg, "discoveryEndpoint", "ClientFindServers"); + const char *applicationUri + = configRequire (&cfg, "applicationUri", "ClientFindServers"); + const char *certPath + = configRequire (&cfg, "certificate", "ClientFindServers"); + const char *keyPath + = configRequire (&cfg, "privateKey", "ClientFindServers"); + const char *securityModeStr + = configRequire (&cfg, "securityMode", "ClientFindServers"); + const char *securityPolicyStr + = configRequire (&cfg, "securityPolicy", "ClientFindServers"); + const char *authMode = configRequire (&cfg, "authMode", "ClientFindServers"); + + if (!discoveryServerEndpoint || !applicationUri || !certPath || !keyPath + || !securityModeStr || !securityPolicyStr || !authMode) + { + configFree (&cfg); + return EXIT_FAILURE; + } - UA_MessageSecurityMode securityMode = parseSecurityMode (argv[5]); + UA_MessageSecurityMode securityMode = parseSecurityMode (securityModeStr); if (securityMode == UA_MESSAGESECURITYMODE_INVALID) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Unknown security mode: %s", argv[5]); + "Unknown security mode: %s", securityModeStr); + configFree (&cfg); return EXIT_FAILURE; } - const char *securityPolicyUri = resolveSecurityPolicyUri (argv[6]); + const char *securityPolicyUri = resolveSecurityPolicyUri (securityPolicyStr); if (!securityPolicyUri) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Unknown security policy: %s", argv[6]); + "Unknown security policy: %s", securityPolicyStr); + configFree (&cfg); return EXIT_FAILURE; } - int idx = 7; - const char *authMode = argv[idx++]; const char *username = NULL, *password = NULL; if (strcmp (authMode, "anonymous") == 0) { - /* No extra args needed */ + /* No credentials needed */ } else if (strcmp (authMode, "user") == 0) { - if (idx + 2 > argc) + username = configRequire (&cfg, "username", "ClientFindServers"); + password = configRequire (&cfg, "password", "ClientFindServers"); + if (!username || !password) { - UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Auth mode 'user' requires <username> <password>"); + configFree (&cfg); return EXIT_FAILURE; } - username = argv[idx++]; - password = argv[idx++]; } else { @@ -275,11 +283,13 @@ main (int argc, char **argv) "Unknown auth mode: %s " "(expected 'anonymous' or 'user')", authMode); + configFree (&cfg); return EXIT_FAILURE; } - char **trustPaths = argv + idx; - size_t trustSize = (idx < argc) ? (size_t)(argc - idx) : 0; + char **trustPaths = NULL; + size_t trustSize = 0; + configGetAll (&cfg, "trustList", &trustPaths, &trustSize); UA_Client *client = UA_Client_new (); UA_StatusCode retval = createSecureClientConfig ( @@ -288,6 +298,8 @@ main (int argc, char **argv) if (retval != UA_STATUSCODE_GOOD) { UA_Client_delete (client); + free (trustPaths); + configFree (&cfg); return EXIT_FAILURE; } @@ -300,6 +312,8 @@ main (int argc, char **argv) if (retval != UA_STATUSCODE_GOOD) { UA_Client_delete (client); + free (trustPaths); + configFree (&cfg); return EXIT_FAILURE; } @@ -313,6 +327,8 @@ main (int argc, char **argv) UA_Array_delete (applicationDescriptionArray, applicationDescriptionArraySize, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); + free (trustPaths); + configFree (&cfg); return EXIT_SUCCESS; } diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..163f601 --- /dev/null +++ b/src/config.c @@ -0,0 +1,252 @@ +/** + * @file config.c + * @brief Simple key=value configuration file parser implementation. + */ + +#include "config.h" + +#include <open62541/plugin/log_stdout.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* Enough for typical config files; doubles on overflow. */ +#define CONFIG_INITIAL_CAPACITY 16 + +/* Sufficient for file paths and URIs. */ +#define CONFIG_LINE_MAX 1024 + +/* ======================================================================== + * Static Helpers + * ======================================================================== */ + +/** + * @brief Trims leading and trailing whitespace in place. + * + * Modifies the string by writing a NUL terminator after the last + * non-whitespace character and returns a pointer past any leading + * whitespace. + */ +static char * +trim (char *s) +{ + while (*s == ' ' || *s == '\t') + s++; + size_t len = strlen (s); + while (len > 0 && (s[len - 1] == ' ' || s[len - 1] == '\t')) + len--; + s[len] = '\0'; + return s; +} + +/** + * @brief Appends a key-value pair to the config's dynamic array. + * + * Grows the array by doubling capacity when full. + * + * @return 0 on success, -1 on allocation failure. + */ +static int +configAppend (Config *cfg, const char *key, const char *value) +{ + if (cfg->count == cfg->capacity) + { + size_t newCap = cfg->capacity * 2; + ConfigEntry *tmp = realloc (cfg->entries, newCap * sizeof (ConfigEntry)); + if (!tmp) + { + UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Config: out of memory"); + return -1; + } + cfg->entries = tmp; + cfg->capacity = newCap; + } + + cfg->entries[cfg->count].key = strdup (key); + cfg->entries[cfg->count].value = strdup (value); + if (!cfg->entries[cfg->count].key || !cfg->entries[cfg->count].value) + { + UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Config: out of memory"); + return -1; + } + cfg->count++; + return 0; +} + +/* ======================================================================== + * Public API + * ======================================================================== */ + +int +configLoad (const char *path, Config *cfg) +{ + memset (cfg, 0, sizeof (Config)); + + cfg->entries = malloc (CONFIG_INITIAL_CAPACITY * sizeof (ConfigEntry)); + if (!cfg->entries) + { + UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Config: out of memory"); + return -1; + } + cfg->capacity = CONFIG_INITIAL_CAPACITY; + + FILE *fp = fopen (path, "r"); + if (!fp) + { + UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Config: cannot open '%s'", path); + free (cfg->entries); + memset (cfg, 0, sizeof (Config)); + return -1; + } + + char line[CONFIG_LINE_MAX]; + int lineNum = 0; + + while (fgets (line, sizeof (line), fp)) + { + lineNum++; + + /* Strip trailing newline / carriage return. */ + size_t len = strlen (line); + while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) + line[--len] = '\0'; + + /* Skip blank lines and comments. */ + char *trimmed = trim (line); + if (*trimmed == '\0' || *trimmed == '#') + continue; + + /* Find the '=' separator. */ + char *eq = strchr (trimmed, '='); + if (!eq) + { + UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Config: syntax error at %s:%d " + "(missing '=')", + path, lineNum); + fclose (fp); + configFree (cfg); + return -1; + } + + *eq = '\0'; + char *key = trim (trimmed); + char *value = trim (eq + 1); + + if (*key == '\0') + { + UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Config: empty key at %s:%d", path, lineNum); + fclose (fp); + configFree (cfg); + return -1; + } + + if (configAppend (cfg, key, value) != 0) + { + fclose (fp); + configFree (cfg); + return -1; + } + } + + fclose (fp); + return 0; +} + +const char * +configGet (const Config *cfg, const char *key) +{ + for (size_t i = 0; i < cfg->count; i++) + { + if (strcmp (cfg->entries[i].key, key) == 0) + return cfg->entries[i].value; + } + return NULL; +} + +const char * +configRequire (const Config *cfg, const char *key, const char *program) +{ + const char *val = configGet (cfg, key); + if (!val) + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "%s: missing required config key '%s'", program, key); + return val; +} + +int +configRequireInt (const Config *cfg, const char *key, const char *program) +{ + const char *val = configRequire (cfg, key, program); + if (!val) + return -1; + + char *endptr; + long num = strtol (val, &endptr, 10); + if (*endptr != '\0') + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "%s: config key '%s' is not a valid integer: '%s'", + program, key, val); + return -1; + } + return (int)num; +} + +void +configGetAll (const Config *cfg, const char *key, char ***out, size_t *size) +{ + /* First pass: count matches. */ + size_t count = 0; + for (size_t i = 0; i < cfg->count; i++) + { + if (strcmp (cfg->entries[i].key, key) == 0) + count++; + } + + if (count == 0) + { + *out = NULL; + *size = 0; + return; + } + + /* Second pass: collect pointers. */ + char **arr = malloc (count * sizeof (char *)); + if (!arr) + { + UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Config: out of memory"); + *out = NULL; + *size = 0; + return; + } + + size_t idx = 0; + for (size_t i = 0; i < cfg->count; i++) + { + if (strcmp (cfg->entries[i].key, key) == 0) + arr[idx++] = cfg->entries[i].value; + } + + *out = arr; + *size = count; +} + +void +configFree (Config *cfg) +{ + for (size_t i = 0; i < cfg->count; i++) + { + free (cfg->entries[i].key); + free (cfg->entries[i].value); + } + free (cfg->entries); + memset (cfg, 0, sizeof (Config)); +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..ee29ada --- /dev/null +++ b/src/config.h @@ -0,0 +1,120 @@ +/** + * @file config.h + * @brief Simple key=value configuration file parser. + * + * Parses configuration files with one key=value pair per line. + * Lines starting with '#' are comments. Blank lines are ignored. + * Repeated keys are allowed (used for list-valued settings like + * trustList). + */ + +#ifndef DISCOVERY_CONFIG_H +#define DISCOVERY_CONFIG_H + +#include <stddef.h> + +/** + * @brief A single key=value entry from a config file. + * + * Both key and value are heap-allocated, null-terminated strings + * with leading/trailing whitespace trimmed. + */ +typedef struct +{ + char *key; + char *value; +} ConfigEntry; + +/** + * @brief A parsed configuration file. + * + * Holds a dynamic array of ConfigEntry items. Duplicate keys are + * allowed (used for list-valued settings like trustList). + */ +typedef struct +{ + ConfigEntry *entries; + size_t count; + size_t capacity; +} Config; + +/** + * @brief Parses a configuration file into a Config structure. + * + * Each non-blank, non-comment line must contain '=' separating key + * and value. Whitespace is trimmed around both key and value. + * + * @param path Path to the configuration file. + * @param cfg Output: the parsed configuration. Must be freed + * with configFree() when no longer needed. + * @return 0 on success, -1 on error (logged via UA_LOG_ERROR). + */ +int configLoad (const char *path, Config *cfg); + +/** + * @brief Looks up a single-valued key. + * + * Returns the value of the first entry matching @p key, or NULL + * if the key is not present. + * + * @param cfg The parsed configuration. + * @param key The key to search for. + * @return The value string (owned by cfg), or NULL. + */ +const char *configGet (const Config *cfg, const char *key); + +/** + * @brief Looks up a required single-valued key. + * + * Like configGet(), but logs a FATAL error and returns NULL when + * the key is missing. + * + * @param cfg The parsed configuration. + * @param key The key to search for. + * @param program Program name (for error messages). + * @return The value string (owned by cfg), or NULL if missing. + */ +const char *configRequire (const Config *cfg, const char *key, + const char *program); + +/** + * @brief Looks up a required integer-valued key. + * + * Parses the value of @p key as an integer. If the key is + * missing or the value is not a valid integer, logs a FATAL + * error and returns -1. + * + * @param cfg The parsed configuration. + * @param key The key to search for. + * @param program Program name (for error messages). + * @return The parsed integer, or -1 on error. + */ +int configRequireInt (const Config *cfg, const char *key, const char *program); + +/** + * @brief Collects all values for a repeated key. + * + * Allocates an array of char* pointers to the values stored + * in @p cfg. The caller must free the array itself (but not + * the strings, which are owned by cfg). + * + * @param cfg The parsed configuration. + * @param key The key to collect (e.g. "trustList"). + * @param out Output: heap-allocated array of string pointers. + * Set to NULL if the key is not present. + * @param size Output: number of entries in @p out. + */ +void configGetAll (const Config *cfg, const char *key, char ***out, + size_t *size); + +/** + * @brief Frees all memory owned by a Config structure. + * + * After this call the Config is zeroed and must not be used + * unless configLoad() is called again. + * + * @param cfg The configuration to free. + */ +void configFree (Config *cfg); + +#endif /* DISCOVERY_CONFIG_H */ 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 <open62541/plugin/accesscontrol_default.h> #include <open62541/plugin/log_stdout.h> @@ -17,6 +18,7 @@ #include <signal.h> #include <stdlib.h> +#include <string.h> 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" - " <port> <applicationUri>\n" - " <server-certificate.der> <private-key.der>\n" - " <cleanup-timeout-seconds>\n" - " <auth-mode> [<username> <password>]\n" - " [<trustlist1.der>, ...]\n" - "\n" - "Auth modes: anonymous, user", - argv[0]); + "Usage: %s <config-file>", 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 <username> <password>"); + 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; } diff --git a/src/server_register.c b/src/server_register.c index 60a4998..ae8e959 100644 --- a/src/server_register.c +++ b/src/server_register.c @@ -9,6 +9,7 @@ */ #include "common.h" +#include "config.h" #include <open62541/client.h> #include <open62541/client_config_default.h> @@ -41,59 +42,73 @@ main (int argc, char **argv) signal (SIGINT, stopHandler); signal (SIGTERM, stopHandler); - if (argc < 13) + if (argc != 2) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Usage: %s\n" - " <port> <applicationUri>\n" - " <server-certificate.der> <server-private-key.der>\n" - " <client-certificate.der> <client-private-key.der>\n" - " <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\n" - "Auth modes : anonymous, user", - argv[0]); + "Usage: %s <config-file>", argv[0]); return EXIT_FAILURE; } - UA_UInt16 port = (UA_UInt16)atoi (argv[1]); - const char *applicationUri = argv[2]; - const char *clientCertPath = argv[5]; - const char *clientKeyPath = argv[6]; - const char *discoveryEndpoint = argv[7]; - int registerInterval = atoi (argv[8]); + Config cfg; + if (configLoad (argv[1], &cfg) != 0) + return EXIT_FAILURE; + + int port = configRequireInt (&cfg, "port", "ServerRegister"); + const char *applicationUri + = configRequire (&cfg, "applicationUri", "ServerRegister"); + const char *serverCertPath + = configRequire (&cfg, "serverCertificate", "ServerRegister"); + const char *serverKeyPath + = configRequire (&cfg, "serverPrivateKey", "ServerRegister"); + const char *clientCertPath + = configRequire (&cfg, "clientCertificate", "ServerRegister"); + const char *clientKeyPath + = configRequire (&cfg, "clientPrivateKey", "ServerRegister"); + const char *discoveryEndpoint + = configRequire (&cfg, "discoveryEndpoint", "ServerRegister"); + int registerInterval + = configRequireInt (&cfg, "registerInterval", "ServerRegister"); + const char *securityModeStr + = configRequire (&cfg, "securityMode", "ServerRegister"); + const char *securityPolicyStr + = configRequire (&cfg, "securityPolicy", "ServerRegister"); + const char *serverAuthMode + = configRequire (&cfg, "serverAuthMode", "ServerRegister"); + const char *clientAuthMode + = configRequire (&cfg, "clientAuthMode", "ServerRegister"); + + if (!applicationUri || !serverCertPath || !serverKeyPath || !clientCertPath + || !clientKeyPath || !discoveryEndpoint || !securityModeStr + || !securityPolicyStr || !serverAuthMode || !clientAuthMode || port < 0 + || registerInterval < 0) + { + configFree (&cfg); + return EXIT_FAILURE; + } - UA_MessageSecurityMode securityMode = parseSecurityMode (argv[9]); + UA_MessageSecurityMode securityMode = parseSecurityMode (securityModeStr); if (securityMode == UA_MESSAGESECURITYMODE_INVALID) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Unknown security mode: %s", argv[9]); + "Unknown security mode: %s", securityModeStr); + configFree (&cfg); return EXIT_FAILURE; } - const char *securityPolicyUri = resolveSecurityPolicyUri (argv[10]); + const char *securityPolicyUri = resolveSecurityPolicyUri (securityPolicyStr); if (!securityPolicyUri) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Unknown security policy: %s", argv[10]); + "Unknown security policy: %s", securityPolicyStr); + configFree (&cfg); 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. */ - int idx = 11; - const char *serverAuthMode = argv[idx++]; UA_Boolean serverAllowAnonymous; - char *serverUsername = NULL, *serverPassword = NULL; + const char *serverUsername = NULL, *serverPassword = NULL; if (strcmp (serverAuthMode, "anonymous") == 0) { @@ -101,16 +116,16 @@ main (int argc, char **argv) } else if (strcmp (serverAuthMode, "user") == 0) { - if (idx + 2 > argc) + serverAllowAnonymous = false; + serverUsername + = configRequire (&cfg, "serverUsername", "ServerRegister"); + serverPassword + = configRequire (&cfg, "serverPassword", "ServerRegister"); + if (!serverUsername || !serverPassword) { - UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Server auth mode 'user' requires " - "<username> <password>"); + configFree (&cfg); return EXIT_FAILURE; } - serverAllowAnonymous = false; - serverUsername = argv[idx++]; - serverPassword = argv[idx++]; } else { @@ -118,34 +133,28 @@ main (int argc, char **argv) "Unknown server auth mode: %s " "(expected 'anonymous' or 'user')", serverAuthMode); + configFree (&cfg); 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; + const char *clientUsername = NULL, *clientPassword = NULL; if (strcmp (clientAuthMode, "anonymous") == 0) { } else if (strcmp (clientAuthMode, "user") == 0) { - if (idx + 2 > argc) + clientUsername + = configRequire (&cfg, "clientUsername", "ServerRegister"); + clientPassword + = configRequire (&cfg, "clientPassword", "ServerRegister"); + if (!clientUsername || !clientPassword) { - UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Client auth mode 'user' requires " - "<username> <password>"); + configFree (&cfg); return EXIT_FAILURE; } - clientUsername = argv[idx++]; - clientPassword = argv[idx++]; } else { @@ -153,16 +162,24 @@ main (int argc, char **argv) "Unknown client auth mode: %s " "(expected 'anonymous' or 'user')", clientAuthMode); + 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, applicationUri, argv[3], argv[4], argv + idx, trustSize, &retval); + UA_Server *server + = createSecureServer ((UA_UInt16)port, applicationUri, serverCertPath, + serverKeyPath, trustPaths, trustSize, &retval); if (!server) - return EXIT_FAILURE; + { + free (trustPaths); + configFree (&cfg); + return EXIT_FAILURE; + } UA_ServerConfig *serverConfig = UA_Server_getConfig (server); @@ -173,12 +190,14 @@ main (int argc, char **argv) if (!serverAllowAnonymous) { UA_UsernamePasswordLogin logins[1]; - logins[0].username = UA_STRING (serverUsername); - logins[0].password = UA_STRING (serverPassword); + logins[0].username = UA_STRING ((char *)serverUsername); + logins[0].password = UA_STRING ((char *)serverPassword); 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; } } @@ -195,12 +214,14 @@ main (int argc, char **argv) UA_ClientConfig clientConfig; memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( - &clientConfig, applicationUri, clientCertPath, clientKeyPath, argv + idx, + &clientConfig, applicationUri, clientCertPath, clientKeyPath, trustPaths, trustSize, securityMode, securityPolicyUri); if (retval != UA_STATUSCODE_GOOD) { UA_Server_run_shutdown (server); UA_Server_delete (server); + free (trustPaths); + configFree (&cfg); return EXIT_FAILURE; } if (clientUsername) @@ -230,7 +251,7 @@ main (int argc, char **argv) memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( &clientConfig, applicationUri, clientCertPath, clientKeyPath, - argv + idx, trustSize, securityMode, securityPolicyUri); + trustPaths, trustSize, securityMode, securityPolicyUri); if (retval == UA_STATUSCODE_GOOD) { if (clientUsername) @@ -253,7 +274,7 @@ main (int argc, char **argv) our entry immediately rather than waiting for the cleanup timeout. */ memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( - &clientConfig, applicationUri, clientCertPath, clientKeyPath, argv + idx, + &clientConfig, applicationUri, clientCertPath, clientKeyPath, trustPaths, trustSize, securityMode, securityPolicyUri); if (retval == UA_STATUSCODE_GOOD) { @@ -271,5 +292,7 @@ main (int argc, char **argv) UA_Server_run_shutdown (server); UA_Server_delete (server); + free (trustPaths); + configFree (&cfg); return EXIT_SUCCESS; } |
