diff options
Diffstat (limited to 'src/common.c')
| -rw-r--r-- | src/common.c | 150 |
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; } |
