mirror of
https://github.com/open62541/open62541.git
synced 2025-06-03 04:00:21 +00:00
feat(plugin): allow custom password validation
Username password validation in access control plugin allows only passwords stored in plaintext. Add a callback to implement custom validation. This allows salted password hashes and timing safe comparison in the server. Furthermore remote validation could be implemented. The new function UA_AccessControl_defaultWithLoginCallback() calls existing UA_AccessControl_default() and after that installs the given UA_UsernamePasswordLoginCallback with context.
This commit is contained in:
parent
1186cfd559
commit
f4b481276a
@ -18,6 +18,11 @@ typedef struct {
|
||||
UA_String password;
|
||||
} UA_UsernamePasswordLogin;
|
||||
|
||||
typedef UA_StatusCode (*UA_UsernamePasswordLoginCallback)
|
||||
(const UA_String *userName, const UA_ByteString *password,
|
||||
size_t usernamePasswordLoginSize, const UA_UsernamePasswordLogin
|
||||
*usernamePasswordLogin, void **sessionContext, void *loginContext);
|
||||
|
||||
/* Default access control. The log-in can be anonymous or username-password. A
|
||||
* logged-in user has all access rights.
|
||||
*
|
||||
@ -31,6 +36,16 @@ UA_AccessControl_default(UA_ServerConfig *config,
|
||||
size_t usernamePasswordLoginSize,
|
||||
const UA_UsernamePasswordLogin *usernamePasswordLogin);
|
||||
|
||||
UA_EXPORT UA_StatusCode
|
||||
UA_AccessControl_defaultWithLoginCallback(UA_ServerConfig *config,
|
||||
UA_Boolean allowAnonymous,
|
||||
UA_CertificateVerification *verifyX509,
|
||||
const UA_ByteString *userTokenPolicyUri,
|
||||
size_t usernamePasswordLoginSize,
|
||||
const UA_UsernamePasswordLogin *usernamePasswordLogin,
|
||||
UA_UsernamePasswordLoginCallback loginCallback,
|
||||
void *loginContext);
|
||||
|
||||
_UA_END_DECLS
|
||||
|
||||
#endif /* UA_ACCESSCONTROL_DEFAULT_H_ */
|
||||
|
@ -21,6 +21,8 @@ typedef struct {
|
||||
UA_Boolean allowAnonymous;
|
||||
size_t usernamePasswordLoginSize;
|
||||
UA_UsernamePasswordLogin *usernamePasswordLogin;
|
||||
UA_UsernamePasswordLoginCallback loginCallback;
|
||||
void *loginContext;
|
||||
UA_CertificateVerification verifyX509;
|
||||
} AccessControlContext;
|
||||
|
||||
@ -95,11 +97,18 @@ activateSession_default(UA_Server *server, UA_AccessControl *ac,
|
||||
|
||||
/* Try to match username/pw */
|
||||
UA_Boolean match = false;
|
||||
for(size_t i = 0; i < context->usernamePasswordLoginSize; i++) {
|
||||
if(UA_String_equal(&userToken->userName, &context->usernamePasswordLogin[i].username) &&
|
||||
UA_String_equal(&userToken->password, &context->usernamePasswordLogin[i].password)) {
|
||||
if(context->loginCallback) {
|
||||
if(context->loginCallback(&userToken->userName, &userToken->password,
|
||||
context->usernamePasswordLoginSize, context->usernamePasswordLogin,
|
||||
sessionContext, context->loginContext) == UA_STATUSCODE_GOOD)
|
||||
match = true;
|
||||
break;
|
||||
} else {
|
||||
for(size_t i = 0; i < context->usernamePasswordLoginSize; i++) {
|
||||
if(UA_String_equal(&userToken->userName, &context->usernamePasswordLogin[i].username) &&
|
||||
UA_String_equal(&userToken->password, &context->usernamePasswordLogin[i].password)) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!match)
|
||||
@ -399,3 +408,24 @@ UA_AccessControl_default(UA_ServerConfig *config,
|
||||
return UA_STATUSCODE_GOOD;
|
||||
}
|
||||
|
||||
UA_StatusCode
|
||||
UA_AccessControl_defaultWithLoginCallback(UA_ServerConfig *config,
|
||||
UA_Boolean allowAnonymous, UA_CertificateVerification *verifyX509,
|
||||
const UA_ByteString *userTokenPolicyUri, size_t usernamePasswordLoginSize,
|
||||
const UA_UsernamePasswordLogin *usernamePasswordLogin,
|
||||
UA_UsernamePasswordLoginCallback loginCallback, void *loginContext)
|
||||
{
|
||||
AccessControlContext *context;
|
||||
UA_StatusCode sc;
|
||||
|
||||
sc = UA_AccessControl_default(config, allowAnonymous, verifyX509,
|
||||
userTokenPolicyUri, usernamePasswordLoginSize, usernamePasswordLogin);
|
||||
if (sc != UA_STATUSCODE_GOOD)
|
||||
return sc;
|
||||
|
||||
context = (AccessControlContext *)config->accessControl.context;
|
||||
context->loginCallback = loginCallback;
|
||||
context->loginContext = loginContext;
|
||||
|
||||
return UA_STATUSCODE_GOOD;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user