44"""
55from datetime import datetime , timedelta
66from copy import copy
7- from struct import unpack_from , unpack
87import os
98import logging
109from threading import Lock
2827from opcua .server .address_space import MethodService
2928from opcua .server .subscription_service import SubscriptionService
3029from opcua .server .standard_address_space import standard_address_space
31- from opcua .server .users import User
30+ from opcua .server .user_manager import UserManager
3231#from opcua.common import xmlimporter
3332
34- use_crypto = True
35- try :
36- from opcua .crypto import uacrypto
37- except ImportError :
38- logging .getLogger (__name__ ).warning ("cryptography is not installed, use of crypto disabled" )
39- use_crypto = False
40-
4133
4234class SessionState (Enum ):
4335 Created = 0
@@ -53,19 +45,17 @@ def __init__(self, serv, cap=None):
5345
5446class InternalServer (object ):
5547
56- def __init__ (self , shelffile = None ):
48+ def __init__ (self , shelffile = None , parent = None ):
5749 self .logger = logging .getLogger (__name__ )
5850
51+ self ._parent = parent
5952 self .server_callback_dispatcher = CallbackDispatcher ()
6053
6154 self .endpoints = []
6255 self ._channel_id_counter = 5
63- self .allow_remote_admin = True
6456 self .disabled_clock = False # for debugging we may want to disable clock that writes too much in log
6557 self ._known_servers = {} # used if we are a discovery server
6658
67- self .private_key = None
68-
6959 self .aspace = AddressSpace ()
7060 self .attribute_service = AttributeService (self .aspace )
7161 self .view_service = ViewService (self .aspace )
@@ -80,15 +70,18 @@ def __init__(self, shelffile=None):
8070
8171 self .history_manager = HistoryManager (self )
8272
83- self .user_manager = default_user_manager # defined at the end of this file
84-
8573 # create a session to use on server side
86- self .isession = InternalSession (self , self .aspace , self .subscription_service , "Internal" , user = User .Admin )
74+ self .isession = InternalSession (self , self .aspace , \
75+ self .subscription_service , "Internal" , user = UserManager .User .Admin )
8776
8877 self .current_time_node = Node (self .isession , ua .NodeId (ua .ObjectIds .Server_ServerStatus_CurrentTime ))
8978 self ._address_space_fixes ()
9079 self .setup_nodes ()
9180
81+ @property
82+ def userManager (self ):
83+ return self ._parent .userManager
84+
9285 def setup_nodes (self ):
9386 """
9487 Set up some nodes as defined by spec
@@ -219,7 +212,7 @@ def register_server(self, server, conf=None):
219212 def register_server2 (self , params ):
220213 return self .register_server (params .Server , params .DiscoveryConfiguration )
221214
222- def create_session (self , name , user = User .Anonymous , external = False ):
215+ def create_session (self , name , user = UserManager . User .Anonymous , external = False ):
223216 return InternalSession (self , self .aspace , self .subscription_service , name , user = user , external = external )
224217
225218 def enable_history_data_change (self , node , period = timedelta (days = 7 ), count = 0 ):
@@ -280,48 +273,12 @@ def set_attribute_value(self, nodeid, datavalue, attr=ua.AttributeIds.Value):
280273 """
281274 self .aspace .set_attribute_value (nodeid , ua .AttributeIds .Value , datavalue )
282275
283- def set_user_manager (self , user_manager ):
284- """
285- set up a function which that will check for authorize users. Input function takes username
286- and password as paramters and returns True of user is allowed access, False otherwise.
287- """
288- self .user_manager = user_manager
289-
290- def check_user_token (self , isession , token ):
291- """
292- unpack the username and password for the benefit of the user defined user manager
293- """
294- userName = token .UserName
295- passwd = token .Password
296-
297- # decrypt password is we can
298- if str (token .EncryptionAlgorithm ) != "None" :
299- if use_crypto == False :
300- return False ;
301- try :
302- if token .EncryptionAlgorithm == "http://www.w3.org/2001/04/xmlenc#rsa-1_5" :
303- raw_pw = uacrypto .decrypt_rsa15 (self .private_key , passwd )
304- elif token .EncryptionAlgorithm == "http://www.w3.org/2001/04/xmlenc#rsa-oaep" :
305- raw_pw = uacrypto .decrypt_rsa_oaep (self .private_key , passwd )
306- else :
307- self .logger .warning ("Unknown password encoding '{0}'" .format (token .EncryptionAlgorithm ))
308- return False
309- length = unpack_from ('<I' , raw_pw )[0 ] - len (isession .nonce )
310- passwd = raw_pw [4 :4 + length ]
311- passwd = passwd .decode ('utf-8' )
312- except Exception as exp :
313- self .logger .warning ("Unable to decrypt password" )
314- return False
315-
316- # call user_manager
317- return self .user_manager (self , isession , userName , passwd )
318-
319276
320277class InternalSession (object ):
321278 _counter = 10
322279 _auth_counter = 1000
323280
324- def __init__ (self , internal_server , aspace , submgr , name , user = User .Anonymous , external = False ):
281+ def __init__ (self , internal_server , aspace , submgr , name , user = UserManager . User .Anonymous , external = False ):
325282 self .logger = logging .getLogger (__name__ )
326283 self .iserver = internal_server
327284 self .external = external # define if session is external, we need to copy some objects if it is internal
@@ -339,6 +296,10 @@ def __init__(self, internal_server, aspace, submgr, name, user=User.Anonymous, e
339296 self .logger .info ("Created internal session %s" , self .name )
340297 self ._lock = Lock ()
341298
299+ @property
300+ def userManager (self ):
301+ return self .iserver .userManager
302+
342303 def __str__ (self ):
343304 return "InternalSession(name:{0}, user:{1}, id:{2}, auth_token:{3})" .format (
344305 self .name , self .user , self .session_id , self .authentication_token )
@@ -377,7 +338,7 @@ def activate_session(self, params):
377338 self .state = SessionState .Activated
378339 id_token = params .UserIdentityToken
379340 if isinstance (id_token , ua .UserNameIdentityToken ):
380- if self .iserver .check_user_token (self , id_token ) == False :
341+ if self .userManager .check_user_token (self , id_token ) == False :
381342 raise utils .ServiceError (ua .StatusCodes .BadUserAccessDenied )
382343 self .logger .info ("Activated internal session %s for user %s" , self .name , self .user )
383344 return result
@@ -457,12 +418,3 @@ def publish(self, acks=None):
457418 if acks is None :
458419 acks = []
459420 return self .subscription_service .publish (acks )
460-
461-
462- def default_user_manager (iserver , isession , userName , password ):
463- """
464- Default user_manager, does nothing much but check for admin
465- """
466- if iserver .allow_remote_admin and userName in ("admin" , "Admin" ):
467- isession .user = User .Admin
468- return True
0 commit comments