From bda2232629b9af6a0f95a18853bb5fbba4b9f381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Wed, 24 Jun 2020 00:48:06 +0200 Subject: [PATCH] Added Custom External URL Launcher --- server/src/uds/transports/URL/__init__.py | 34 ++++++ server/src/uds/transports/URL/url.png | Bin 0 -> 2803 bytes server/src/uds/transports/URL/url_custom.py | 118 ++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 server/src/uds/transports/URL/__init__.py create mode 100644 server/src/uds/transports/URL/url.png create mode 100644 server/src/uds/transports/URL/url_custom.py diff --git a/server/src/uds/transports/URL/__init__.py b/server/src/uds/transports/URL/__init__.py new file mode 100644 index 00000000..a3c43b27 --- /dev/null +++ b/server/src/uds/transports/URL/__init__.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +# +# Copyright (c) 2012-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 +""" + +from .url_custom import URLCustomTransport diff --git a/server/src/uds/transports/URL/url.png b/server/src/uds/transports/URL/url.png new file mode 100644 index 0000000000000000000000000000000000000000..d07ebf0ce4510c93f5948fa65df0dfeafece2d70 GIT binary patch literal 2803 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 FV1h^*K$8Ff literal 0 HcmV?d00001 diff --git a/server/src/uds/transports/URL/url_custom.py b/server/src/uds/transports/URL/url_custom.py new file mode 100644 index 00000000..9624bc79 --- /dev/null +++ b/server/src/uds/transports/URL/url_custom.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- + +# +# Copyright (c) 2012-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 logging +import typing + +from django.utils.translation import ugettext_noop as _ +from django.urls import reverse +from django.http import HttpResponseRedirect + +from uds.core.ui import gui + +from uds.core import transports + +from uds.core.util import os_detector as OsDetector +from uds.core.managers import cryptoManager +from uds import models + +# Not imported at runtime, just for type checking +if typing.TYPE_CHECKING: + from uds.core import Module + from django.http import HttpRequest # pylint: disable=ungrouped-imports + +logger = logging.getLogger(__name__) + + +class URLCustomTransport(transports.Transport): + """ + Provides access via RDP to service. + This transport can use an domain. If username processed by authenticator contains '@', it will split it and left-@-part will be username, and right password + """ + typeName = _('URL Launcher') + typeType = 'URLTransport' + typeDescription = _('Launchs an external UDS customized URL') + iconFile = 'url.png' + + ownLink = True + supportedOss = OsDetector.allOss + protocol = transports.protocols.OTHER + group = transports.DIRECT_GROUP + + urlPattern = gui.TextField(label=_('URL Pattern'), order=1, tooltip=_('URL Pattern to open (i.e. https://_IP_/test?user=_USER_'), defvalue='https://www.udsenterprise.com', length=64, required=True) + + forceNewWindow = gui.CheckBoxField( + label=_('Force new HTML Window'), + order=91, + tooltip=_('If checked, every connection will try to open its own window instead of reusing the "global" one.'), + defvalue=gui.FALSE, + tab=gui.ADVANCED_TAB + ) + + def initialize(self, values: 'Module.ValuesType'): + if not values: + return + # Strip spaces + if not (self.urlPattern.value.startswith('http://') or self.urlPattern.value.startswith('https://')): + raise transports.Transport.ValidationException(_('The url must be http or https')) + + # Same check as normal RDP transport + def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool: + # No check is done for URL transport + return True + + def getLink( # pylint: disable=too-many-locals + self, + userService: 'models.UserService', + transport: 'models.Transport', + ip: str, + os: typing.Dict[str, str], + user: 'models.User', + password: str, + request: 'HttpRequest' + ) -> str: + + # Fix username/password acording to os manager + username: str = user.getUsernameForAuth() + username, password = userService.processUserPassword(username, password) + + url = ( + self.urlPattern.value.replace('_IP_', ip) + .replace('_USERNAME_', username) + ) + + return HttpResponseRedirect( + "{}{}".format( + url, + '&o_n_w=0;' if self.forceNewWindow.isTrue() else '' + ) + )