forked from shaba/openuds
Advancing on actor
This commit is contained in:
parent
cf6a03b585
commit
6f3f573f61
@ -1,3 +1,4 @@
|
||||
Linux:
|
||||
python3-prctl (recommended, but not required in fact)
|
||||
python3-pyqt5
|
||||
|
||||
|
75
actor/src/udsactor/linux/__main__.py
Normal file
75
actor/src/udsactor/linux/__main__.py
Normal file
@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
import sys
|
||||
|
||||
from ..log import logger
|
||||
from .service import UDSActorSvc
|
||||
|
||||
def usage():
|
||||
sys.stderr.write('usage: udsactor start|stop|restart|login "username"|logout "username"\n')
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
logger.setLevel(20000)
|
||||
|
||||
if len(sys.argv) == 3 and sys.argv[1] in ('login', 'logout'):
|
||||
logger.debug('Running client udsactor')
|
||||
# client = None
|
||||
# try:
|
||||
# client = ipc.ClientIPC(IPC_PORT)
|
||||
# if 'login' == sys.argv[1]:
|
||||
# client.sendLogin(sys.argv[2])
|
||||
# sys.exit(0)
|
||||
# elif 'logout' == sys.argv[1]:
|
||||
# client.sendLogout(sys.argv[2])
|
||||
# sys.exit(0)
|
||||
# else:
|
||||
# usage()
|
||||
# except Exception as e:
|
||||
# logger.error(e)
|
||||
sys.exit(0)
|
||||
elif len(sys.argv) != 2:
|
||||
usage()
|
||||
|
||||
daemonSvr = UDSActorSvc()
|
||||
if len(sys.argv) == 2:
|
||||
if sys.argv[1] == 'start':
|
||||
daemonSvr.start()
|
||||
elif sys.argv[1] == 'stop':
|
||||
daemonSvr.stop()
|
||||
elif sys.argv[1] == 'restart':
|
||||
daemonSvr.restart()
|
||||
else:
|
||||
usage()
|
||||
sys.exit(0)
|
||||
else:
|
||||
usage()
|
@ -34,8 +34,6 @@ import platform
|
||||
import socket
|
||||
import fcntl
|
||||
import os
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
import subprocess
|
||||
import struct
|
||||
import array
|
||||
@ -44,6 +42,7 @@ import typing
|
||||
from .. import types
|
||||
|
||||
from .renamer import rename
|
||||
from . import xss
|
||||
|
||||
|
||||
def _getMacAddr(ifname: str) -> typing.Optional[str]:
|
||||
@ -106,7 +105,6 @@ def _getIpAndMac(ifname: str) -> typing.Tuple[typing.Optional[str], typing.Optio
|
||||
ip, mac = _getIpAddr(ifname), _getMacAddr(ifname)
|
||||
return (ip, mac)
|
||||
|
||||
|
||||
def checkPermissions() -> bool:
|
||||
return os.getuid() == 0
|
||||
|
||||
@ -166,33 +164,6 @@ def changeUserPassword(user: str, oldPassword: str, newPassword: str) -> None:
|
||||
os.system('echo "{1}\n{1}" | /usr/bin/passwd {0} 2> /dev/null'.format(user, newPassword))
|
||||
|
||||
|
||||
class XScreenSaverInfo(ctypes.Structure): # pylint: disable=too-few-public-methods
|
||||
_fields_ = [('window', ctypes.c_long),
|
||||
('state', ctypes.c_int),
|
||||
('kind', ctypes.c_int),
|
||||
('til_or_since', ctypes.c_ulong),
|
||||
('idle', ctypes.c_ulong),
|
||||
('eventMask', ctypes.c_ulong)]
|
||||
|
||||
# Initialize xlib & xss
|
||||
try:
|
||||
xlibPath = ctypes.util.find_library('X11')
|
||||
xssPath = ctypes.util.find_library('Xss')
|
||||
xlib = xss = None
|
||||
if not xlibPath or not xssPath:
|
||||
raise Exception()
|
||||
xlib = ctypes.cdll.LoadLibrary(xlibPath)
|
||||
xss = ctypes.cdll.LoadLibrary(xssPath)
|
||||
|
||||
# Fix result type to XScreenSaverInfo Structure
|
||||
xss.XScreenSaverQueryExtension.restype = ctypes.c_int
|
||||
xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo) # Result in a XScreenSaverInfo structure
|
||||
display = xlib.XOpenDisplay(None)
|
||||
xssInfo = xss.XScreenSaverAllocInfo()
|
||||
except Exception: # Libraries not accesible, not found or whatever..
|
||||
xlib = xss = display = xssInfo = None
|
||||
|
||||
|
||||
def initIdleDuration(atLeastSeconds: int) -> None:
|
||||
subprocess.call(['/usr/bin/xset', 's', '{}'.format(atLeastSeconds + 30)])
|
||||
# And now reset it
|
||||
@ -200,28 +171,7 @@ def initIdleDuration(atLeastSeconds: int) -> None:
|
||||
|
||||
|
||||
def getIdleDuration() -> float:
|
||||
'''
|
||||
Returns idle duration, in seconds
|
||||
'''
|
||||
if xlib is None or xss is None:
|
||||
return 0 # Libraries not available
|
||||
|
||||
event_base = ctypes.c_int()
|
||||
error_base = ctypes.c_int()
|
||||
|
||||
available = xss.XScreenSaverQueryExtension(display, ctypes.byref(event_base), ctypes.byref(error_base))
|
||||
|
||||
if available != 1:
|
||||
return 0 # No screen saver is available, no way of getting idle
|
||||
|
||||
xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), xssInfo)
|
||||
|
||||
# Centos seems to set state to 1?? (weird, but it's happening don't know why... will try this way)
|
||||
if xssInfo.contents.state != 0 and 'centos' not in getLinuxOs().lower().strip():
|
||||
return 3600 * 100 * 1000 # If screen saver is active, return a high enough value
|
||||
|
||||
return xssInfo.contents.idle / 1000.0
|
||||
|
||||
return xss.getIdleDuration()
|
||||
|
||||
def getCurrentUser() -> str:
|
||||
'''
|
||||
|
@ -30,3 +30,6 @@
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from .common import rename
|
||||
|
||||
# Import packages
|
||||
from . import debian, opensuse, redhat
|
||||
|
@ -49,11 +49,3 @@ def rename(newName: str) -> bool:
|
||||
logger.info('Renamer for platform "{0}" not found, tryin debian renamer'.format(distribution))
|
||||
return renamers['debian'](newName)
|
||||
|
||||
|
||||
# Do load of packages
|
||||
def _init():
|
||||
pkgpath = os.path.dirname(sys.modules[__name__].__file__)
|
||||
for _, name, _ in pkgutil.iter_modules([pkgpath]):
|
||||
__import__(__name__ + '.' + name, globals(), locals())
|
||||
|
||||
_init()
|
@ -29,7 +29,6 @@
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
import sys
|
||||
import signal
|
||||
import typing
|
||||
|
||||
@ -57,10 +56,9 @@ class UDSActorSvc(daemon.Daemon, CommonService):
|
||||
signal.signal(signal.SIGTERM, self.markForExit)
|
||||
|
||||
|
||||
def markForExit(self, signum, frame):
|
||||
def markForExit(self, signum, frame) -> None:
|
||||
self._isAlive = False
|
||||
|
||||
|
||||
def rename( # pylint: disable=unused-argument
|
||||
self,
|
||||
name: str,
|
||||
@ -78,6 +76,8 @@ class UDSActorSvc(daemon.Daemon, CommonService):
|
||||
logger.info('Computer name is already {}'.format(hostName))
|
||||
return
|
||||
|
||||
logger.debug('Data: {}'.format((name, userName, oldPassword, newPassword)))
|
||||
|
||||
# Check for password change request for an user
|
||||
if userName and oldPassword and newPassword:
|
||||
logger.info('Setting password for user {}'.format(userName))
|
||||
@ -100,14 +100,15 @@ class UDSActorSvc(daemon.Daemon, CommonService):
|
||||
) -> None:
|
||||
logger.fatal('Join domain is not supported on linux platforms right now')
|
||||
|
||||
def run(self):
|
||||
logger.debug('Running Daemon')
|
||||
def run(self) -> None:
|
||||
logger.debug('Running Daemon: {}'.format(self._isAlive))
|
||||
set_proctitle('UDSActorDaemon')
|
||||
|
||||
# Linux daemon will continue running unless something is requested to
|
||||
if not self.initialize():
|
||||
return # Stop daemon if initializes told to do so
|
||||
|
||||
logger.debug('Initialized, setting ready')
|
||||
# Initialization is done, set machine to ready for UDS, communicate urls, etc...
|
||||
self.setReady()
|
||||
|
||||
@ -117,7 +118,7 @@ class UDSActorSvc(daemon.Daemon, CommonService):
|
||||
# Counter used to check ip changes only once every 10 seconds, for
|
||||
# example
|
||||
counter = 0
|
||||
while self.isAlive:
|
||||
while self._isAlive:
|
||||
counter += 1
|
||||
if counter % 10 == 0:
|
||||
self.checkIpsChanged()
|
||||
@ -125,45 +126,3 @@ class UDSActorSvc(daemon.Daemon, CommonService):
|
||||
self.doWait(1000)
|
||||
|
||||
self.notifyStop()
|
||||
|
||||
|
||||
def usage():
|
||||
sys.stderr.write("usage: {} start|stop|restart|login 'username'|logout 'username'\n".format(sys.argv[0]))
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logger.setLevel(20000)
|
||||
|
||||
if len(sys.argv) == 3 and sys.argv[1] in ('login', 'logout'):
|
||||
logger.debug('Running client udsactor')
|
||||
# client = None
|
||||
# try:
|
||||
# client = ipc.ClientIPC(IPC_PORT)
|
||||
# if 'login' == sys.argv[1]:
|
||||
# client.sendLogin(sys.argv[2])
|
||||
# sys.exit(0)
|
||||
# elif 'logout' == sys.argv[1]:
|
||||
# client.sendLogout(sys.argv[2])
|
||||
# sys.exit(0)
|
||||
# else:
|
||||
# usage()
|
||||
# except Exception as e:
|
||||
# logger.error(e)
|
||||
elif len(sys.argv) != 2:
|
||||
usage()
|
||||
|
||||
logger.debug('Executing actor')
|
||||
daemonSvr = UDSActorSvc()
|
||||
if len(sys.argv) == 2:
|
||||
if sys.argv[1] == 'start':
|
||||
daemonSvr.start()
|
||||
elif sys.argv[1] == 'stop':
|
||||
daemonSvr.stop()
|
||||
elif sys.argv[1] == 'restart':
|
||||
daemonSvr.restart()
|
||||
else:
|
||||
usage()
|
||||
sys.exit(0)
|
||||
else:
|
||||
usage()
|
105
actor/src/udsactor/linux/xss.py
Normal file
105
actor/src/udsactor/linux/xss.py
Normal file
@ -0,0 +1,105 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
# pylint: disable=invalid-name
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
import subprocess
|
||||
|
||||
xlib = None
|
||||
xss = None
|
||||
display = None
|
||||
xssInfo = None
|
||||
initialized = False
|
||||
|
||||
class XScreenSaverInfo(ctypes.Structure): # pylint: disable=too-few-public-methods
|
||||
_fields_ = [('window', ctypes.c_long),
|
||||
('state', ctypes.c_int),
|
||||
('kind', ctypes.c_int),
|
||||
('til_or_since', ctypes.c_ulong),
|
||||
('idle', ctypes.c_ulong),
|
||||
('eventMask', ctypes.c_ulong)]
|
||||
|
||||
def _init():
|
||||
global xlib, xss, xssInfo, display, initialized # pylint: disable=global-statement
|
||||
initialized = True
|
||||
|
||||
# Initialize xlib & xss
|
||||
try:
|
||||
xlibPath = ctypes.util.find_library('X11')
|
||||
xssPath = ctypes.util.find_library('Xss')
|
||||
xlib = xss = None
|
||||
if not xlibPath or not xssPath:
|
||||
raise Exception()
|
||||
xlib = ctypes.cdll.LoadLibrary(xlibPath)
|
||||
xss = ctypes.cdll.LoadLibrary(xssPath)
|
||||
|
||||
# Fix result type to XScreenSaverInfo Structure
|
||||
xss.XScreenSaverQueryExtension.restype = ctypes.c_int
|
||||
xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo) # Result in a XScreenSaverInfo structure
|
||||
display = xlib.XOpenDisplay(None)
|
||||
xssInfo = xss.XScreenSaverAllocInfo()
|
||||
if display <= 0:
|
||||
raise Exception() # Invalid display, not accesible
|
||||
except Exception: # Libraries not accesible, not found or whatever..
|
||||
xlib = xss = display = xssInfo = None
|
||||
|
||||
|
||||
def initIdleDuration(atLeastSeconds: int) -> None:
|
||||
subprocess.call(['/usr/bin/xset', 's', '{}'.format(atLeastSeconds + 30)])
|
||||
# And now reset it
|
||||
subprocess.call(['/usr/bin/xset', 's', 'reset'])
|
||||
|
||||
|
||||
def getIdleDuration() -> float:
|
||||
'''
|
||||
Returns idle duration, in seconds
|
||||
'''
|
||||
if not initialized:
|
||||
_init()
|
||||
|
||||
if not xlib or not xss or not xssInfo:
|
||||
return 0 # Libraries not available
|
||||
|
||||
event_base = ctypes.c_int()
|
||||
error_base = ctypes.c_int()
|
||||
|
||||
available = xss.XScreenSaverQueryExtension(display, ctypes.byref(event_base), ctypes.byref(error_base))
|
||||
|
||||
if available != 1:
|
||||
return 0 # No screen saver is available, no way of getting idle
|
||||
|
||||
xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), xssInfo)
|
||||
|
||||
# Centos seems to set state to 1?? (weird, but it's happening don't know why... will try this way)
|
||||
if xssInfo.contents.state == 1: # state = 1 means "active", so idle is not a valid state
|
||||
return 3600 * 100 * 1000 # If screen saver is active, return a high enough value
|
||||
|
||||
return xssInfo.contents.idle / 1000.0
|
@ -69,7 +69,7 @@ class CommonService:
|
||||
@staticmethod
|
||||
def execute(cmdLine: str, section: str) -> bool:
|
||||
try:
|
||||
res = subprocess.check_call(cmdLine)
|
||||
res = subprocess.check_call(cmdLine, shell=True)
|
||||
except Exception as e:
|
||||
logger.error('Got exception executing: {} - {} - {}'.format(section, cmdLine, e))
|
||||
return False
|
||||
|
37
actor/src/udsactor/windows/__main__.py
Normal file
37
actor/src/udsactor/windows/__main__.py
Normal file
@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
# pylint: disable=invalid-name
|
||||
import win32serviceutil
|
||||
|
||||
from .service import UDSActorSvc
|
||||
|
||||
if __name__ == '__main__':
|
||||
win32serviceutil.HandleCommandLine(UDSActorSvc)
|
@ -364,8 +364,3 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
||||
self.endAPI() # And deinitializes REST api if needed
|
||||
|
||||
self.notifyStop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
initCfg()
|
||||
win32serviceutil.HandleCommandLine(UDSActorSvc)
|
Loading…
Reference in New Issue
Block a user