forked from shaba/openuds
advancing on new actor
This commit is contained in:
parent
4df7c18ddc
commit
2cf869150f
@ -48,7 +48,6 @@ if typing.TYPE_CHECKING:
|
||||
|
||||
logger = logging.getLogger('actor')
|
||||
|
||||
|
||||
class UDSConfigDialog(QDialog):
|
||||
_host: str = ''
|
||||
|
||||
@ -103,7 +102,7 @@ class UDSConfigDialog(QDialog):
|
||||
data: udsactor.types.InterfaceInfo = next(udsactor.operations.getNetworkInfo())
|
||||
|
||||
try:
|
||||
key = self.api.register(
|
||||
token = self.api.register(
|
||||
self.ui.authenticators.currentData().auth,
|
||||
self.ui.username.text(),
|
||||
self.ui.password.text(),
|
||||
@ -115,7 +114,13 @@ class UDSConfigDialog(QDialog):
|
||||
(self.ui.logLevelComboBox.currentIndex() + 1) * 10000 # Loglevel
|
||||
)
|
||||
# Store parameters on register for later use, notify user of registration
|
||||
|
||||
udsactor.store.writeConfig(
|
||||
udsactor.types.ActorConfigurationType(
|
||||
host=self.ui.host.text(),
|
||||
validateCertificate=self.ui.validateCertificate.currentIndex() == 1,
|
||||
master_token=token
|
||||
)
|
||||
)
|
||||
# Inform the user
|
||||
QMessageBox.information(self, 'UDS Registration', 'Registration with UDS completed.', QMessageBox.Ok)
|
||||
except udsactor.rest.RESTError as e:
|
||||
|
@ -34,9 +34,9 @@ from . import types
|
||||
from . import rest
|
||||
|
||||
if sys.platform == 'win32':
|
||||
from .windows import operations
|
||||
from .windows import operations, store
|
||||
else:
|
||||
from .linux import operations
|
||||
from .linux import operations, store
|
||||
|
||||
from .info import VERSION
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -29,45 +29,50 @@
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
|
||||
import six
|
||||
import os
|
||||
import configparser
|
||||
import base64
|
||||
import pickle
|
||||
|
||||
DEBUG = False
|
||||
from .. import types
|
||||
|
||||
CONFIGFILE = '/etc/udsactor/udsactor.cfg' if DEBUG is False else '/tmp/udsactor.cfg'
|
||||
PRECONNECT_CMD = '/etc/udsactor/pre'
|
||||
CONFIGFILE = '/etc/udsactor/udsactor.cfg'
|
||||
|
||||
def checkPermissions() -> bool:
|
||||
return os.getuid() == 0
|
||||
|
||||
def checkPermissions():
|
||||
return True if DEBUG else os.getuid() == 0
|
||||
|
||||
|
||||
def readConfig():
|
||||
res = {}
|
||||
def readConfig() -> types.ActorConfigurationType:
|
||||
try:
|
||||
cfg = six.moves.configparser.SafeConfigParser() # @UndefinedVariable
|
||||
cfg.optionxform = six.text_type
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg.read(CONFIGFILE)
|
||||
# Just reads 'uds' section
|
||||
for key in cfg.options('uds'):
|
||||
res[key] = cfg.get('uds', key)
|
||||
if res[key].lower() in ('true', 'yes', 'si'):
|
||||
res[key] = True
|
||||
elif res[key].lower() in ('false', 'no'):
|
||||
res[key] = False
|
||||
uds: configparser.SectionProxy = cfg['uds']
|
||||
# Extract data:
|
||||
base64Data = uds.get('data', None)
|
||||
data = pickle.loads(base64.b64decode(base64Data.encode())) if base64Data else None
|
||||
|
||||
return types.ActorConfigurationType(
|
||||
host=uds.get('host', ''),
|
||||
validateCertificate=uds.getboolean('validate', fallback=False),
|
||||
master_token=uds.get('master_token', None),
|
||||
own_token=uds.get('own_token', None),
|
||||
data=data
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return res
|
||||
return types.ActorConfigurationType('', False)
|
||||
|
||||
|
||||
def writeConfig(data):
|
||||
cfg = six.moves.configparser.SafeConfigParser() # @UndefinedVariable
|
||||
cfg.optionxform = six.text_type
|
||||
def writeConfig(config: types.ActorConfigurationType) -> None:
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg.add_section('uds')
|
||||
for key, val in data.items():
|
||||
cfg.set('uds', key, str(val))
|
||||
uds: configparser.SectionProxy = cfg['uds']
|
||||
uds['host'] = config.host
|
||||
uds['validate'] = 'yes' if config.validateCertificate else 'no'
|
||||
if config.master_token:
|
||||
uds['master_token'] = config.master_token
|
||||
if config.own_token:
|
||||
uds['own_token'] = config.own_token
|
||||
if config.data:
|
||||
uds['data'] = base64.b64encode(pickle.dumps(config.data)).decode()
|
||||
|
||||
# Ensures exists destination folder
|
||||
dirname = os.path.dirname(CONFIGFILE)
|
||||
@ -77,17 +82,8 @@ def writeConfig(data):
|
||||
with open(CONFIGFILE, 'w') as f:
|
||||
cfg.write(f)
|
||||
|
||||
os.chmod(CONFIGFILE, 0o0600)
|
||||
os.chmod(CONFIGFILE, 0o0600) # Ensure only readable by root
|
||||
|
||||
|
||||
def useOldJoinSystem():
|
||||
return False
|
||||
|
||||
|
||||
# Right now, we do not really need an application to be run on "startup" as could ocur with windows
|
||||
def runApplication():
|
||||
return None
|
||||
|
||||
|
||||
def preApplication():
|
||||
return PRECONNECT_CMD
|
||||
|
@ -12,3 +12,10 @@ class AuthenticatorType(typing.NamedTuple):
|
||||
type: str
|
||||
priority: int
|
||||
isCustom: bool
|
||||
|
||||
class ActorConfigurationType(typing.NamedTuple):
|
||||
host: str
|
||||
validateCertificate: bool
|
||||
master_token: typing.Optional[str] = None
|
||||
own_token: typing.Optional[str] = None
|
||||
data: typing.Optional[typing.Dict[str, str]] = None
|
||||
|
@ -29,115 +29,75 @@
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import pickle
|
||||
from win32com.shell import shell # @UnresolvedImport, pylint: disable=import-error
|
||||
try:
|
||||
import typing
|
||||
|
||||
from win32com.shell import shell
|
||||
import winreg as wreg
|
||||
except ImportError: # Python 2.7 fallback
|
||||
import _winreg as wreg # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32security # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32security
|
||||
|
||||
DEBUG = False
|
||||
from .. import types
|
||||
|
||||
PATH = 'Software\\UDSActor'
|
||||
BASEKEY = wreg.HKEY_LOCAL_MACHINE
|
||||
|
||||
|
||||
# Can be changed to whatever we want, but registry key is protected by permissions
|
||||
def encoder(data):
|
||||
return data.encode('bz2')
|
||||
def checkPermissions() -> bool:
|
||||
return shell.IsUserAnAdmin()
|
||||
|
||||
|
||||
def decoder(data):
|
||||
return data.decode('bz2')
|
||||
|
||||
|
||||
path = 'Software\\UDSActor'
|
||||
baseKey = wreg.HKEY_CURRENT_USER if DEBUG is True else wreg.HKEY_LOCAL_MACHINE # @UndefinedVariable
|
||||
|
||||
|
||||
def checkPermissions():
|
||||
return True if DEBUG else shell.IsUserAnAdmin()
|
||||
|
||||
|
||||
def fixRegistryPermissions(handle):
|
||||
if DEBUG:
|
||||
return
|
||||
def fixRegistryPermissions(handle) -> None:
|
||||
# Fix permissions so users can't read this key
|
||||
v = win32security.GetSecurityInfo(handle, win32security.SE_REGISTRY_KEY, win32security.DACL_SECURITY_INFORMATION)
|
||||
dacl = v.GetSecurityDescriptorDacl()
|
||||
n = 0
|
||||
# Remove all normal users access permissions to the registry key
|
||||
while n < dacl.GetAceCount():
|
||||
if unicode(dacl.GetAce(n)[2]) == u'PySID:S-1-5-32-545': # Whell known Users SID
|
||||
if str(dacl.GetAce(n)[2]) == 'PySID:S-1-5-32-545': # Whell known Users SID
|
||||
dacl.DeleteAce(n)
|
||||
else:
|
||||
n += 1
|
||||
win32security.SetSecurityInfo(handle, win32security.SE_REGISTRY_KEY,
|
||||
win32security.SetSecurityInfo(
|
||||
handle,
|
||||
win32security.SE_REGISTRY_KEY,
|
||||
win32security.DACL_SECURITY_INFORMATION | win32security.PROTECTED_DACL_SECURITY_INFORMATION,
|
||||
None, None, dacl, None)
|
||||
None,
|
||||
None,
|
||||
dacl,
|
||||
None
|
||||
)
|
||||
|
||||
|
||||
def readConfig():
|
||||
def readConfig() -> types.ActorConfigurationType:
|
||||
try:
|
||||
key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_QUERY_VALUE) # @UndefinedVariable
|
||||
key = wreg.OpenKey(BASEKEY, PATH, 0, wreg.KEY_QUERY_VALUE) # @UndefinedVariable
|
||||
data, _ = wreg.QueryValueEx(key, '') # @UndefinedVariable
|
||||
wreg.CloseKey(key) # @UndefinedVariable
|
||||
return pickle.loads(decoder(data))
|
||||
return pickle.loads(data)
|
||||
except Exception:
|
||||
return None
|
||||
return types.ActorConfigurationType('', False)
|
||||
|
||||
|
||||
def writeConfig(data, fixPermissions=True):
|
||||
def writeConfig(config: types.ActorConfigurationType) -> None:
|
||||
try:
|
||||
key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
||||
key = wreg.OpenKey(BASEKEY, PATH, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
||||
except Exception:
|
||||
key = wreg.CreateKeyEx(baseKey, path, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
||||
if fixPermissions is True:
|
||||
key = wreg.CreateKeyEx(BASEKEY, PATH, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
||||
fixRegistryPermissions(key.handle)
|
||||
|
||||
wreg.SetValueEx(key, "", 0, wreg.REG_BINARY, encoder(pickle.dumps(data))) # @UndefinedVariable
|
||||
wreg.SetValueEx(key, "", 0, wreg.REG_BINARY, pickle.dumps(config)) # @UndefinedVariable
|
||||
wreg.CloseKey(key) # @UndefinedVariable
|
||||
|
||||
|
||||
def useOldJoinSystem():
|
||||
def useOldJoinSystem() -> bool:
|
||||
try:
|
||||
key = wreg.OpenKey(baseKey, 'Software\\UDSEnterpriseActor', 0, wreg.KEY_QUERY_VALUE) # @UndefinedVariable
|
||||
key = wreg.OpenKey(BASEKEY, 'Software\\UDSEnterpriseActor', 0, wreg.KEY_QUERY_VALUE) # @UndefinedVariable
|
||||
try:
|
||||
data, _ = wreg.QueryValueEx(key, 'join') # @UndefinedVariable
|
||||
except Exception:
|
||||
data = ''
|
||||
wreg.CloseKey(key) # @UndefinedVariable
|
||||
except:
|
||||
except Exception:
|
||||
data = ''
|
||||
|
||||
return data == 'old'
|
||||
|
||||
|
||||
# Gives the oportunity to run an application ONE TIME (because, the registry key "run" will be deleted after read)
|
||||
def runApplication():
|
||||
try:
|
||||
key = wreg.OpenKey(baseKey, 'Software\\UDSEnterpriseActor', 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
||||
try:
|
||||
data, _ = wreg.QueryValueEx(key, 'run') # @UndefinedVariable
|
||||
wreg.DeleteValue(key, 'run') # @UndefinedVariable
|
||||
except Exception:
|
||||
data = None
|
||||
wreg.CloseKey(key) # @UndefinedVariable
|
||||
except Exception:
|
||||
data = None
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def preApplication():
|
||||
try:
|
||||
key = wreg.OpenKey(baseKey, 'Software\\UDSEnterpriseActor', 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
||||
try:
|
||||
data, _ = wreg.QueryValueEx(key, 'pre') # @UndefinedVariable
|
||||
except Exception:
|
||||
data = None
|
||||
wreg.CloseKey(key) # @UndefinedVariable
|
||||
except Exception:
|
||||
data = None
|
||||
|
||||
return data
|
||||
|
29
server/src/uds/migrations/0034_actortoken.py
Normal file
29
server/src/uds/migrations/0034_actortoken.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Generated by Django 2.2.7 on 2019-11-21 12:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('uds', '0033_auto_20190814_0951'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ActorToken',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('username', models.CharField(max_length=128)),
|
||||
('ip_from', models.CharField(max_length=128)),
|
||||
('ip', models.CharField(max_length=128)),
|
||||
('mac', models.CharField(db_index=True, max_length=128, unique=True)),
|
||||
('pre_command', models.CharField(blank=True, default='', max_length=255)),
|
||||
('post_command', models.CharField(blank=True, default='', max_length=255)),
|
||||
('runonce_command', models.CharField(blank=True, default='', max_length=255)),
|
||||
('log_level', models.IntegerField()),
|
||||
('token', models.CharField(db_index=True, max_length=48, unique=True)),
|
||||
('stamp', models.DateTimeField()),
|
||||
],
|
||||
),
|
||||
]
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -25,15 +25,26 @@
|
||||
# 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
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
# pylint: disable=unused-wildcard-import, wildcard-import
|
||||
from __future__ import unicode_literals
|
||||
from django.db import models
|
||||
|
||||
import sys
|
||||
if sys.platform == 'win32':
|
||||
from udsactor.windows.store import * # @UnusedWildImport
|
||||
else:
|
||||
from udsactor.linux.store import * # @UnusedWildImport
|
||||
class ActorToken(models.Model):
|
||||
"""
|
||||
UDS Actors tokens on DB
|
||||
"""
|
||||
username = models.CharField(max_length=128)
|
||||
ip_from = models.CharField(max_length=128)
|
||||
ip = models.CharField(max_length=128)
|
||||
mac = models.CharField(max_length=128, db_index=True, unique=True)
|
||||
pre_command = models.CharField(max_length=255, blank=True, default='')
|
||||
post_command = models.CharField(max_length=255, blank=True, default='')
|
||||
runonce_command = models.CharField(max_length=255, blank=True, default='')
|
||||
log_level = models.IntegerField()
|
||||
|
||||
token = models.CharField(max_length=48, db_index=True, unique=True)
|
||||
stamp = models.DateTimeField() # Date creation or validation of this entry
|
||||
|
||||
def __str__(self):
|
||||
return '<ActorToken {} created on {} by {} from {}/{}>'.format(self.token, self.stamp, self.username, self.ip_from, self.ip)
|
Loading…
Reference in New Issue
Block a user