forked from shaba/openuds
Merge remote-tracking branch 'origin/v3.5' into v3.6
This commit is contained in:
commit
e79753748e
@ -198,7 +198,7 @@ class UDSActorClient(threading.Thread): # pylint: disable=too-many-instance-att
|
|||||||
time.sleep(1.3) # Sleeps between loop iterations
|
time.sleep(1.3) # Sleeps between loop iterations
|
||||||
|
|
||||||
self._loginInfo = None
|
self._loginInfo = None
|
||||||
self.api.logout(platform.operations.getCurrentUser() + self._extraLogoff)
|
self.api.logout(platform.operations.getCurrentUser() + self._extraLogoff, platform.operations.getSessionType())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error('Error on client loop: %s', e)
|
logger.error('Error on client loop: %s', e)
|
||||||
|
|
||||||
|
@ -351,19 +351,21 @@ class UDSServerApi(UDSApi):
|
|||||||
actor_type: typing.Optional[str],
|
actor_type: typing.Optional[str],
|
||||||
token: str,
|
token: str,
|
||||||
username: str,
|
username: str,
|
||||||
|
sessionType: str,
|
||||||
interfaces: typing.Iterable[types.InterfaceInfoType],
|
interfaces: typing.Iterable[types.InterfaceInfoType],
|
||||||
secret: typing.Optional[str],
|
secret: typing.Optional[str],
|
||||||
) -> None:
|
) -> typing.Optional[str]:
|
||||||
if not token:
|
if not token:
|
||||||
return
|
return None
|
||||||
payload = {
|
payload = {
|
||||||
'type': actor_type or types.MANAGED,
|
'type': actor_type or types.MANAGED,
|
||||||
'id': [{'mac': i.mac, 'ip': i.ip} for i in interfaces],
|
'id': [{'mac': i.mac, 'ip': i.ip} for i in interfaces],
|
||||||
'token': token,
|
'token': token,
|
||||||
'username': username,
|
'username': username,
|
||||||
|
'session_type': sessionType,
|
||||||
'secret': secret or '',
|
'secret': secret or '',
|
||||||
}
|
}
|
||||||
self._doPost('logout', payload)
|
return self._doPost('logout', payload) # Can be 'ok' or 'notified'
|
||||||
|
|
||||||
def log(self, own_token: str, level: int, message: str) -> None:
|
def log(self, own_token: str, level: int, message: str) -> None:
|
||||||
if not own_token:
|
if not own_token:
|
||||||
@ -418,8 +420,11 @@ class UDSClientApi(UDSApi):
|
|||||||
max_idle=result['max_idle'],
|
max_idle=result['max_idle'],
|
||||||
)
|
)
|
||||||
|
|
||||||
def logout(self, username: str) -> None:
|
def logout(self, username: str, sessionType: typing.Optional[str]) -> None:
|
||||||
payLoad = {'username': username}
|
payLoad = {
|
||||||
|
'username': username,
|
||||||
|
'session_type': sessionType or UNKNOWN
|
||||||
|
}
|
||||||
self.post('logout', payLoad)
|
self.post('logout', payLoad)
|
||||||
|
|
||||||
def ping(self) -> bool:
|
def ping(self) -> bool:
|
||||||
|
@ -377,6 +377,7 @@ class CommonService: # pylint: disable=too-many-instance-attributes
|
|||||||
self._cfg.actorType,
|
self._cfg.actorType,
|
||||||
self._cfg.own_token,
|
self._cfg.own_token,
|
||||||
'',
|
'',
|
||||||
|
'',
|
||||||
self._interfaces,
|
self._interfaces,
|
||||||
self._secret,
|
self._secret,
|
||||||
)
|
)
|
||||||
@ -494,7 +495,10 @@ class CommonService: # pylint: disable=too-many-instance-attributes
|
|||||||
# If unmanaged, do initialization now, because we don't know before this
|
# If unmanaged, do initialization now, because we don't know before this
|
||||||
# Also, even if not initialized, get a "login" notification token
|
# Also, even if not initialized, get a "login" notification token
|
||||||
if not self.isManaged():
|
if not self.isManaged():
|
||||||
|
self._initialized = (
|
||||||
self.initialize()
|
self.initialize()
|
||||||
|
) # Maybe it's a local login by an unmanaged host.... On real login, will execute initilize again
|
||||||
|
if self._initialized:
|
||||||
master_token = self._cfg.master_token
|
master_token = self._cfg.master_token
|
||||||
secret = self._secret
|
secret = self._secret
|
||||||
|
|
||||||
@ -518,7 +522,7 @@ class CommonService: # pylint: disable=too-many-instance-attributes
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def logout(self, username: str) -> None:
|
def logout(self, username: str, sessionType: typing.Optional[str] = None) -> None:
|
||||||
self._loggedIn = False
|
self._loggedIn = False
|
||||||
|
|
||||||
master_token = self._cfg.master_token
|
master_token = self._cfg.master_token
|
||||||
@ -527,9 +531,20 @@ class CommonService: # pylint: disable=too-many-instance-attributes
|
|||||||
# In that case, take master token (if machine is Unamanaged version)
|
# In that case, take master token (if machine is Unamanaged version)
|
||||||
token = self._cfg.own_token or master_token
|
token = self._cfg.own_token or master_token
|
||||||
if token:
|
if token:
|
||||||
|
# If logout is not processed (that is, not ok result), the logout has not been processed
|
||||||
|
if (
|
||||||
self._api.logout(
|
self._api.logout(
|
||||||
self._cfg.actorType, token, username, self._interfaces, self._secret
|
self._cfg.actorType,
|
||||||
|
token,
|
||||||
|
username,
|
||||||
|
sessionType or '',
|
||||||
|
self._interfaces,
|
||||||
|
self._secret,
|
||||||
)
|
)
|
||||||
|
!= 'ok'
|
||||||
|
):
|
||||||
|
logger.info('Logout from %s ignored as required by uds broker', username)
|
||||||
|
return
|
||||||
|
|
||||||
self.onLogout(username)
|
self.onLogout(username)
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ class Version(ActorV3Action):
|
|||||||
class LoginLogout(ActorV3Action):
|
class LoginLogout(ActorV3Action):
|
||||||
name = 'notused' # Not really important, this is not a "leaf" class and will not be directly available
|
name = 'notused' # Not really important, this is not a "leaf" class and will not be directly available
|
||||||
|
|
||||||
def notifyService(self, isLogin: bool):
|
def notifyService(self, isLogin: bool) -> None:
|
||||||
try:
|
try:
|
||||||
# If unmanaged, use Service locator
|
# If unmanaged, use Service locator
|
||||||
service: 'services.Service' = Service.objects.get(
|
service: 'services.Service' = Service.objects.get(
|
||||||
@ -446,12 +446,12 @@ class LoginLogout(ActorV3Action):
|
|||||||
# idInfo = service.recoverIdInfo(validId)
|
# idInfo = service.recoverIdInfo(validId)
|
||||||
|
|
||||||
# Notify Service that someone logged in/out
|
# Notify Service that someone logged in/out
|
||||||
|
is_remote = self._params.get('session_type', '')[:4] in ('xrdp', 'RDP-')
|
||||||
if isLogin:
|
if isLogin:
|
||||||
# Try to guess if this is a remote session
|
# Try to guess if this is a remote session
|
||||||
is_remote = self._params.get('session_type', '')[:4] in ('xrdp', 'RDP-')
|
|
||||||
service.processLogin(validId, remote_login=is_remote)
|
service.processLogin(validId, remote_login=is_remote)
|
||||||
else:
|
else:
|
||||||
service.processLogout(validId)
|
service.processLogout(validId, remote_login=is_remote)
|
||||||
|
|
||||||
# All right, service notified...
|
# All right, service notified...
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -562,6 +562,7 @@ class Logout(LoginLogout):
|
|||||||
if isManaged:
|
if isManaged:
|
||||||
raise
|
raise
|
||||||
self.notifyService(isLogin=False) # Logout notification
|
self.notifyService(isLogin=False) # Logout notification
|
||||||
|
return ActorV3Action.actorResult('notified') # Result is that we have not processed the logout in fact, but notified the service
|
||||||
|
|
||||||
return ActorV3Action.actorResult('ok')
|
return ActorV3Action.actorResult('ok')
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ class Service(Module):
|
|||||||
"""
|
"""
|
||||||
return
|
return
|
||||||
|
|
||||||
def processLogout(self, id: str) -> None:
|
def processLogout(self, id: str, remote_login: bool) -> None:
|
||||||
"""
|
"""
|
||||||
In the case that a logout is invoked directly on an actor controlled machine with
|
In the case that a logout is invoked directly on an actor controlled machine with
|
||||||
an service token, this method will be called with provided info by uds actor (parameters)
|
an service token, this method will be called with provided info by uds actor (parameters)
|
||||||
|
@ -231,10 +231,13 @@ class IPMachinesService(IPServiceBase):
|
|||||||
# Sets maximum services for this
|
# Sets maximum services for this
|
||||||
self.maxDeployed = len(self._ips)
|
self.maxDeployed = len(self._ips)
|
||||||
|
|
||||||
def canBeUsed(self, locked: typing.Optional[int], now: int) -> int:
|
def canBeUsed(self, locked: typing.Optional[typing.Union[str, int]], now: int) -> int:
|
||||||
# If _maxSessionForMachine is 0, it can be used only if not locked
|
# If _maxSessionForMachine is 0, it can be used only if not locked
|
||||||
# (that is locked is None)
|
# (that is locked is None)
|
||||||
locked = locked or 0
|
locked = locked or 0
|
||||||
|
if isinstance(locked, str) and not '.' in locked: # Convert to int and treat it as a "locked" element
|
||||||
|
locked = int(locked)
|
||||||
|
|
||||||
if self._maxSessionForMachine <= 0:
|
if self._maxSessionForMachine <= 0:
|
||||||
return not bool(locked) # If locked is None, it can be used
|
return not bool(locked) # If locked is None, it can be used
|
||||||
|
|
||||||
@ -342,19 +345,26 @@ class IPMachinesService(IPServiceBase):
|
|||||||
Process login for a machine not assigned to any user.
|
Process login for a machine not assigned to any user.
|
||||||
'''
|
'''
|
||||||
logger.debug('Processing login for %s: %s', self, id)
|
logger.debug('Processing login for %s: %s', self, id)
|
||||||
|
|
||||||
# Locate the IP on the storage
|
# Locate the IP on the storage
|
||||||
theIP = IPServiceBase.getIp(id)
|
theIP = IPServiceBase.getIp(id)
|
||||||
now = getSqlDatetimeAsUnix()
|
now = getSqlDatetimeAsUnix()
|
||||||
locked = self.storage.getPickle(theIP)
|
locked: typing.Union[None, str, int] = self.storage.getPickle(theIP)
|
||||||
if self.canBeUsed(locked, now):
|
if self.canBeUsed(locked, now):
|
||||||
self.storage.putPickle(theIP, now) # Lock it
|
self.storage.putPickle(theIP, str(now)) # Lock it
|
||||||
|
|
||||||
def processLogout(self, id: str) -> None:
|
def processLogout(self, id: str, remote_login: bool) -> None:
|
||||||
'''
|
'''
|
||||||
Process logout for a machine not assigned to any user.
|
Process logout for a machine not assigned to any user.
|
||||||
'''
|
'''
|
||||||
logger.debug('Processing logout for %s: %s', self, id)
|
logger.debug('Processing logout for %s: %s', self, id)
|
||||||
|
# Locate the IP on the storage
|
||||||
|
theIP = IPServiceBase.getIp(id)
|
||||||
|
locked: typing.Union[None, str, int] = self.storage.getPickle(theIP)
|
||||||
|
# If locked is str, has been locked by processLogin so we can unlock it
|
||||||
|
if isinstance(locked, str):
|
||||||
self.unassignMachine(id)
|
self.unassignMachine(id)
|
||||||
|
# If not proccesed by login, we cannot release it
|
||||||
|
|
||||||
def notifyInitialization(self, id: str) -> None:
|
def notifyInitialization(self, id: str) -> None:
|
||||||
'''
|
'''
|
||||||
|
Loading…
x
Reference in New Issue
Block a user