mirror of
https://github.com/dkmstr/openuds.git
synced 2025-01-03 01:17:56 +03:00
Included "mac" as a informative field for registered servers
This commit is contained in:
parent
7ca11fdb53
commit
c0484d628d
@ -86,7 +86,7 @@ class Handler:
|
||||
_request: 'ExtendedHttpRequestWithUser' # It's a modified HttpRequest
|
||||
_path: str
|
||||
_operation: str
|
||||
_params: typing.Any # This is a deserliazied object from request. Can be anything as 'a' or {'a': 1} or ....
|
||||
_params: typing.MutableMapping[str, typing.Any] # This is a deserliazied object from request. Can be anything as 'a' or {'a': 1} or ....
|
||||
_args: typing.Tuple[
|
||||
str, ...
|
||||
] # This are the "path" split by /, that is, the REST invocation arguments
|
||||
|
@ -276,20 +276,18 @@ class Register(ActorV3Action):
|
||||
name = 'register'
|
||||
|
||||
def post(self) -> typing.MutableMapping[str, typing.Any]:
|
||||
actorToken: RegisteredServers
|
||||
# If already exists a token for this MAC, return it instead of creating a new one, and update the information...
|
||||
# Look for a token for this mac. mac is "inside" data, so we must filter first by type and then ensure mac is inside data
|
||||
# and mac is the requested one
|
||||
found = False
|
||||
for actorToken in RegisteredServers.objects.filter(kind=RegisteredServers.ServerType.ACTOR):
|
||||
if actorToken.data and actorToken.data.get('mac', '') == self._params['mac']:
|
||||
actorToken: typing.Optional[RegisteredServers] = RegisteredServers.objects.filter(kind=RegisteredServers.ServerType.ACTOR, mac=self._params['mac']).first()
|
||||
if actorToken:
|
||||
# Update parameters
|
||||
actorToken.username = self._user.pretty_name
|
||||
actorToken.ip_from = self._request.ip
|
||||
actorToken.ip = self._params['ip']
|
||||
actorToken.hostname = self._params['hostname']
|
||||
actorToken.data = { # type: ignore
|
||||
'mac': self._params['mac'],
|
||||
'pre_command': self._params['pre_command'],
|
||||
'post_command': self._params['post_command'],
|
||||
'run_once_command': self._params['run_once_command'],
|
||||
@ -300,7 +298,6 @@ class Register(ActorV3Action):
|
||||
actorToken.save()
|
||||
logger.info('Registered actor %s', self._params)
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
kwargs = {
|
||||
@ -310,16 +307,16 @@ class Register(ActorV3Action):
|
||||
'ip_version': self._request.ip_version,
|
||||
'hostname': self._params['hostname'],
|
||||
'data': { # type: ignore
|
||||
'mac': self._params['mac'],
|
||||
'pre_command': self._params['pre_command'],
|
||||
'post_command': self._params['post_command'],
|
||||
'run_once_command': self._params['run_once_command'],
|
||||
'log_level': self._params['log_level'],
|
||||
'custom': self._params.get('custom', ''),
|
||||
},
|
||||
'token': secrets.token_urlsafe(36),
|
||||
'token': RegisteredServers.create_token(),
|
||||
'kind': RegisteredServers.ServerType.ACTOR,
|
||||
'os_type': self._params.get('os', KnownOS.UNKNOWN.os_name()),
|
||||
'mac': self._params['mac'],
|
||||
'stamp': getSqlDatetime(),
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,9 @@ class ServerRegister(Handler):
|
||||
serverToken: models.RegisteredServers
|
||||
now = getSqlDatetimeAsUnix()
|
||||
try:
|
||||
# If already exists a token for this MAC, return it instead of creating a new one, and update the information...
|
||||
# If already exists a token for this, return it instead of creating a new one, and update the information...
|
||||
# Note that we use IP and HOSTNAME to identify the server, so if any of them changes, a new token will be created
|
||||
# MAC is just informative, and data is used to store any other information that may be needed
|
||||
serverToken = models.RegisteredServers.objects.get(
|
||||
ip=self._params['ip'], hostname=self._params['hostname']
|
||||
)
|
||||
@ -72,10 +74,11 @@ class ServerRegister(Handler):
|
||||
ip_from=self._request.ip,
|
||||
ip=self._params['ip'],
|
||||
hostname=self._params['hostname'],
|
||||
token=secrets.token_urlsafe(36),
|
||||
token=models.RegisteredServers.create_token(),
|
||||
stamp=getSqlDatetime(),
|
||||
kind=self._params['type'],
|
||||
os_type=typing.cast(str, self._params.get('os', KnownOS.UNKNOWN.os_name())).lower(),
|
||||
mac=self._params.get('mac', models.RegisteredServers.MAC_UNKNOWN),
|
||||
data=self._params.get('data', None),
|
||||
)
|
||||
except Exception as e:
|
@ -41,7 +41,7 @@ from uds.core.auths.auth import isTrustedSource
|
||||
from uds.core.util import log, net
|
||||
from uds.core.util.stats import events
|
||||
|
||||
from .servers import ServerRegister
|
||||
from .registered_servers import ServerRegister
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -162,5 +162,5 @@ class TunnelRegister(ServerRegister):
|
||||
# Just a compatibility method for old tunnel servers
|
||||
def post(self) -> typing.MutableMapping[str, typing.Any]:
|
||||
self._params['type'] = models.RegisteredServers.ServerType.TUNNEL
|
||||
self._params['os'] = KnownOS.LINUX.os_name() # Legacy tunnels are always linux
|
||||
self._params['os'] = self._params.get('os', KnownOS.LINUX.os_name()) # Legacy tunnels are always linux
|
||||
return super().post()
|
||||
|
@ -30,6 +30,8 @@ Author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
import typing
|
||||
import enum
|
||||
import secrets
|
||||
|
||||
from uds.core.util.os_detector import KnownOS
|
||||
|
||||
from django.db import models
|
||||
@ -37,6 +39,7 @@ from uds.core.util.request import ExtendedHttpRequest
|
||||
|
||||
from .consts import MAX_DNS_NAME_LENGTH, MAX_IPV6_LENGTH
|
||||
|
||||
|
||||
class RegisteredServers(models.Model):
|
||||
"""
|
||||
UDS Registered Servers
|
||||
@ -54,14 +57,18 @@ class RegisteredServers(models.Model):
|
||||
If server is Other, but not Tunnel, it will be allowed to access API, but will not be able to
|
||||
create tunnels.
|
||||
"""
|
||||
class ServerType(enum.IntFlag):
|
||||
|
||||
class ServerType(enum.IntEnum):
|
||||
TUNNEL = 1
|
||||
ACTOR = 2
|
||||
APP_SERVER = 3
|
||||
OTHER = 99
|
||||
|
||||
def as_str(self) -> str:
|
||||
return self.name.lower() # type: ignore
|
||||
|
||||
MAC_UNKNOWN = '00:00:00:00:00:00'
|
||||
|
||||
username = models.CharField(max_length=128)
|
||||
ip_from = models.CharField(max_length=MAX_IPV6_LENGTH)
|
||||
ip = models.CharField(max_length=MAX_IPV6_LENGTH)
|
||||
@ -72,18 +79,26 @@ class RegisteredServers(models.Model):
|
||||
token = models.CharField(max_length=48, db_index=True, unique=True)
|
||||
stamp = models.DateTimeField() # Date creation or validation of this entry
|
||||
|
||||
kind = models.IntegerField(default=ServerType.TUNNEL.value) # Defaults to tunnel server, so we can migrate from previous versions
|
||||
os_type = models.CharField(max_length=32, default=KnownOS.UNKNOWN.os_name()) # os type of server (linux, windows, etc..)
|
||||
# Type of server. Defaults to tunnel, so we can migrate from previous versions
|
||||
kind = models.IntegerField(default=ServerType.TUNNEL.value)
|
||||
# os type of server (linux, windows, etc..)
|
||||
os_type = models.CharField(max_length=32, default=KnownOS.UNKNOWN.os_name())
|
||||
# mac address of registered server, if any. Important for actor servers mainly, informative for others
|
||||
mac = models.CharField(max_length=32, default=MAC_UNKNOWN, db_index=True)
|
||||
|
||||
# Extra data, for custom server type use (i.e. actor keeps command related data here)
|
||||
data = models.JSONField(null=True, blank=True, default=None)
|
||||
|
||||
class Meta: # pylint: disable=too-few-public-methods
|
||||
app_label = 'uds'
|
||||
|
||||
@staticmethod
|
||||
def validateToken(
|
||||
token: str, request: typing.Optional[ExtendedHttpRequest] = None
|
||||
) -> bool:
|
||||
def create_token() -> str:
|
||||
return secrets.token_urlsafe(36)
|
||||
|
||||
@staticmethod
|
||||
def validateToken(token: str, request: typing.Optional[ExtendedHttpRequest] = None) -> bool:
|
||||
# Ensure tiken is composed of
|
||||
try:
|
||||
tt = RegisteredServers.objects.get(token=token)
|
||||
# We could check the request ip here
|
||||
|
Loading…
Reference in New Issue
Block a user