/** * @file server_register.c * @brief OPC UA Server that registers with a Local Discovery Server. * * This program runs an OPC UA server configured with security and periodically * registers itself with a remote LDS using the RegisterServer2 service. It * uses separate certificate pairs for the server and for the client connection * to the LDS. On shutdown, it deregisters from the LDS. */ #include "common.h" #include #include #include #include #include #include #include #include #include #include UA_Boolean running = true; static void stopHandler (int sign) { UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c"); running = false; } /* ======================================================================== * Main * ======================================================================== */ int main (int argc, char **argv) { signal (SIGINT, stopHandler); signal (SIGTERM, stopHandler); if (argc < 11) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Usage: %s\n" " \n" " \n" " \n" " \n" " \n" " \n" " [, ...]\n" "\n" "Security modes : None, Sign, SignAndEncrypt\n" "Security policies: None, Basic256Sha256, " "Aes256_Sha256_RsaPss,\n" " Aes128_Sha256_RsaOaep, ECC_nistP256", 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]); UA_MessageSecurityMode securityMode = parseSecurityMode (argv[9]); if (securityMode == UA_MESSAGESECURITYMODE_INVALID) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Unknown security mode: %s", argv[9]); return EXIT_FAILURE; } const char *securityPolicyUri = resolveSecurityPolicyUri (argv[10]); if (!securityPolicyUri) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Unknown security policy: %s", argv[10]); return EXIT_FAILURE; } size_t trustSize = (argc > 11) ? (size_t)argc - 11 : 0; UA_StatusCode retval; UA_Server *server = createSecureServer ( port, applicationUri, argv[3], argv[4], argv + 11, trustSize, &retval); if (!server) return EXIT_FAILURE; UA_ServerConfig *serverConfig = UA_Server_getConfig (server); /* Disallow anonymous sessions. 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) { UA_Server_delete (server); return EXIT_FAILURE; } serverConfig->applicationDescription.applicationType = UA_APPLICATIONTYPE_SERVER; UA_Server_run_startup (server); /* UA_Server_registerDiscovery consumes (clears) the client config, so a fresh zero-initialized config is needed for every call. */ UA_ClientConfig clientConfig; memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( &clientConfig, applicationUri, clientCertPath, clientKeyPath, argv + 11, trustSize, securityMode, securityPolicyUri); if (retval != UA_STATUSCODE_GOOD) { UA_Server_run_shutdown (server); UA_Server_delete (server); return EXIT_FAILURE; } UA_ClientConfig_setAuthenticationUsername (&clientConfig, "user", "password"); UA_String discoveryUrl = UA_STRING_ALLOC (discoveryEndpoint); retval = UA_Server_registerDiscovery (server, &clientConfig, discoveryUrl, UA_STRING_NULL); UA_String_clear (&discoveryUrl); if (retval != UA_STATUSCODE_GOOD) UA_LOG_WARNING (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Initial register failed: %s", UA_StatusCode_name (retval)); time_t lastRegister = time (NULL); while (running) { UA_Server_run_iterate (server, true); time_t now = time (NULL); if (now - lastRegister >= registerInterval) { memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( &clientConfig, applicationUri, clientCertPath, clientKeyPath, argv + 11, trustSize, securityMode, securityPolicyUri); if (retval == UA_STATUSCODE_GOOD) { UA_ClientConfig_setAuthenticationUsername (&clientConfig, "user", "password"); UA_String reregUrl = UA_STRING_ALLOC (discoveryEndpoint); retval = UA_Server_registerDiscovery (server, &clientConfig, reregUrl, UA_STRING_NULL); UA_String_clear (&reregUrl); if (retval != UA_STATUSCODE_GOOD) UA_LOG_WARNING (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Re-register failed: %s", UA_StatusCode_name (retval)); } lastRegister = now; } } memset (&clientConfig, 0, sizeof (UA_ClientConfig)); retval = createSecureClientConfig ( &clientConfig, applicationUri, clientCertPath, clientKeyPath, argv + 11, trustSize, securityMode, securityPolicyUri); if (retval == UA_STATUSCODE_GOOD) { UA_ClientConfig_setAuthenticationUsername (&clientConfig, "user", "password"); UA_String deregUrl = UA_STRING_ALLOC (discoveryEndpoint); retval = UA_Server_deregisterDiscovery (server, &clientConfig, deregUrl); UA_String_clear (&deregUrl); if (retval != UA_STATUSCODE_GOOD) UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Could not unregister from discovery server: %s", UA_StatusCode_name (retval)); } UA_Server_run_shutdown (server); UA_Server_delete (server); return EXIT_SUCCESS; }