aboutsummaryrefslogtreecommitdiffstats
path: root/src/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common.c')
-rw-r--r--src/common.c150
1 files changed, 105 insertions, 45 deletions
diff --git a/src/common.c b/src/common.c
index 865fc55..cf364bb 100644
--- a/src/common.c
+++ b/src/common.c
@@ -172,43 +172,33 @@ parseLogLevel (const char *name)
}
int
-parseAuthConfig (const Config *cfg, const char *program,
- UA_Boolean *allowAnonymous, const char **username,
- const char **password, UA_Boolean *certAuth)
+parseAuthConfig (const Config *cfg, const char *program, AuthConfig *auth)
{
const char *authMode = configRequire (cfg, "authMode", program);
if (!authMode)
return -1;
- *username = NULL;
- *password = NULL;
- if (certAuth)
- *certAuth = false;
+ memset (auth, 0, sizeof (*auth));
if (strcmp (authMode, "anonymous") == 0)
{
- if (allowAnonymous)
- *allowAnonymous = true;
+ auth->mode = AUTH_ANONYMOUS;
return 0;
}
if (strcmp (authMode, "user") == 0)
{
- if (allowAnonymous)
- *allowAnonymous = false;
- *username = configRequire (cfg, "username", program);
- *password = configRequire (cfg, "password", program);
- if (!*username || !*password)
+ auth->mode = AUTH_USER;
+ auth->user.username = configRequire (cfg, "username", program);
+ auth->user.password = configRequire (cfg, "password", program);
+ if (!auth->user.username || !auth->user.password)
return -1;
return 0;
}
if (strcmp (authMode, "cert") == 0)
{
- if (allowAnonymous)
- *allowAnonymous = false;
- if (certAuth)
- *certAuth = true;
+ auth->mode = AUTH_CERT;
return 0;
}
@@ -219,6 +209,63 @@ parseAuthConfig (const Config *cfg, const char *program,
return -1;
}
+int
+parseSecurityConfig (const Config *cfg, const char *program,
+ UA_Boolean needsModePolicy, SecurityConfig *sec)
+{
+ memset (sec, 0, sizeof (*sec));
+
+ 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)
+ return 0;
+
+ if (!certPath || !keyPath || !trustStore)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "%s: incomplete security config: certificate, privateKey, "
+ "and trustStore must all be set, or all omitted",
+ program);
+ return -1;
+ }
+
+ sec->certPath = certPath;
+ sec->keyPath = keyPath;
+
+ if (needsModePolicy)
+ {
+ const char *secModeStr = configRequire (cfg, "securityMode", program);
+ const char *secPolStr = configRequire (cfg, "securityPolicy", program);
+ if (!secModeStr || !secPolStr)
+ return -1;
+
+ sec->securityMode = parseSecurityMode (secModeStr);
+ if (sec->securityMode == UA_MESSAGESECURITYMODE_INVALID)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "%s: unknown security mode: %s", program, secModeStr);
+ return -1;
+ }
+
+ sec->securityPolicyUri = resolveSecurityPolicyUri (secPolStr);
+ if (!sec->securityPolicyUri)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "%s: unknown security policy: %s", program, secPolStr);
+ return -1;
+ }
+ }
+
+ if (loadTrustStore (trustStore, &sec->trustPaths, &sec->trustSize) != 0)
+ return -1;
+
+ return 0;
+}
+
UA_MessageSecurityMode
parseSecurityMode (const char *name)
{
@@ -351,26 +398,26 @@ printEndpoint (const UA_EndpointDescription *endpoint, size_t index)
* ======================================================================== */
UA_Server *
-createServer (UA_UInt16 port, const char *applicationUri, const char *certPath,
- const char *keyPath, char **trustPaths, size_t trustSize,
- UA_Boolean discovery, UA_StatusCode *retval)
+createServer (UA_UInt16 port, const char *applicationUri,
+ const SecurityConfig *sec, UA_Boolean discovery,
+ UA_StatusCode *retval)
{
UA_Server *server = UA_Server_new ();
UA_ServerConfig *config = UA_Server_getConfig (server);
- if (certPath)
+ if (sec && sec->certPath)
{
- UA_ByteString certificate = loadFile (certPath);
- UA_ByteString privateKey = loadFile (keyPath);
+ UA_ByteString certificate = loadFile (sec->certPath);
+ UA_ByteString privateKey = loadFile (sec->keyPath);
/* +1: UA_STACKARRAY requires a strictly positive size for VLA. */
- UA_STACKARRAY (UA_ByteString, trustList, trustSize + 1);
- for (size_t i = 0; i < trustSize; i++)
- trustList[i] = loadFile (trustPaths[i]);
+ UA_STACKARRAY (UA_ByteString, trustList, sec->trustSize + 1);
+ for (size_t i = 0; i < sec->trustSize; i++)
+ trustList[i] = loadFile (sec->trustPaths[i]);
*retval = UA_ServerConfig_setDefaultWithSecureSecurityPolicies (
- config, port, &certificate, &privateKey, trustList, trustSize, NULL,
- 0, NULL, 0);
+ config, port, &certificate, &privateKey, trustList, sec->trustSize,
+ NULL, 0, NULL, 0);
/* When discovery is true (LDS) add SecurityPolicy#None
restricted to discovery services so that unencrypted clients
@@ -390,7 +437,7 @@ createServer (UA_UInt16 port, const char *applicationUri, const char *certPath,
UA_ByteString_clear (&certificate);
UA_ByteString_clear (&privateKey);
- for (size_t i = 0; i < trustSize; i++)
+ for (size_t i = 0; i < sec->trustSize; i++)
UA_ByteString_clear (&trustList[i]);
}
else
@@ -412,8 +459,16 @@ createServer (UA_UInt16 port, const char *applicationUri, const char *certPath,
}
UA_StatusCode
-createUnsecureClientConfig (UA_ClientConfig *cc, const char *applicationUri)
+createUnsecureClientConfig (UA_ClientConfig *cc, const char *applicationUri,
+ const AuthConfig *auth)
{
+ if (auth && auth->mode == AUTH_CERT)
+ {
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_APPLICATION,
+ "Certificate authentication requires encryption");
+ return UA_STATUSCODE_BADINVALIDARGUMENT;
+ }
+
UA_StatusCode retval = UA_ClientConfig_setDefault (cc);
if (retval != UA_STATUSCODE_GOOD)
return retval;
@@ -426,38 +481,39 @@ createUnsecureClientConfig (UA_ClientConfig *cc, const char *applicationUri)
cc->securityPolicyUri = UA_String_fromChars (
"http://opcfoundation.org/UA/SecurityPolicy#None");
+ if (auth && auth->mode == AUTH_USER)
+ UA_ClientConfig_setAuthenticationUsername (cc, auth->user.username,
+ auth->user.password);
+
return UA_STATUSCODE_GOOD;
}
UA_StatusCode
createSecureClientConfig (UA_ClientConfig *cc, const char *applicationUri,
- const char *certPath, const char *keyPath,
- char **trustPaths, size_t trustSize,
- UA_MessageSecurityMode securityMode,
- const char *securityPolicyUri, UA_Boolean certAuth)
+ const SecurityConfig *sec, const AuthConfig *auth)
{
- UA_ByteString certificate = loadFile (certPath);
- UA_ByteString privateKey = loadFile (keyPath);
+ UA_ByteString certificate = loadFile (sec->certPath);
+ UA_ByteString privateKey = loadFile (sec->keyPath);
/* +1: UA_STACKARRAY requires a strictly positive size for VLA. */
- UA_STACKARRAY (UA_ByteString, trustList, trustSize + 1);
- for (size_t i = 0; i < trustSize; i++)
- trustList[i] = loadFile (trustPaths[i]);
+ UA_STACKARRAY (UA_ByteString, trustList, sec->trustSize + 1);
+ for (size_t i = 0; i < sec->trustSize; i++)
+ trustList[i] = loadFile (sec->trustPaths[i]);
UA_StatusCode retval = UA_ClientConfig_setDefaultEncryption (
- cc, certificate, privateKey, trustList, trustSize, NULL, 0);
+ cc, certificate, privateKey, trustList, sec->trustSize, NULL, 0);
/* X509 identity token: reuse the application certificate. open62541
requires that the identity cert matches the SecureChannel cert, so
a separate user cert cannot be used. Call before clearing the local
buffers since setAuthenticationCert makes its own copy. */
- if (retval == UA_STATUSCODE_GOOD && certAuth)
+ if (retval == UA_STATUSCODE_GOOD && auth && auth->mode == AUTH_CERT)
retval
= UA_ClientConfig_setAuthenticationCert (cc, certificate, privateKey);
UA_ByteString_clear (&certificate);
UA_ByteString_clear (&privateKey);
- for (size_t i = 0; i < trustSize; i++)
+ for (size_t i = 0; i < sec->trustSize; i++)
UA_ByteString_clear (&trustList[i]);
if (retval != UA_STATUSCODE_GOOD)
@@ -471,8 +527,12 @@ createSecureClientConfig (UA_ClientConfig *cc, const char *applicationUri,
UA_String_clear (&cc->clientDescription.applicationUri);
cc->clientDescription.applicationUri = UA_String_fromChars (applicationUri);
- cc->securityMode = securityMode;
- cc->securityPolicyUri = UA_String_fromChars (securityPolicyUri);
+ cc->securityMode = sec->securityMode;
+ cc->securityPolicyUri = UA_String_fromChars (sec->securityPolicyUri);
+
+ if (auth && auth->mode == AUTH_USER)
+ UA_ClientConfig_setAuthenticationUsername (cc, auth->user.username,
+ auth->user.password);
return retval;
}