Skip to content

Commit

Permalink
User manager and permission ruleset fix (#352)
Browse files Browse the repository at this point in the history
* User-defined PermissionRuleset is now propagated to all InternalServers Endpoinds (also with the one with SecurityPolicy#None)

* Fixed check_user_token method of InternalServer and activate_session of InternalSession to provide an encrypted password to the user-defined UserManager

* Fixed bug in InternalServer when password is not provided

Co-authored-by: Marco Panato <marco.panato_01@univr.it>
  • Loading branch information
Marco9412 and Marco Panato committed Dec 7, 2020
1 parent 6a913f8 commit ac4373e
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 9 deletions.
17 changes: 14 additions & 3 deletions asyncua/server/internal_server.py
Expand Up @@ -300,9 +300,17 @@ def check_user_token(self, isession, token):
user_name = token.UserName
password = token.Password

# TODO Support all Token Types
# AnonimousIdentityToken
# UserIdentityToken
# UserNameIdentityToken
# X509IdentityToken
# IssuedIdentityToken

# decrypt password if we can
if str(token.EncryptionAlgorithm) != "None":
if not uacrypto:
# raise # Should I raise a significant exception?
return False
try:
if token.EncryptionAlgorithm == "http://www.w3.org/2001/04/xmlenc#rsa-1_5":
Expand All @@ -311,12 +319,15 @@ def check_user_token(self, isession, token):
raw_pw = uacrypto.decrypt_rsa_oaep(self.private_key, password)
else:
self.logger.warning("Unknown password encoding %s", token.EncryptionAlgorithm)
return False
# raise # Should I raise a significant exception?
return user_name, password
length = unpack_from('<I', raw_pw)[0] - len(isession.nonce)
password = raw_pw[4:4 + length]
password = password.decode('utf-8')
except Exception:
self.logger.exception("Unable to decrypt password")
return False
# call user_manager
return self.user_manager(self, isession, user_name, password)
elif type(password) == bytes: # TODO check
password = password.decode('utf-8')

return user_name, password
3 changes: 1 addition & 2 deletions asyncua/server/internal_session.py
Expand Up @@ -89,8 +89,7 @@ def activate_session(self, params, peer_certificate):
id_token = params.UserIdentityToken
if self.iserver.user_manager is not None:
if isinstance(id_token, ua.UserNameIdentityToken):
username = id_token.UserName
password = id_token.Password
username, password = self.iserver.check_user_token(self, id_token)
else:
username, password = None, None

Expand Down
2 changes: 1 addition & 1 deletion asyncua/server/server.py
Expand Up @@ -295,7 +295,7 @@ async def _setup_server_nodes(self):
# to be called just before starting server since it needs all parameters to be setup
if ua.SecurityPolicyType.NoSecurity in self._security_policy:
self._set_endpoints()
self._policies = [ua.SecurityPolicyFactory()]
self._policies = [ua.SecurityPolicyFactory(permission_ruleset=self._permission_ruleset)]

if self._security_policy != [ua.SecurityPolicyType.NoSecurity]:
if not (self.certificate and self.iserver.private_key):
Expand Down
6 changes: 3 additions & 3 deletions asyncua/ua/uaprotocol_hand.py
Expand Up @@ -234,14 +234,14 @@ class SecurityPolicy:
signature_key_size = 0
symmetric_key_size = 0

def __init__(self):
def __init__(self, permissions=None):
self.asymmetric_cryptography = CryptographyNone()
self.symmetric_cryptography = CryptographyNone()
self.Mode = auto.MessageSecurityMode.None_
self.peer_certificate = None
self.host_certificate = None
self.user = None
self.permissions = None
self.permissions = permissions

def make_local_symmetric_key(self, secret, seed):
pass
Expand All @@ -268,7 +268,7 @@ def matches(self, uri, mode=None):

def create(self, peer_certificate):
if self.cls is SecurityPolicy:
return self.cls()
return self.cls(permissions=self.permission_ruleset)
else:
return self.cls(peer_certificate, self.certificate, self.private_key, self.mode, permission_ruleset=self.permission_ruleset)

Expand Down

0 comments on commit ac4373e

Please sign in to comment.