Started Linux Actors part

This commit is contained in:
Adolfo Gómez García 2014-11-10 06:29:18 +01:00
parent 12c93732da
commit 1f519308a1
12 changed files with 117 additions and 41 deletions

2
actors/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
bin
*_enterprise*

View File

@ -1,5 +1,3 @@
build build
dist
bin
.idea .idea
*_enterprise* *_enterprise*

View File

@ -52,7 +52,7 @@ class MyForm(QtGui.QDialog):
self.ui.host.setText(data.get('host', '')) self.ui.host.setText(data.get('host', ''))
self.ui.masterKey.setText(data.get('masterKey', '')) self.ui.masterKey.setText(data.get('masterKey', ''))
self.ui.useSSl.setCurrentIndex(1 if data.get('ssl', False) is True else 0) self.ui.useSSl.setCurrentIndex(1 if data.get('ssl', False) is True else 0)
self.ui.logLevelComboBox.setCurrentIndex(data.get('logLevel', 10000) / 10000 - 1) self.ui.logLevelComboBox.setCurrentIndex(int(data.get('logLevel', '10000')) / 10000 - 1)
def _getCfg(self): def _getCfg(self):
return { return {

View File

@ -30,13 +30,14 @@
@author: Adolfo Gómez, dkmaster at dkmon dot com @author: Adolfo Gómez, dkmaster at dkmon dot com
''' '''
from __future__ import unicode_literals from __future__ import unicode_literals
# pylint: disable=unused-wildcard-import, wildcard-import
import win32serviceutil import win32serviceutil # @UnresolvedImport, pylint: disable=import-error
import win32service import win32service # @UnresolvedImport, pylint: disable=import-error
import win32event import win32event # @UnresolvedImport, pylint: disable=import-error
import win32com.client import win32com.client # @UnresolvedImport, @UnusedImport, pylint: disable=import-error
import pythoncom import pythoncom # @UnresolvedImport, pylint: disable=import-error
import servicemanager import servicemanager # @UnresolvedImport, pylint: disable=import-error
import socket import socket
import random import random
@ -47,13 +48,14 @@ from udsactor import operations
from udsactor import httpserver from udsactor import httpserver
from udsactor import ipc from udsactor import ipc
from udsactor.windows.SENS import * from udsactor.windows.SENS import * # @UnusedWildImport
from udsactor.log import logger from udsactor.log import logger
IPC_PORT = 39188 IPC_PORT = 39188
cfg = None cfg = None
def initCfg(): def initCfg():
global cfg global cfg
cfg = store.readConfig() cfg = store.readConfig()
@ -281,7 +283,7 @@ class UDSActorSvc(win32serviceutil.ServiceFramework):
operations.reboot() operations.reboot()
except Exception as e: except Exception as e:
logger.error('Exception on reboot: {}'.format(e.message)) logger.error('Exception on reboot: {}'.format(e.message))
return False # Stops service return False # Stops service
return True return True
@ -381,7 +383,7 @@ class UDSActorSvc(win32serviceutil.ServiceFramework):
# Process SENS messages, This will be a bit asyncronous (1 second # Process SENS messages, This will be a bit asyncronous (1 second
# delay) # delay)
pythoncom.PumpWaitingMessages() pythoncom.PumpWaitingMessages()
#if counter % 10 == 0: # if counter % 10 == 0:
# self.checkIpsChanged() # self.checkIpsChanged()
# In milliseconds, will break # In milliseconds, will break
win32event.WaitForSingleObject(self.hWaitStop, 1000) win32event.WaitForSingleObject(self.hWaitStop, 1000)

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -46,7 +46,7 @@ from udsactor.log import logger
# Message_id Data Action # Message_id Data Action
# ------------ -------- -------------------------- # ------------ -------- --------------------------
# MSG_LOGOFF None Logout user from session # MSG_LOGOFF None Logout user from session
# MSG_MESSAGE message,level Display a message with level (INFO, WARN, ERROR, FATAL) # TODO: Include levle, right now only has message # MSG_MESSAGE message,level Display a message with level (INFO, WARN, ERROR, FATAL) # TODO: Include level, right now only has message
# MSG_SCRIPT python script Execute an specific python script INSIDE CLIENT environment (this messages is not sent right now) # MSG_SCRIPT python script Execute an specific python script INSIDE CLIENT environment (this messages is not sent right now)
# #
# All messages are in the form: # All messages are in the form:
@ -64,7 +64,8 @@ VALID_MESSAGES = (MSG_LOGOFF, MSG_MESSAGE, MSG_SCRIPT, MSG_INFORMATION)
REQ_INFORMATION = 0xAA REQ_INFORMATION = 0xAA
MAGIC = b'\x55\x44\x53\x00' # UDS in hexa with a padded 0 to the ridght MAGIC = b'\x55\x44\x53\x00' # UDS in hexa with a padded 0 to the right
class ClientProcessor(threading.Thread): class ClientProcessor(threading.Thread):
def __init__(self, parent, clientSocket): def __init__(self, parent, clientSocket):
@ -85,7 +86,7 @@ class ClientProcessor(threading.Thread):
while self.running: while self.running:
try: try:
while True: while True:
buf = self.clientSocket.recv(512) # Empty buffer, this is set as non-blocking buf = self.clientSocket.recv(512) # Empty buffer, this is set as non-blocking
if buf == b'': # No data if buf == b'': # No data
break break
for b in buf: for b in buf:
@ -110,7 +111,7 @@ class ClientProcessor(threading.Thread):
try: try:
m = msg[1] if msg[1] is not None else b'' m = msg[1] if msg[1] is not None else b''
l = len(m) l = len(m)
data = MAGIC + chr(msg[0]) + chr(l&0xFF) + chr(l>>8) + m data = MAGIC + chr(msg[0]) + chr(l & 0xFF) + chr(l >> 8) + m
try: try:
self.clientSocket.sendall(data) self.clientSocket.sendall(data)
except socket.error as e: except socket.error as e:
@ -236,13 +237,13 @@ class ClientIPC(threading.Thread):
Override this method to automatically get notified on new message Override this method to automatically get notified on new message
received. Message is at self.messages queue received. Message is at self.messages queue
''' '''
pass # Messa pass # Messa
def receiveBytes(self, number): def receiveBytes(self, number):
msg = b'' msg = b''
while self.running and len(msg) < number: while self.running and len(msg) < number:
try: try:
buf = self.clientSocket.recv(number-len(msg)) buf = self.clientSocket.recv(number - len(msg))
if buf == b'': if buf == b'':
self.running = False self.running = False
break break
@ -268,7 +269,7 @@ class ClientIPC(threading.Thread):
# We look for magic message header # We look for magic message header
while self.running: # Wait for MAGIC while self.running: # Wait for MAGIC
try: try:
buf = self.clientSocket.recv(len(MAGIC)-len(msg)) buf = self.clientSocket.recv(len(MAGIC) - len(msg))
if buf == b'': if buf == b'':
self.running = False self.running = False
break break
@ -279,7 +280,7 @@ class ClientIPC(threading.Thread):
msg = msg[1:] msg = msg[1:]
continue continue
break break
except socket.timeout: # Timeout is here so we can get stop thread except socket.timeout: # Timeout is here so we can get stop thread
continue continue
# Now we get message basic data (msg + datalen) # Now we get message basic data (msg + datalen)
@ -290,7 +291,7 @@ class ClientIPC(threading.Thread):
continue continue
msgId = ord(msg[0]) msgId = ord(msg[0])
dataLen = ord(msg[1]) + (ord(msg[2])<<8) dataLen = ord(msg[1]) + (ord(msg[2]) << 8)
if msgId not in VALID_MESSAGES: if msgId not in VALID_MESSAGES:
raise Exception('Invalid message id: {}'.format(msgId)) raise Exception('Invalid message id: {}'.format(msgId))

View File

@ -0,0 +1,68 @@
# -*- 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
'''
from __future__ import unicode_literals
import six
import os
DEBUG = True
CONFIGFILE = '/etc/udsactor/udsactor.cfg' if DEBUG is False else '/tmp/udsactor.cfg'
def checkPermissions():
return True if DEBUG else os.getuid() == 0
def readConfig():
res = {}
try:
cfg = six.moves.configparser.SafeConfigParser() # @UndefinedVariable
cfg.read(CONFIGFILE)
# Just reads 'uds' section
for key in cfg.options('uds'):
res[key] = cfg.get('uds', key)
except Exception:
pass
return res
def writeConfig(data):
cfg = six.moves.configparser.SafeConfigParser() # @UndefinedVariable
cfg.add_section('uds')
for key, val in data.iteritems():
cfg.set('uds', key, unicode(val))
with file(CONFIGFILE, 'w') as f:
cfg.write(f)
os.chmod(CONFIGFILE, 0600)

View File

@ -40,6 +40,7 @@ else:
# Valid logging levels, from UDS Broker (uds.core.utils.log) # Valid logging levels, from UDS Broker (uds.core.utils.log)
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in xrange(6)) OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in xrange(6))
class Logger(object): class Logger(object):
def __init__(self): def __init__(self):
self.logLevel = OTHER self.logLevel = OTHER

View File

@ -29,14 +29,11 @@
''' '''
@author: Adolfo Gómez, dkmaster at dkmon dot com @author: Adolfo Gómez, dkmaster at dkmon dot com
''' '''
# pylint: disable=unused-wildcard-import,wildcard-import # pylint: disable=unused-wildcard-import, wildcard-import
from __future__ import unicode_literals from __future__ import unicode_literals
import sys import sys
if sys.platform == 'win32': if sys.platform == 'win32':
from udsactor.windows.store import * from udsactor.windows.store import * # @UnusedWildImport
else: else:
pass from udsactor.linux.store import * # @UnusedWildImport

View File

@ -31,7 +31,7 @@
''' '''
from __future__ import unicode_literals from __future__ import unicode_literals
import servicemanager import servicemanager # @UnresolvedImport, pylint: disable=import-error
import logging import logging
import os import os
import tempfile import tempfile
@ -39,6 +39,7 @@ import tempfile
# Valid logging levels, from UDS Broker (uds.core.utils.log) # Valid logging levels, from UDS Broker (uds.core.utils.log)
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in xrange(6)) OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in xrange(6))
class LocalLogger(object): class LocalLogger(object):
def __init__(self): def __init__(self):
# tempdir is different for "user application" and "service" # tempdir is different for "user application" and "service"
@ -57,14 +58,14 @@ class LocalLogger(object):
# our loglevels are 10000 (other), 20000 (debug), .... # our loglevels are 10000 (other), 20000 (debug), ....
# logging levels are 10 (debug), 20 (info) # logging levels are 10 (debug), 20 (info)
# OTHER = logging.NOTSET # OTHER = logging.NOTSET
self.logger.log(level/1000-10, message) self.logger.log(level / 1000 - 10, message)
if level < INFO or self.serviceLogger is False: # Only information and above will be on event log if level < INFO or self.serviceLogger is False: # Only information and above will be on event log
return return
if level < WARN: # Info if level < WARN: # Info
servicemanager.LogInfoMsg(message) servicemanager.LogInfoMsg(message)
elif level < ERROR: # WARN elif level < ERROR: # WARN
servicemanager.LogWarningMsg(message) servicemanager.LogWarningMsg(message)
else: # Error & Fatal else: # Error & Fatal
servicemanager.LogErrorMsg(message) servicemanager.LogErrorMsg(message)

View File

@ -31,26 +31,30 @@
''' '''
from __future__ import unicode_literals from __future__ import unicode_literals
from win32com.shell import shell from win32com.shell import shell # @UnresolvedImport, pylint: disable=import-error
import _winreg as wreg import _winreg as wreg # @UnresolvedImport, pylint: disable=import-error
import win32security import win32security # @UnresolvedImport, pylint: disable=import-error
import cPickle import cPickle
# Can be changed to whatever we want, but registry key is protected by permissions # Can be changed to whatever we want, but registry key is protected by permissions
def encoder(data): def encoder(data):
return data.encode('bz2') return data.encode('bz2')
def decoder(data): def decoder(data):
return data.decode('bz2') return data.decode('bz2')
DEBUG = False DEBUG = False
path = 'Software\\UDSActor' path = 'Software\\UDSActor'
baseKey = wreg.HKEY_CURRENT_USER if DEBUG is True else wreg.HKEY_LOCAL_MACHINE baseKey = wreg.HKEY_CURRENT_USER if DEBUG is True else wreg.HKEY_LOCAL_MACHINE # @UndefinedVariable
def checkPermissions(): def checkPermissions():
return True if DEBUG else shell.IsUserAnAdmin() return True if DEBUG else shell.IsUserAnAdmin()
def fixRegistryPermissions(handle): def fixRegistryPermissions(handle):
if DEBUG: if DEBUG:
return return
@ -68,21 +72,23 @@ def fixRegistryPermissions(handle):
win32security.DACL_SECURITY_INFORMATION | win32security.PROTECTED_DACL_SECURITY_INFORMATION, win32security.DACL_SECURITY_INFORMATION | win32security.PROTECTED_DACL_SECURITY_INFORMATION,
None, None, dacl, None) None, None, dacl, None)
def readConfig(): def readConfig():
try: try:
key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_QUERY_VALUE) key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_QUERY_VALUE) # @UndefinedVariable
data, _ = wreg.QueryValueEx(key, '') data, _ = wreg.QueryValueEx(key, '') # @UndefinedVariable
wreg.CloseKey(key) wreg.CloseKey(key) # @UndefinedVariable
return cPickle.loads(decoder(data)) return cPickle.loads(decoder(data))
except Exception: except Exception:
return None return None
def writeConfig(data): def writeConfig(data):
try: try:
key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_ALL_ACCESS) key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
except Exception: except Exception:
key = wreg.CreateKeyEx(baseKey, path, 0, wreg.KEY_ALL_ACCESS) key = wreg.CreateKeyEx(baseKey, path, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
fixRegistryPermissions(key.handle) fixRegistryPermissions(key.handle)
wreg.SetValueEx(key, "", 0, wreg.REG_BINARY, encoder(cPickle.dumps(data))) wreg.SetValueEx(key, "", 0, wreg.REG_BINARY, encoder(cPickle.dumps(data))) # @UndefinedVariable
wreg.CloseKey(key) wreg.CloseKey(key) # @UndefinedVariable