Browse Source

Config: Configure the UserTokenPolicy; Warn if password is unencrypted

Julius Pfrommer 4 years ago
parent
commit
85c4d53b1c

+ 2 - 2
examples/access_control/server_access_control.c

@@ -62,8 +62,8 @@ int main(void) {
 
     /* Disable anonymous logins, enable two user/password logins */
     config->accessControl.deleteMembers(&config->accessControl);
-    UA_StatusCode retval = UA_AccessControl_default(&config->accessControl,
-                                                    false, 2, logins);
+    UA_StatusCode retval = UA_AccessControl_default(config, false,
+             &config->securityPolicies[config->securityPoliciesSize-1].policyUri, 2, logins);
     if(retval != UA_STATUSCODE_GOOD)
         goto cleanup;
 

+ 2 - 1
plugins/include/open62541/plugin/accesscontrol_default.h

@@ -21,7 +21,8 @@ typedef struct {
 /* Default access control. The log-in can be anonymous or username-password. A
  * logged-in user has all access rights. */
 UA_EXPORT UA_StatusCode
-UA_AccessControl_default(UA_AccessControl *ac, UA_Boolean allowAnonymous,
+UA_AccessControl_default(UA_ServerConfig *config, UA_Boolean allowAnonymous,
+                         const UA_ByteString *userTokenPolicyUri,
                          size_t usernamePasswordLoginSize,
                          const UA_UsernamePasswordLogin *usernamePasswordLogin);
 

+ 17 - 8
plugins/ua_accesscontrol_default.c

@@ -6,6 +6,7 @@
  */
 
 #include <open62541/plugin/accesscontrol_default.h>
+#include <open62541/server_config.h>
 
 /* Example access control management. Anonymous and username / password login.
  * The access rights are maximally permissive. */
@@ -213,9 +214,11 @@ static void deleteMembers_default(UA_AccessControl *ac) {
 }
 
 UA_StatusCode
-UA_AccessControl_default(UA_AccessControl *ac,
-                         UA_Boolean allowAnonymous, size_t usernamePasswordLoginSize,
+UA_AccessControl_default(UA_ServerConfig *config, UA_Boolean allowAnonymous,
+                         const UA_ByteString *userTokenPolicyUri,
+                         size_t usernamePasswordLoginSize,
                          const UA_UsernamePasswordLogin *usernamePasswordLogin) {
+    UA_AccessControl *ac = &config->accessControl;
     ac->deleteMembers = deleteMembers_default;
     ac->activateSession = activateSession_default;
     ac->closeSession = closeSession_default;
@@ -282,13 +285,19 @@ UA_AccessControl_default(UA_AccessControl *ac,
     if(usernamePasswordLoginSize > 0) {
         ac->userTokenPolicies[policies].tokenType = UA_USERTOKENTYPE_USERNAME;
         ac->userTokenPolicies[policies].policyId = UA_STRING_ALLOC(USERNAME_POLICY);
-        if (!ac->userTokenPolicies[policies].policyId.data)
-            return UA_STATUSCODE_BADOUTOFMEMORY;
-        /* No encryption of username/password supported at the moment */
-        ac->userTokenPolicies[policies].securityPolicyUri =
-            UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#None");
-        if (!ac->userTokenPolicies[policies].securityPolicyUri.data)
+        if(!ac->userTokenPolicies[policies].policyId.data)
             return UA_STATUSCODE_BADOUTOFMEMORY;
+
+#if UA_LOGLEVEL <= 400
+        const UA_String noneUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None");
+        if(UA_ByteString_equal(userTokenPolicyUri, &noneUri)) {
+            UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_SERVER,
+                           "Username/Password configured, but no encrypting SecurityPolicy. "
+                           "This can leak credentials on the network.");
+        }
+#endif
+        return UA_ByteString_copy(userTokenPolicyUri,
+                                  &ac->userTokenPolicies[policies].securityPolicyUri);
     }
     return UA_STATUSCODE_GOOD;
 }

+ 19 - 12
plugins/ua_config_default.c

@@ -81,12 +81,10 @@ createEndpoint(UA_ServerConfig *conf, UA_EndpointDescription *endpoint,
                                          &UA_TYPES[UA_TYPES_USERTOKENPOLICY]);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
-    endpoint->userIdentityTokensSize =
-        conf->accessControl.userTokenPoliciesSize;
+    endpoint->userIdentityTokensSize = conf->accessControl.userTokenPoliciesSize;
 
     UA_String_copy(&securityPolicy->localCertificate, &endpoint->serverCertificate);
-    UA_ApplicationDescription_copy(&conf->applicationDescription,
-                                   &endpoint->server);
+    UA_ApplicationDescription_copy(&conf->applicationDescription, &endpoint->server);
 
     return UA_STATUSCODE_GOOD;
 }
@@ -157,14 +155,6 @@ setDefaultConfig(UA_ServerConfig *conf) {
     conf->nodeLifecycle.constructor = NULL;
     conf->nodeLifecycle.destructor = NULL;
 
-    UA_StatusCode retval = UA_AccessControl_default(&conf->accessControl, true,
-                                                    usernamePasswordsSize,
-                                                    usernamePasswords);
-    if(retval != UA_STATUSCODE_GOOD) {
-        UA_ServerConfig_clean(conf);
-        return retval;
-    }
-
     /* Relax constraints for the InformationModel */
     conf->relaxEmptyValueConstraint = true; /* Allow empty values */
 
@@ -383,6 +373,15 @@ UA_ServerConfig_setMinimalCustomBuffer(UA_ServerConfig *config, UA_UInt16 portNu
         return retval;
     }
 
+    /* Initialize the Access Control plugin */
+    retval = UA_AccessControl_default(config, true,
+                &config->securityPolicies[config->securityPoliciesSize-1].policyUri,
+                usernamePasswordsSize, usernamePasswords);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_ServerConfig_clean(config);
+        return retval;
+    }
+
     /* Allocate the endpoint */
     retval = UA_ServerConfig_addEndpoint(config, UA_SECURITY_POLICY_NONE_URI, UA_MESSAGESECURITYMODE_NONE);
     if(retval != UA_STATUSCODE_GOOD) {
@@ -574,6 +573,14 @@ UA_ServerConfig_setDefaultWithSecurityPolicies(UA_ServerConfig *conf,
         return retval;
     }
 
+    retval = UA_AccessControl_default(conf, true,
+                &conf->securityPolicies[conf->securityPoliciesSize-1].policyUri,
+                usernamePasswordsSize, usernamePasswords);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_ServerConfig_clean(conf);
+        return retval;
+    }
+
     retval = UA_ServerConfig_addAllEndpoints(conf);
     if(retval != UA_STATUSCODE_GOOD) {
         UA_ServerConfig_clean(conf);