diff --git a/server/src/uds/transports/HTML5VNC/html5vnc.py b/server/src/uds/transports/HTML5VNC/html5vnc.py index 7c51d1ad..d8901776 100644 --- a/server/src/uds/transports/HTML5VNC/html5vnc.py +++ b/server/src/uds/transports/HTML5VNC/html5vnc.py @@ -60,6 +60,7 @@ class HTML5VNCTransport(transports.Transport): Provides access via VNC 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 = _('HTML5 VNC Experimental') typeType = 'HTML5VNCTransport' typeDescription = _('VNC protocol using HTML5 client (EXPERIMENTAL)') @@ -70,10 +71,30 @@ class HTML5VNCTransport(transports.Transport): protocol = transports.protocols.VNC group = transports.TUNNELED_GROUP - guacamoleServer = gui.TextField(label=_('Tunnel Server'), order=1, tooltip=_('Host of the tunnel server (use http/https & port if needed) as accesible from users'), defvalue='https://', length=64, required=True, tab=gui.TUNNEL_TAB) + guacamoleServer = gui.TextField( + label=_('Tunnel Server'), + order=1, + tooltip=_( + 'Host of the tunnel server (use http/https & port if needed) as accesible from users' + ), + defvalue='https://', + length=64, + required=True, + tab=gui.TUNNEL_TAB, + ) - username = gui.TextField(label=_('Username'), order=20, tooltip=_('Username for VNC connection authentication.'), tab=gui.PARAMETERS_TAB) - password = gui.PasswordField(label=_('Password'), order=21, tooltip=_('Password for VNC connection authentication'), tab=gui.PARAMETERS_TAB) + username = gui.TextField( + label=_('Username'), + order=20, + tooltip=_('Username for VNC connection authentication.'), + tab=gui.PARAMETERS_TAB, + ) + password = gui.PasswordField( + label=_('Password'), + order=21, + tooltip=_('Password for VNC connection authentication'), + tab=gui.PARAMETERS_TAB, + ) vncPort = gui.NumericField( length=22, @@ -82,7 +103,7 @@ class HTML5VNCTransport(transports.Transport): order=2, tooltip=_('Port of the VNC server.'), required=True, - tab=gui.PARAMETERS_TAB + tab=gui.PARAMETERS_TAB, ) colorDepth = gui.ChoiceField( @@ -98,21 +119,40 @@ class HTML5VNCTransport(transports.Transport): gui.choiceItem('32', '33 bits'), ], defvalue='-', - tab=gui.PARAMETERS_TAB + tab=gui.PARAMETERS_TAB, ) - swapRedBlue = gui.CheckBoxField(label=_('Swap red/blue'), order=27, tooltip=_('Use this if your colours seems incorrect (blue appears red, ..) to swap them.'), tab=gui.PARAMETERS_TAB) - cursor = gui.CheckBoxField(label=_('Remote cursor'), order=28, tooltip=_('If set, force to show remote cursor'), tab=gui.PARAMETERS_TAB) - readOnly = gui.CheckBoxField(label=_('Read only'), order=29, tooltip=_('If set, the connection will be read only'), tab=gui.PARAMETERS_TAB) - + swapRedBlue = gui.CheckBoxField( + label=_('Swap red/blue'), + order=27, + tooltip=_( + 'Use this if your colours seems incorrect (blue appears red, ..) to swap them.' + ), + tab=gui.PARAMETERS_TAB, + ) + cursor = gui.CheckBoxField( + label=_('Remote cursor'), + order=28, + tooltip=_('If set, force to show remote cursor'), + tab=gui.PARAMETERS_TAB, + ) + readOnly = gui.CheckBoxField( + label=_('Read only'), + order=29, + tooltip=_('If set, the connection will be read only'), + tab=gui.PARAMETERS_TAB, + ) + ticketValidity = gui.NumericField( length=3, label=_('Ticket Validity'), defvalue='60', order=90, - tooltip=_('Allowed time, in seconds, for HTML5 client to reload data from UDS Broker. The default value of 60 is recommended.'), + tooltip=_( + 'Allowed time, in seconds, for HTML5 client to reload data from UDS Broker. The default value of 60 is recommended.' + ), required=True, minValue=60, - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) forceNewWindow = gui.ChoiceField( order=91, @@ -120,12 +160,20 @@ class HTML5VNCTransport(transports.Transport): tooltip=_('Select windows behavior for new connections on HTML5'), required=True, values=[ - gui.choiceItem(gui.FALSE, _('Open every connection on the same window, but keeps UDS window.')), - gui.choiceItem(gui.TRUE, _('Force every connection to be opened on a new window.')), - gui.choiceItem('overwrite', _('Override UDS window and replace it with the connection.')), + gui.choiceItem( + gui.FALSE, + _('Open every connection on the same window, but keeps UDS window.'), + ), + gui.choiceItem( + gui.TRUE, _('Force every connection to be opened on a new window.') + ), + gui.choiceItem( + 'overwrite', + _('Override UDS window and replace it with the connection.'), + ), ], defvalue=gui.FALSE, - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) def initialize(self, values: 'Module.ValuesType'): @@ -134,7 +182,9 @@ class HTML5VNCTransport(transports.Transport): # Strip spaces self.guacamoleServer.value = self.guacamoleServer.value.strip() if self.guacamoleServer.value[0:4] != 'http': - raise transports.Transport.ValidationException(_('The server must be http or https')) + raise transports.Transport.ValidationException( + _('The server must be http or https') + ) def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool: """ @@ -152,15 +202,15 @@ class HTML5VNCTransport(transports.Transport): return ready == 'Y' 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: + self, + userService: 'models.UserService', + transport: 'models.Transport', + ip: str, + os: typing.Dict[str, str], + user: 'models.User', + password: str, + request: 'HttpRequest', + ) -> str: # Build params dict params = { 'protocol': 'vnc', @@ -200,9 +250,6 @@ class HTML5VNCTransport(transports.Transport): return str( "{}/guacamole/#/?data={}.{}{}".format( - self.guacamoleServer.value, - ticket, - scrambler, - onw + self.guacamoleServer.value, ticket, scrambler, onw ) ) diff --git a/server/src/uds/transports/RDP/rdp.py b/server/src/uds/transports/RDP/rdp.py index 65aff7f9..33630df5 100644 --- a/server/src/uds/transports/RDP/rdp.py +++ b/server/src/uds/transports/RDP/rdp.py @@ -53,6 +53,7 @@ class RDPTransport(BaseRDPTransport): 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 = _('RDP') typeType = 'RDPTransport' typeDescription = _('RDP Protocol. Direct connection.') @@ -91,15 +92,15 @@ class RDPTransport(BaseRDPTransport): customParametersMAC = BaseRDPTransport.customParametersMAC def getUDSTransportScript( # 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' - ) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]: + self, + userService: 'models.UserService', + transport: 'models.Transport', + ip: str, + os: typing.Dict[str, str], + user: 'models.User', + password: str, + request: 'HttpRequest', + ) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]: # We use helper to keep this clean # prefs = user.prefs('rdp') @@ -114,7 +115,9 @@ class RDPTransport(BaseRDPTransport): width, height = self.screenSize.value.split('x') depth = self.colorDepth.value - r = RDPFile(width == '-1' or height == '-1', width, height, depth, target=os['OS']) + r = RDPFile( + width == '-1' or height == '-1', width, height, depth, target=os['OS'] + ) r.enablecredsspsupport = ci.get('sso') == 'True' or self.credssp.isTrue() r.address = '{}:{}'.format(ip, self.rdpPort.value) r.username = username @@ -143,13 +146,17 @@ class RDPTransport(BaseRDPTransport): osName = { OsDetector.Windows: 'windows', OsDetector.Linux: 'linux', - OsDetector.Macintosh: 'macosx' - + OsDetector.Macintosh: 'macosx', }.get(os['OS']) if osName is None: - logger.error('Os not detected for RDP Transport: %s', request.META.get('HTTP_USER_AGENT', 'Unknown')) - return super().getUDSTransportScript(userService, transport, ip, os, user, password, request) + logger.error( + 'Os not detected for RDP Transport: %s', + request.META.get('HTTP_USER_AGENT', 'Unknown'), + ) + return super().getUDSTransportScript( + userService, transport, ip, os, user, password, request + ) sp: typing.MutableMapping[str, typing.Any] = { 'password': password, @@ -162,21 +169,27 @@ class RDPTransport(BaseRDPTransport): if osName == 'windows': if password != '': r.password = '{password}' - sp.update({ - 'as_file': r.as_file, - }) + sp.update( + { + 'as_file': r.as_file, + } + ) elif osName == 'linux': - sp.update({ - 'as_new_xfreerdp_params': r.as_new_xfreerdp_params, - 'address': r.address, - }) + sp.update( + { + 'as_new_xfreerdp_params': r.as_new_xfreerdp_params, + 'address': r.address, + } + ) else: # Mac r.linuxCustomParameters = self.customParametersMAC.value - sp.update({ - 'as_new_xfreerdp_params': r.as_new_xfreerdp_params, - 'as_rdp_url': r.as_rdp_url if self.allowMacMSRDC.isTrue() else '', - 'as_file': r.as_file if self.allowMacMSRDC.isTrue() else '', - 'address': r.address, - }) + sp.update( + { + 'as_new_xfreerdp_params': r.as_new_xfreerdp_params, + 'as_rdp_url': r.as_rdp_url if self.allowMacMSRDC.isTrue() else '', + 'as_file': r.as_file if self.allowMacMSRDC.isTrue() else '', + 'address': r.address, + } + ) return self.getScript('scripts/{}/direct.py', osName, sp) diff --git a/server/src/uds/transports/RDP/rdp_base.py b/server/src/uds/transports/RDP/rdp_base.py index e6fbdc1a..9775e2b2 100644 --- a/server/src/uds/transports/RDP/rdp_base.py +++ b/server/src/uds/transports/RDP/rdp_base.py @@ -167,16 +167,16 @@ class BaseRDPTransport(transports.Transport): tab=gui.PARAMETERS_TAB, defvalue=gui.TRUE, ) - rdpPort = gui.NumericField(order = 29, - length = 5, # That is, max allowed value is 65535 + rdpPort = gui.NumericField( + order=29, + length=5, # That is, max allowed value is 65535 label=_('RDP Port'), tooltip=_('Use this port as RDP port. Defaults to 3389.'), tab=gui.PARAMETERS_TAB, - required = True, #: Numeric fields have always a value, so this not really needed - defvalue = '3389', + required=True, #: Numeric fields have always a value, so this not really needed + defvalue='3389', ) - screenSize = gui.ChoiceField( label=_('Screen Size'), order=30, @@ -359,7 +359,7 @@ class BaseRDPTransport(transports.Transport): if self.fixedPassword.value: password = self.fixedPassword.value - + azureAd = False if self.fixedDomain.value != '': if self.fixedDomain.value.lower() == 'azuread': @@ -391,7 +391,7 @@ class BaseRDPTransport(transports.Transport): 'protocol': self.protocol, 'username': username, 'password': password, - 'domain': domain + 'domain': domain, } def getConnectionInfo( @@ -408,7 +408,10 @@ class BaseRDPTransport(transports.Transport): _, username, password = cdata # Host is unused return self.processUserPassword( - typing.cast('models.UserService', userService), user, password, altUsername=username + typing.cast('models.UserService', userService), + user, + password, + altUsername=username, ) def getScript( diff --git a/server/src/uds/transports/RDP/rdp_file.py b/server/src/uds/transports/RDP/rdp_file.py index 29e68430..088823cf 100644 --- a/server/src/uds/transports/RDP/rdp_file.py +++ b/server/src/uds/transports/RDP/rdp_file.py @@ -39,6 +39,7 @@ import typing from uds.core.util import os_detector as OsDetector + class RDPFile: fullScreen = False width = '800' @@ -71,13 +72,13 @@ class RDPFile: enforcedShares: typing.Optional[str] = None def __init__( - self, - fullScreen: bool, - width: typing.Union[str, int], - height: typing.Union[str, int], - bpp: str, - target: str = OsDetector.Windows - ): + self, + fullScreen: bool, + width: typing.Union[str, int], + height: typing.Union[str, int], + bpp: str, + target: str = OsDetector.Windows, + ): self.width = str(width) self.height = str(height) self.bpp = str(bpp) @@ -95,7 +96,9 @@ class RDPFile: return self.get() @property - def as_new_xfreerdp_params(self): # pylint: disable=too-many-statements,too-many-branches + def as_new_xfreerdp_params( + self, + ): # pylint: disable=too-many-statements,too-many-branches """ Parameters for xfreerdp >= 1.1.0 with self rdp description Note that server is not added @@ -188,7 +191,7 @@ class RDPFile: def getGeneric(self): # pylint: disable=too-many-statements password = '{password}' screenMode = '2' if self.fullScreen else '1' - audioMode = '0' if self.redirectAudio else '2' + audioMode = '0' if self.redirectAudio else '2' serials = '1' if self.redirectSerials else '0' scards = '1' if self.redirectSmartcards else '0' printers = '1' if self.redirectPrinters else '0' @@ -250,7 +253,11 @@ class RDPFile: if self.redirectWebcam: res += 'camerastoredirect:s:*\n' - enforcedSharesStr = ';'.join(self.enforcedShares.replace(' ', '').upper().split(',')) + ';' if self.enforcedShares else '' + enforcedSharesStr = ( + ';'.join(self.enforcedShares.replace(' ', '').upper().split(',')) + ';' + if self.enforcedShares + else '' + ) if self.redirectDrives != 'false': if self.redirectDrives == 'true': @@ -259,7 +266,9 @@ class RDPFile: res += 'drivestoredirect:s:{}DynamicDrives\n'.format(enforcedSharesStr) res += 'devicestoredirect:s:*\n' - res += 'enablecredsspsupport:i:{}\n'.format(0 if self.enablecredsspsupport is False else 1) + res += 'enablecredsspsupport:i:{}\n'.format( + 0 if self.enablecredsspsupport is False else 1 + ) # DirectX? res += 'redirectdirectx:i:1\n' @@ -273,12 +282,11 @@ class RDPFile: def as_rdp_url(self) -> str: # Some parameters screenMode = '2' if self.fullScreen else '1' - audioMode = '0' if self.redirectAudio else '2' + audioMode = '0' if self.redirectAudio else '2' useMultimon = '1' if self.multimon else '0' disableWallpaper = '0' if self.showWallpaper else '1' printers = '1' if self.redirectPrinters else '0' credsspsupport = '1' if self.enablecredsspsupport else '0' - parameters = [ ('full address', f's:{self.address}'), @@ -295,7 +303,7 @@ class RDPFile: ('disable full window drag', 'i:1'), ('authentication level', f'i:0'), # Not listed, but maybe usable? - ('enablecredsspsupport', f'i:{credsspsupport}') + ('enablecredsspsupport', f'i:{credsspsupport}'), ] if self.username: parameters.append(('username', f's:{urllib.parse.quote(self.username)}')) @@ -311,5 +319,6 @@ class RDPFile: if self.redirectDrives != 'false': # Only "all drives" is supported parameters.append(('drivestoredirect', 's:*')) - return 'rdp://' + '&'.join((urllib.parse.quote(i[0]) + '=' + i[1] for i in parameters)) - + return 'rdp://' + '&'.join( + (urllib.parse.quote(i[0]) + '=' + i[1] for i in parameters) + ) diff --git a/server/src/uds/transports/RDP/scripts/linux/direct.py b/server/src/uds/transports/RDP/scripts/linux/direct.py index dbb28602..b7c3d35e 100644 --- a/server/src/uds/transports/RDP/scripts/linux/direct.py +++ b/server/src/uds/transports/RDP/scripts/linux/direct.py @@ -1,17 +1,15 @@ -# This is a template -# Saved as .py for easier editing -from __future__ import unicode_literals - -import subprocess +import subprocess # noqa from uds import tools # type: ignore # Inject local passed sp into globals for inner functions globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable + def execUdsRdp(udsrdp): import subprocess # @Reimport import os.path + params = [os.path.expandvars(i) for i in [udsrdp] + sp['as_new_xfreerdp_params'] + ['/v:{}'.format(sp['address'])]] # type: ignore tools.addTaskToWait(subprocess.Popen(params)) @@ -19,9 +17,11 @@ def execUdsRdp(udsrdp): def execNewXFreeRdp(xfreerdp): import subprocess # @Reimport import os.path + params = [os.path.expandvars(i) for i in [xfreerdp] + sp['as_new_xfreerdp_params'] + ['/v:{}'.format(sp['address'])]] # type: ignore tools.addTaskToWait(subprocess.Popen(params)) + # Try to locate a "valid" version of xfreerdp as first option (<1.1 does not allows drive redirections, so it will not be used if found) xfreerdp = tools.findApp('xfreerdp') udsrdp = tools.findApp('udsrdp') @@ -34,9 +34,11 @@ if udsrdp is not None: fnc, app = execUdsRdp, udsrdp if app is None or fnc is None: - raise Exception('''
You need to have installed xfreerdp (>= 1.1) or rdesktop, and have them in your PATH in order to connect to this UDS service.
+ raise Exception( + '''You need to have installed xfreerdp (>= 1.1) or rdesktop, and have them in your PATH in order to connect to this UDS service.
Please, install the proper package for your system.
Also note that xfreerdp prior to version 1.1 will not be taken into consideration.
-''') +''' + ) else: fnc(app) # @UndefinedVariable diff --git a/server/src/uds/transports/RDP/scripts/linux/tunnel.py b/server/src/uds/transports/RDP/scripts/linux/tunnel.py index 11f36188..3c96e3db 100644 --- a/server/src/uds/transports/RDP/scripts/linux/tunnel.py +++ b/server/src/uds/transports/RDP/scripts/linux/tunnel.py @@ -1,8 +1,5 @@ -# This is a template -# Saved as .py for easier editing -from __future__ import unicode_literals +import subprocess # noqa -import subprocess from uds.tunnel import forward # type: ignore from uds import tools # type: ignore @@ -10,9 +7,11 @@ from uds import tools # type: ignore # Inject local passed sp into globals for functions globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable + def execUdsRdp(udsrdp, port): import subprocess # @Reimport import os.path + params = [os.path.expandvars(i) for i in [udsrdp] + sp['as_new_xfreerdp_params'] + ['/v:127.0.0.1:{}'.format(port)]] # type: ignore tools.addTaskToWait(subprocess.Popen(params)) @@ -20,9 +19,11 @@ def execUdsRdp(udsrdp, port): def execNewXFreeRdp(xfreerdp, port): import subprocess # @Reimport import os.path + params = [os.path.expandvars(i) for i in [xfreerdp] + sp['as_new_xfreerdp_params'] + ['/v:127.0.0.1:{}'.format(port)]] # type: ignore tools.addTaskToWait(subprocess.Popen(params)) + # Try to locate a "valid" version of xfreerdp as first option (<1.1 does not allows drive redirections, so it will not be used if found) xfreerdp = tools.findApp('xfreerdp') udsrdp = tools.findApp('udsrdp') @@ -35,16 +36,20 @@ if udsrdp: fnc, app = execUdsRdp, udsrdp if app is None or fnc is None: - raise Exception('''You need to have installed xfreerdp (>= 1.1) or rdesktop, and have them in your PATH in order to connect to this UDS service.
+ raise Exception( + '''You need to have installed xfreerdp (>= 1.1) or rdesktop, and have them in your PATH in order to connect to this UDS service.
Please, install apropiate package for your system.
Also note that xfreerdp prior to version 1.1 will not be taken into consideration.
-''') +''' + ) else: # Open tunnel - fs = forward(remote=(sp['tunHost'], int(sp['tunPort'])), ticket=sp['ticket'], timeout=sp['tunWait'], check_certificate=sp['tunChk']) # type: ignore + fs = forward(remote=(sp['tunHost'], int(sp['tunPort'])), ticket=sp['ticket'], timeout=sp['tunWait'], check_certificate=sp['tunChk']) # type: ignore # Check that tunnel works.. if fs.check() is False: - raise Exception('Could not connect to tunnel server.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server.
Please, check your network settings.
' + ) fnc(app, fs.server_address[1]) diff --git a/server/src/uds/transports/RDP/scripts/macosx/direct.py b/server/src/uds/transports/RDP/scripts/macosx/direct.py index 1234bb13..101a221f 100644 --- a/server/src/uds/transports/RDP/scripts/macosx/direct.py +++ b/server/src/uds/transports/RDP/scripts/macosx/direct.py @@ -1,7 +1,3 @@ -# This is a template -# Saved as .py for easier editing -from __future__ import unicode_literals - # pylint: disable=import-error, no-name-in-module, too-many-format-args, undefined-variable, invalid-sequence-index import subprocess import shutil @@ -13,21 +9,32 @@ from uds import tools # type: ignore # Inject local passed sp into globals for functions globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable -msrdc = '/Applications/Microsoft Remote Desktop.app/Contents/MacOS/Microsoft Remote Desktop' +msrdc = ( + '/Applications/Microsoft Remote Desktop.app/Contents/MacOS/Microsoft Remote Desktop' +) xfreerdp = tools.findApp('xfreerdp') executable = None + def fixResolution(): import re import subprocess - results = str(subprocess.Popen(['system_profiler SPDisplaysDataType'],stdout=subprocess.PIPE, shell=True).communicate()[0]) + + results = str( + subprocess.Popen( + ['system_profiler SPDisplaysDataType'], stdout=subprocess.PIPE, shell=True + ).communicate()[0] + ) groups = re.search(r': \d* x \d*', results) width, height = '1024', '768' # Safe default values if groups: res = groups.group(0).split(' ') - width, height = str(int(res[1])-4), str(int(int(res[3])*90/100)) # Width and Height + width, height = str(int(res[1]) - 4), str( + int(int(res[3]) * 90 / 100) + ) # Width and Height return list(map(lambda x: x.replace('#WIDTH#', width).replace('#HEIGHT#', height), sp['as_new_xfreerdp_params'])) # type: ignore + # Check first xfreerdp, allow password redir if xfreerdp and os.path.isfile(xfreerdp): executable = xfreerdp @@ -36,7 +43,8 @@ elif msrdc and os.path.isfile(msrdc) and sp['as_file']: # type: ignore if executable is None: if sp['as_file']: # type: ignore - raise Exception('''Microsoft Remote Desktop or xfreerdp not found
+ raise Exception( + '''Microsoft Remote Desktop or xfreerdp not found
In order to connect to UDS RDP Sessions, you need to have a
Xfreerdp from homebrew
xfreerdp not found
+ raise Exception( + '''xfreerdp not found
In order to connect to UDS RDP Sessions, you need to have a
Microsoft Remote Desktop or xfreerdp not found
+ raise Exception( + '''Microsoft Remote Desktop or xfreerdp not found
In order to connect to UDS RDP Sessions, you need to have a
Xfreerdp from homebrew
xfreerdp not found
+ raise Exception( + '''xfreerdp not found
In order to connect to UDS RDP Sessions, you need to have a
Could not connect to tunnel server.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server.
Please, check your network settings.
' + ) if executable == msrdc: - theFile = theFile = sp['as_file'].format( # type: ignore - address=address - ) + theFile = theFile = sp['as_file'].format(address=address) # type: ignore filename = tools.saveTempFile(theFile) # Rename as .rdp, so open recognizes it @@ -89,7 +103,16 @@ if executable == msrdc: # tools.addTaskToWait(subprocess.Popen(['open', filename + '.rdp'])) # Force MSRDP to be used with -a (thanks to Dani Torregrosa @danitorregrosa (https://github.com/danitorregrosa) ) - tools.addTaskToWait(subprocess.Popen(['open', '-a', '/Applications/Microsoft Remote Desktop.app', filename + '.rdp'])) + tools.addTaskToWait( + subprocess.Popen( + [ + 'open', + '-a', + '/Applications/Microsoft Remote Desktop.app', + filename + '.rdp', + ] + ) + ) tools.addFileToUnlink(filename + '.rdp') elif executable == xfreerdp: # Fix resolution... @@ -98,6 +121,8 @@ elif executable == xfreerdp: except Exception as e: xfparms = list(map(lambda x: x.replace('#WIDTH#', '1400').replace('#HEIGHT#', '800'), sp['as_new_xfreerdp_params'])) # type: ignore - params = [os.path.expandvars(i) for i in [executable] + xfparms + ['/v:{}'.format(address)]] + params = [ + os.path.expandvars(i) + for i in [executable] + xfparms + ['/v:{}'.format(address)] + ] subprocess.Popen(params) - diff --git a/server/src/uds/transports/RDP/scripts/windows/direct.py b/server/src/uds/transports/RDP/scripts/windows/direct.py index ff511ebe..fb572268 100644 --- a/server/src/uds/transports/RDP/scripts/windows/direct.py +++ b/server/src/uds/transports/RDP/scripts/windows/direct.py @@ -13,13 +13,22 @@ from uds import tools # type: ignore thePass = sp['password'].encode('UTF-16LE') # type: ignore try: - password = codecs.encode(win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01), 'hex').decode() + password = codecs.encode( + win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01), 'hex' + ).decode() except Exception: # logger.info('Cannot encrypt for user, trying for machine') - password = codecs.encode(win32crypt.CryptProtectData(thePass, None, None, None, None, 0x05), 'hex').decode() + password = codecs.encode( + win32crypt.CryptProtectData(thePass, None, None, None, None, 0x05), 'hex' + ).decode() try: - key = wreg.OpenKey(wreg.HKEY_CURRENT_USER, 'Software\\Microsoft\\Terminal Server Client\\LocalDevices', 0, wreg.KEY_SET_VALUE) + key = wreg.OpenKey( + wreg.HKEY_CURRENT_USER, + 'Software\\Microsoft\\Terminal Server Client\\LocalDevices', + 0, + wreg.KEY_SET_VALUE, + ) wreg.SetValueEx(key, sp['ip'], 0, wreg.REG_DWORD, 255) # type: ignore wreg.CloseKey(key) except Exception as e: @@ -27,15 +36,14 @@ except Exception as e: pass # Key does not exists, ok... # The password must be encoded, to be included in a .rdp file, as 'UTF-16LE' before protecting (CtrpyProtectData) it in order to work with mstsc -theFile = sp['as_file'].format( # type: ignore - password=password -) +theFile = sp['as_file'].format(password=password) # type: ignore filename = tools.saveTempFile(theFile) executable = tools.findApp('mstsc.exe') if executable is None: - raise Exception('Unable to find mstsc.exe. Check that path points to your SYSTEM32 folder') + raise Exception( + 'Unable to find mstsc.exe. Check that path points to your SYSTEM32 folder' + ) subprocess.Popen([executable, filename]) tools.addFileToUnlink(filename) - diff --git a/server/src/uds/transports/RDP/scripts/windows/tunnel.py b/server/src/uds/transports/RDP/scripts/windows/tunnel.py index a71f821c..7b1902d8 100644 --- a/server/src/uds/transports/RDP/scripts/windows/tunnel.py +++ b/server/src/uds/transports/RDP/scripts/windows/tunnel.py @@ -16,29 +16,41 @@ fs = forward(remote=(sp['tunHost'], int(sp['tunPort'])), ticket=sp['ticket'], ti # Check that tunnel works.. if fs.check() is False: - raise Exception('Could not connect to tunnel server.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server.
Please, check your network settings.
' + ) thePass = sp['password'].encode('UTF-16LE') # type: ignore try: - password = codecs.encode(win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01), 'hex').decode() + password = codecs.encode( + win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01), 'hex' + ).decode() except Exception: # Cannot encrypt for user, trying for machine - password = codecs.encode(win32crypt.CryptProtectData(thePass, None, None, None, None, 0x05), 'hex').decode() + password = codecs.encode( + win32crypt.CryptProtectData(thePass, None, None, None, None, 0x05), 'hex' + ).decode() # The password must be encoded, to be included in a .rdp file, as 'UTF-16LE' before protecting (CtrpyProtectData) it in order to work with mstsc theFile = sp['as_file'].format( # type: ignore - password=password, - address='127.0.0.1:{}'.format(fs.server_address[1]) + password=password, address='127.0.0.1:{}'.format(fs.server_address[1]) ) filename = tools.saveTempFile(theFile) executable = tools.findApp('mstsc.exe') if executable is None: - raise Exception('Unable to find mstsc.exe. Check that path points to your SYSTEM32 folder') + raise Exception( + 'Unable to find mstsc.exe. Check that path points to your SYSTEM32 folder' + ) try: - key = wreg.OpenKey(wreg.HKEY_CURRENT_USER, 'Software\\Microsoft\\Terminal Server Client\\LocalDevices', 0, wreg.KEY_SET_VALUE) + key = wreg.OpenKey( + wreg.HKEY_CURRENT_USER, + 'Software\\Microsoft\\Terminal Server Client\\LocalDevices', + 0, + wreg.KEY_SET_VALUE, + ) wreg.SetValueEx(key, '127.0.0.1', 0, wreg.REG_DWORD, 255) # type: ignore wreg.CloseKey(key) except Exception as e: diff --git a/server/src/uds/transports/SPICE/remote_viewer_file.py b/server/src/uds/transports/SPICE/remote_viewer_file.py index 3c6a6035..f9a48571 100644 --- a/server/src/uds/transports/SPICE/remote_viewer_file.py +++ b/server/src/uds/transports/SPICE/remote_viewer_file.py @@ -67,15 +67,15 @@ class RemoteViewerFile: delete_file: bool = True def __init__( - self, - host: str, - port: str, - tls_port: str, - password: str, - ca: str, - host_subject: str, - fullscreen: bool = False - ): + self, + host: str, + port: str, + tls_port: str, + password: str, + ca: str, + host_subject: str, + fullscreen: bool = False, + ): self.host = host self.port = port self.tls_port = tls_port @@ -102,7 +102,9 @@ class RemoteViewerFile: usb_auto_share = '01'[self.usb_auto_share] new_usb_auto_share = '01'[self.new_usb_auto_share] - ca = self.ca.strip().replace('\n', '\\n') # So we get '\\n' and script works fine after replacement + ca = self.ca.strip().replace( + '\n', '\\n' + ) # So we get '\\n' and script works fine after replacement return TEMPLATE.format( type=self.connectionType, @@ -118,5 +120,7 @@ class RemoteViewerFile: delete_file=delete_file, host_subject=self.host_subject if tls_port != '-1' else '', ca=ca if tls_port != '-1' else '', - secure_channel='secure-channels=main;inputs;cursor;playback;record;display;usbredir;smartcard' if tls_port != '-1' else '' + secure_channel='secure-channels=main;inputs;cursor;playback;record;display;usbredir;smartcard' + if tls_port != '-1' + else '', ) diff --git a/server/src/uds/transports/SPICE/scripts/linux/direct.py b/server/src/uds/transports/SPICE/scripts/linux/direct.py index d97b5131..62e52732 100644 --- a/server/src/uds/transports/SPICE/scripts/linux/direct.py +++ b/server/src/uds/transports/SPICE/scripts/linux/direct.py @@ -10,11 +10,13 @@ from uds import tools # type: ignore executable = tools.findApp('remote-viewer') if executable is None: - raise Exception('''You need to have installed virt-viewer to connect to this UDS service.
+ raise Exception( + '''You need to have installed virt-viewer to connect to this UDS service.
Please, install appropriate package for your Linux system. (probably named something like remote-viewer)
-''') +''' + ) theFile = sp['as_file'] # type: ignore diff --git a/server/src/uds/transports/SPICE/scripts/linux/tunnel.py b/server/src/uds/transports/SPICE/scripts/linux/tunnel.py index 6c879aae..1bb1e5db 100644 --- a/server/src/uds/transports/SPICE/scripts/linux/tunnel.py +++ b/server/src/uds/transports/SPICE/scripts/linux/tunnel.py @@ -11,14 +11,16 @@ from uds.tunnel import forward # type: ignore executable = tools.findApp('remote-viewer') if executable is None: - raise Exception('''You need to have installed virt-viewer to connect to this UDS service.
+ raise Exception( + '''You need to have installed virt-viewer to connect to this UDS service.
Please, install appropriate package for your system.
Please, install appropriate package for your Linux system. (probably named something like virt-viewer)
-''') +''' + ) theFile = sp['as_file_ns'] # type: ignore @@ -29,7 +31,9 @@ if sp['ticket']: # type: ignore # Check that tunnel works.. if fs.check() is False: - raise Exception('Could not connect to tunnel server.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server.
Please, check your network settings.
' + ) fss = None if sp['ticket_secure']: # type: ignore @@ -38,11 +42,13 @@ if sp['ticket_secure']: # type: ignore # Check that tunnel works.. if fss.check() is False: - raise Exception('Could not connect to tunnel server 2.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server 2.
Please, check your network settings.
' + ) theFile = theFile.format( secure_port='-1' if not fss else fss.server_address[1], - port='-1' if not fs else fs.server_address[1] + port='-1' if not fs else fs.server_address[1], ) filename = tools.saveTempFile(theFile) diff --git a/server/src/uds/transports/SPICE/scripts/macosx/direct.py b/server/src/uds/transports/SPICE/scripts/macosx/direct.py index a50dae5a..3f601b96 100644 --- a/server/src/uds/transports/SPICE/scripts/macosx/direct.py +++ b/server/src/uds/transports/SPICE/scripts/macosx/direct.py @@ -11,7 +11,8 @@ from uds import tools # type: ignore remoteViewer = '/Applications/RemoteViewer.app/Contents/MacOS/RemoteViewer' if not os.path.isfile(remoteViewer): - raise Exception('''You need to have installed virt-viewer to connect to this UDS service.
+ raise Exception( + '''You need to have installed virt-viewer to connect to this UDS service.
Please, install appropriate package for your system.
@@ -22,7 +23,8 @@ if not os.path.isfile(remoteViewer): Please, note that in order to UDS Connector to work correctly, you must copy the Remote Viewer app to your Applications Folder.You need to have installed virt-viewer to connect to this UDS service.
+ raise Exception( + '''You need to have installed virt-viewer to connect to this UDS service.
Please, install appropriate package for your system.
@@ -23,7 +24,8 @@ if not os.path.isfile(remoteViewer): Please, note that in order to UDS Connector to work correctly, you must copy the Remote Viewer app to your Applications Folder.Could not connect to tunnel server.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server.
Please, check your network settings.
' + ) fss = None if sp['ticket_secure']: # type: ignore @@ -42,11 +46,13 @@ if sp['ticket_secure']: # type: ignore # Check that tunnel works.. if fss.check() is False: - raise Exception('Could not connect to tunnel server 2.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server 2.
Please, check your network settings.
' + ) theFile = theFile.format( secure_port='-1' if not fss else fss.server_address[1], - port='-1' if not fs else fs.server_address[1] + port='-1' if not fs else fs.server_address[1], ) filename = tools.saveTempFile(theFile) diff --git a/server/src/uds/transports/SPICE/scripts/windows/direct.py b/server/src/uds/transports/SPICE/scripts/windows/direct.py index b76b8c41..446b0594 100644 --- a/server/src/uds/transports/SPICE/scripts/windows/direct.py +++ b/server/src/uds/transports/SPICE/scripts/windows/direct.py @@ -19,14 +19,16 @@ for env in ('PROGRAMFILES', 'PROGRAMW6432'): executable = tools.findApp('remote-viewer.exe', extraPaths) if executable is None: - raise Exception('''You need to have installed virt-viewer to connect to this UDS service.
+ raise Exception( + '''You need to have installed virt-viewer to connect to this UDS service.
Please, install appropriate package for your system.
-''') +''' + ) theFile = sp['as_file'] # type: ignore diff --git a/server/src/uds/transports/SPICE/scripts/windows/tunnel.py b/server/src/uds/transports/SPICE/scripts/windows/tunnel.py index 3a5a487c..16dcb503 100644 --- a/server/src/uds/transports/SPICE/scripts/windows/tunnel.py +++ b/server/src/uds/transports/SPICE/scripts/windows/tunnel.py @@ -20,14 +20,16 @@ for env in ('PROGRAMFILES', 'PROGRAMW6432'): executable = tools.findApp('remote-viewer.exe', extraPaths) if executable is None: - raise Exception('''You need to have installed virt-viewer to connect to this UDS service.
+ raise Exception( + '''You need to have installed virt-viewer to connect to this UDS service.
Please, install appropriate package for your system.
-''') +''' + ) theFile = sp['as_file_ns'] # type: ignore fs = None if sp['ticket']: # type: ignore @@ -36,7 +38,9 @@ if sp['ticket']: # type: ignore # Check that tunnel works.. if fs.check() is False: - raise Exception('Could not connect to tunnel server.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server.
Please, check your network settings.
' + ) fss = None if sp['ticket_secure']: # type: ignore @@ -45,11 +49,13 @@ if sp['ticket_secure']: # type: ignore # Check that tunnel works.. if fss.check() is False: - raise Exception('Could not connect to tunnel server 2.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server 2.
Please, check your network settings.
' + ) theFile = theFile.format( secure_port='-1' if not fss else fss.server_address[1], - port='-1' if not fs else fs.server_address[1] + port='-1' if not fs else fs.server_address[1], ) filename = tools.saveTempFile(theFile) diff --git a/server/src/uds/transports/SPICE/spice.py b/server/src/uds/transports/SPICE/spice.py index c36a6eac..0b15dc73 100644 --- a/server/src/uds/transports/SPICE/spice.py +++ b/server/src/uds/transports/SPICE/spice.py @@ -51,6 +51,7 @@ class SPICETransport(BaseSpiceTransport): Provides access via SPICE 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 = _('SPICE') typeType = 'SPICETransport' typeDescription = _('SPICE Protocol. Direct connection.') @@ -65,15 +66,15 @@ class SPICETransport(BaseSpiceTransport): smartCardRedirect = BaseSpiceTransport.smartCardRedirect def getUDSTransportScript( # 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' - ) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]: + self, + userService: 'models.UserService', + transport: 'models.Transport', + ip: str, + os: typing.Dict[str, str], + user: 'models.User', + password: str, + request: 'HttpRequest', + ) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]: userServiceInstance: typing.Any = userService.getInstance() con = userServiceInstance.getConsoleConnection() @@ -85,7 +86,15 @@ class SPICETransport(BaseSpiceTransport): port: str = con['port'] or '-1' secure_port: str = con['secure_port'] or '-1' - r = RemoteViewerFile(con['address'], port, secure_port, con['ticket']['value'], self.serverCertificate.value, con['cert_subject'], fullscreen=self.fullScreen.isTrue()) + r = RemoteViewerFile( + con['address'], + port, + secure_port, + con['ticket']['value'], + self.serverCertificate.value, + con['cert_subject'], + fullscreen=self.fullScreen.isTrue(), + ) r.usb_auto_share = self.usbShare.isTrue() r.new_usb_auto_share = self.autoNewUsbShare.isTrue() r.smartcard = self.smartCardRedirect.isTrue() @@ -93,11 +102,13 @@ class SPICETransport(BaseSpiceTransport): osName = { OsDetector.Windows: 'windows', OsDetector.Linux: 'linux', - OsDetector.Macintosh: 'macosx' + OsDetector.Macintosh: 'macosx', }.get(os['OS']) if osName is None: - return super().getUDSTransportScript(userService, transport, ip, os, user, password, request) + return super().getUDSTransportScript( + userService, transport, ip, os, user, password, request + ) # if sso: # If SSO requested, and when supported by platform # userServiceInstance.desktopLogin(user, password, '') diff --git a/server/src/uds/transports/SPICE/spice_base.py b/server/src/uds/transports/SPICE/spice_base.py index eb6fcd62..005ff65c 100644 --- a/server/src/uds/transports/SPICE/spice_base.py +++ b/server/src/uds/transports/SPICE/spice_base.py @@ -54,6 +54,7 @@ class BaseSpiceTransport(transports.Transport): Provides access via SPICE 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 """ + iconFile = 'spice.png' protocol = protocols.SPICE @@ -61,54 +62,56 @@ class BaseSpiceTransport(transports.Transport): order=1, label=_('Empty credentials'), tooltip=_('If checked, the credentials used to connect will be emtpy'), - tab=gui.CREDENTIALS_TAB + tab=gui.CREDENTIALS_TAB, ) fixedName = gui.TextField( order=2, label=_('Username'), tooltip=_('If not empty, this username will be always used as credential'), - tab=gui.CREDENTIALS_TAB + tab=gui.CREDENTIALS_TAB, ) fixedPassword = gui.PasswordField( order=3, label=_('Password'), tooltip=_('If not empty, this password will be always used as credential'), - tab=gui.CREDENTIALS_TAB + tab=gui.CREDENTIALS_TAB, ) serverCertificate = gui.TextField( order=4, length=4096, multiline=4, label=_('Certificate'), - tooltip=_('Server certificate (public), can be found on your ovirt engine, probably at /etc/pki/ovirt-engine/certs/ca.der (Use the contents of this file).'), - required=False + tooltip=_( + 'Server certificate (public), can be found on your ovirt engine, probably at /etc/pki/ovirt-engine/certs/ca.der (Use the contents of this file).' + ), + required=False, ) fullScreen = gui.CheckBoxField( order=5, label=_('Fullscreen Mode'), tooltip=_('If checked, viewer will be shown on fullscreen mode-'), - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) smartCardRedirect = gui.CheckBoxField( order=6, label=_('Smartcard Redirect'), tooltip=_('If checked, SPICE protocol will allow smartcard redirection.'), defvalue=gui.FALSE, - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) usbShare = gui.CheckBoxField( order=7, label=_('Enable USB'), tooltip=_('If checked, USB redirection will be allowed.'), defvalue=gui.FALSE, - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) autoNewUsbShare = gui.CheckBoxField( order=8, label=_('New USB Auto Sharing'), tooltip=_('Auto-redirect USB devices when plugged in.'), defvalue=gui.FALSE, - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool: @@ -117,7 +120,9 @@ class BaseSpiceTransport(transports.Transport): """ ready = self.cache.get(ip) if ready is None: - userServiceInstance: typing.Any = userService.getInstance() # Disable mypy checks on this + userServiceInstance: typing.Any = ( + userService.getInstance() + ) # Disable mypy checks on this con = userServiceInstance.getConsoleConnection() logger.debug('Connection data: %s', con) @@ -130,13 +135,19 @@ class BaseSpiceTransport(transports.Transport): # test ANY of the ports port_to_test = port if port != -1 else secure_port if port_to_test == -1: - self.cache.put('cachedMsg', 'Could not find the PORT for connection', 120) # Write a message, that will be used from getCustom + self.cache.put( + 'cachedMsg', 'Could not find the PORT for connection', 120 + ) # Write a message, that will be used from getCustom logger.info('SPICE didn\'t find has any port: %s', con) return False - self.cache.put('cachedMsg', - 'Could not reach server "{}" on port "{}" from broker (prob. causes are name resolution & firewall rules)'.format(con['address'], port_to_test), - 120) + self.cache.put( + 'cachedMsg', + 'Could not reach server "{}" on port "{}" from broker (prob. causes are name resolution & firewall rules)'.format( + con['address'], port_to_test + ), + 120, + ) if self.testServer(userService, con['address'], port_to_test) is True: self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT) @@ -144,17 +155,25 @@ class BaseSpiceTransport(transports.Transport): return ready == 'Y' - def getCustomAvailableErrorMsg(self, userService: 'models.UserService', ip: str) -> str: + def getCustomAvailableErrorMsg( + self, userService: 'models.UserService', ip: str + ) -> str: msg = self.cache.get('cachedMsg') if msg is None: - return transports.Transport.getCustomAvailableErrorMsg(self, userService, ip) + return transports.Transport.getCustomAvailableErrorMsg( + self, userService, ip + ) return msg - def processedUser(self, userService: 'models.UserService', user: 'models.User') -> str: + def processedUser( + self, userService: 'models.UserService', user: 'models.User' + ) -> str: v = self.processUserPassword(userService, user, '') return v['username'] - def processUserPassword(self, userService: 'models.UserService', user: 'models.User', password: str) -> typing.Dict[str, str]: + def processUserPassword( + self, userService: typing.Union['models.UserService', 'models.ServicePool'], user: 'models.User', password: str + ) -> typing.Dict[str, str]: username = user.getUsernameForAuth() if self.fixedName.value: @@ -172,19 +191,23 @@ class BaseSpiceTransport(transports.Transport): return {'protocol': self.protocol, 'username': username, 'password': password} def getConnectionInfo( - self, - userService: typing.Union['models.UserService', 'models.ServicePool'], - user: 'models.User', - password: str - ) -> typing.Dict[str, str]: + self, + userService: typing.Union['models.UserService', 'models.ServicePool'], + user: 'models.User', + password: str, + ) -> typing.Dict[str, str]: return self.processUserPassword(userService, user, password) - def getScript(self, scriptNameTemplate: str, osName: str, params: typing.Dict[str, typing.Any]) -> typing.Tuple[str, str, typing.Dict[str, typing.Any]]: + def getScript( + self, scriptNameTemplate: str, osName: str, params: typing.Dict[str, typing.Any] + ) -> typing.Tuple[str, str, typing.Dict[str, typing.Any]]: # Reads script scriptNameTemplate = scriptNameTemplate.format(osName) with open(os.path.join(os.path.dirname(__file__), scriptNameTemplate)) as f: script = f.read() # Reads signature - with open(os.path.join(os.path.dirname(__file__), scriptNameTemplate + '.signature')) as f: + with open( + os.path.join(os.path.dirname(__file__), scriptNameTemplate + '.signature') + ) as f: signature = f.read() return script, signature, params diff --git a/server/src/uds/transports/X2GO/scripts/authorize.py b/server/src/uds/transports/X2GO/scripts/authorize.py index 55d4db09..b585b971 100644 --- a/server/src/uds/transports/X2GO/scripts/authorize.py +++ b/server/src/uds/transports/X2GO/scripts/authorize.py @@ -1,10 +1,10 @@ +# may be executed on old python version from __future__ import unicode_literals import sys import os import errno import pwd -import six USER = '__USER__' KEY = '__KEY__' diff --git a/server/src/uds/transports/X2GO/scripts/linux/direct.py b/server/src/uds/transports/X2GO/scripts/linux/direct.py index 3bdaa088..404d1341 100644 --- a/server/src/uds/transports/X2GO/scripts/linux/direct.py +++ b/server/src/uds/transports/X2GO/scripts/linux/direct.py @@ -17,9 +17,21 @@ filename = tools.saveTempFile(theFile) executable = tools.findApp('x2goclient') if executable is None: - raise Exception('''You must have installed latest X2GO Client in order to connect to this UDS service.
-Please, install the required packages for your platform
''') + raise Exception( + '''You must have installed latest X2GO Client in order to connect to this UDS service.
+Please, install the required packages for your platform
''' + ) -subprocess.Popen([executable, '--session-conf={}'.format(filename), '--session=UDS/connect', '--close-disconnect', '--hide', '--no-menu', '--add-to-known-hosts']) +subprocess.Popen( + [ + executable, + '--session-conf={}'.format(filename), + '--session=UDS/connect', + '--close-disconnect', + '--hide', + '--no-menu', + '--add-to-known-hosts', + ] +) # tools.addFileToUnlink(filename) # tools.addFileToUnlink(keyFile) diff --git a/server/src/uds/transports/X2GO/scripts/linux/tunnel.py b/server/src/uds/transports/X2GO/scripts/linux/tunnel.py index 3419f1cc..4c348461 100644 --- a/server/src/uds/transports/X2GO/scripts/linux/tunnel.py +++ b/server/src/uds/transports/X2GO/scripts/linux/tunnel.py @@ -15,7 +15,9 @@ fs = forward(remote=(sp['tunHost'], int(sp['tunPort'])), ticket=sp['ticket'], ti # Check that tunnel works.. if fs.check() is False: - raise Exception('Could not connect to tunnel server.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server.
Please, check your network settings.
' + ) home = expanduser('~') + ':1;/media:1;' keyFile = tools.saveTempFile(sp['key']) # type: ignore @@ -26,7 +28,19 @@ filename = tools.saveTempFile(theFile) executable = tools.findApp('x2goclient') if executable is None: - raise Exception('''You must have installed latest X2GO Client in order to connect to this UDS service.
-Please, install the required packages for your platform
''') + raise Exception( + '''You must have installed latest X2GO Client in order to connect to this UDS service.
+Please, install the required packages for your platform
''' + ) -subprocess.Popen([executable, '--session-conf={}'.format(filename), '--session=UDS/connect', '--close-disconnect', '--hide', '--no-menu', '--add-to-known-hosts']) +subprocess.Popen( + [ + executable, + '--session-conf={}'.format(filename), + '--session=UDS/connect', + '--close-disconnect', + '--hide', + '--no-menu', + '--add-to-known-hosts', + ] +) diff --git a/server/src/uds/transports/X2GO/scripts/windows/direct.py b/server/src/uds/transports/X2GO/scripts/windows/direct.py index 0a7046fc..71b63842 100644 --- a/server/src/uds/transports/X2GO/scripts/windows/direct.py +++ b/server/src/uds/transports/X2GO/scripts/windows/direct.py @@ -18,11 +18,23 @@ filename = tools.saveTempFile(theFile) x2goPath = os.environ['PROGRAMFILES(X86)'] + '\\x2goclient' executable = tools.findApp('x2goclient.exe', [x2goPath]) if executable is None: - raise Exception('''You must have installed latest X2GO Client in order to connect to this UDS service.
-You can download it for windows from X2Go Site.
''') + raise Exception( + '''You must have installed latest X2GO Client in order to connect to this UDS service.
+You can download it for windows from X2Go Site.
''' + ) # C:\Program Files (x86)\\x2goclient>x2goclient.exe --session-conf=c:/temp/sessions --session=UDS/test-session --close-disconnect --hide --no-menu -subprocess.Popen([executable, '--session-conf={}'.format(filename), '--session=UDS/connect', '--close-disconnect', '--hide', '--no-menu', '--add-to-known-hosts']) +subprocess.Popen( + [ + executable, + '--session-conf={}'.format(filename), + '--session=UDS/connect', + '--close-disconnect', + '--hide', + '--no-menu', + '--add-to-known-hosts', + ] +) # tools.addFileToUnlink(filename) # tools.addFileToUnlink(keyFile) diff --git a/server/src/uds/transports/X2GO/scripts/windows/tunnel.py b/server/src/uds/transports/X2GO/scripts/windows/tunnel.py index 8dc404b4..b7b79750 100644 --- a/server/src/uds/transports/X2GO/scripts/windows/tunnel.py +++ b/server/src/uds/transports/X2GO/scripts/windows/tunnel.py @@ -1,6 +1,6 @@ # This is a template # Saved as .py for easier editing -#from __future__ import unicode_literals +# from __future__ import unicode_literals # pylint: disable=import-error, no-name-in-module, too-many-format-args, undefined-variable @@ -16,7 +16,9 @@ fs = forward(remote=(sp['tunHost'], int(sp['tunPort'])), ticket=sp['ticket'], ti # Check that tunnel works.. if fs.check() is False: - raise Exception('Could not connect to tunnel server.
Please, check your network settings.
') + raise Exception( + 'Could not connect to tunnel server.
Please, check your network settings.
' + ) # Care, expanduser is encoding using "mcbs", so treat it as bytes on python 2.7 home = expanduser('~').replace('\\', '\\\\') + '#1;' @@ -27,7 +29,19 @@ filename = tools.saveTempFile(theFile) x2goPath = os.environ['PROGRAMFILES(X86)'] + '\\x2goclient' executable = tools.findApp('x2goclient.exe', [x2goPath]) if executable is None: - raise Exception('''You must have installed latest X2GO Client in default program file folder in order to connect to this UDS service.
-You can download it for windows from X2Go Site.
''') + raise Exception( + '''You must have installed latest X2GO Client in default program file folder in order to connect to this UDS service.
+You can download it for windows from X2Go Site.
''' + ) -subprocess.Popen([executable, '--session-conf={}'.format(filename), '--session=UDS/connect', '--close-disconnect', '--hide', '--no-menu', '--add-to-known-hosts']) +subprocess.Popen( + [ + executable, + '--session-conf={}'.format(filename), + '--session=UDS/connect', + '--close-disconnect', + '--hide', + '--no-menu', + '--add-to-known-hosts', + ] +) diff --git a/server/src/uds/transports/X2GO/x2go.py b/server/src/uds/transports/X2GO/x2go.py index 6c1f881b..c9aedf1b 100644 --- a/server/src/uds/transports/X2GO/x2go.py +++ b/server/src/uds/transports/X2GO/x2go.py @@ -51,6 +51,7 @@ class X2GOTransport(BaseX2GOTransport): Provides access via X2GO 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 = _('X2Go') typeType = 'X2GOTransport' typeDescription = _('X2Go access (Experimental). Direct connection.') @@ -69,15 +70,15 @@ class X2GOTransport(BaseX2GOTransport): quality = BaseX2GOTransport.quality def getUDSTransportScript( # 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' - ) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]: + self, + userService: 'models.UserService', + transport: 'models.Transport', + ip: str, + os: typing.Dict[str, str], + user: 'models.User', + password: str, + request: 'HttpRequest', + ) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]: ci = self.getConnectionInfo(userService, user, password) username = ci['username'] @@ -101,7 +102,7 @@ class X2GOTransport(BaseX2GOTransport): rootless=rootless, width=width, height=height, - user=username + user=username, ) osName = { @@ -111,13 +112,10 @@ class X2GOTransport(BaseX2GOTransport): }.get(os['OS']) if osName is None: - return super().getUDSTransportScript(userService, transport, ip, os, user, password, request) + return super().getUDSTransportScript( + userService, transport, ip, os, user, password, request + ) - sp = { - 'ip': ip, - 'port': '22', - 'key': priv, - 'xf': xf - } + sp = {'ip': ip, 'port': '22', 'key': priv, 'xf': xf} return self.getScript('scripts/{}/direct.py', osName, sp) diff --git a/server/src/uds/transports/X2GO/x2go_base.py b/server/src/uds/transports/X2GO/x2go_base.py index 10b65872..0f474d27 100644 --- a/server/src/uds/transports/X2GO/x2go_base.py +++ b/server/src/uds/transports/X2GO/x2go_base.py @@ -60,6 +60,7 @@ class BaseX2GOTransport(transports.Transport): Provides access via X2GO 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 """ + iconFile = 'x2go.png' protocol = transports.protocols.X2GO supportedOss = (OsDetector.Linux, OsDetector.Windows) @@ -68,7 +69,7 @@ class BaseX2GOTransport(transports.Transport): order=2, label=_('Username'), tooltip=_('If not empty, this username will be always used as credential'), - tab=gui.CREDENTIALS_TAB + tab=gui.CREDENTIALS_TAB, ) screenSize = gui.ChoiceField( @@ -82,9 +83,9 @@ class BaseX2GOTransport(transports.Transport): {'id': CommonPrefs.SZ_1024x768, 'text': '1024x768'}, {'id': CommonPrefs.SZ_1366x768, 'text': '1366x768'}, {'id': CommonPrefs.SZ_1920x1080, 'text': '1920x1080'}, - {'id': CommonPrefs.SZ_FULLSCREEN, 'text': ugettext_lazy('Full Screen')} + {'id': CommonPrefs.SZ_FULLSCREEN, 'text': ugettext_lazy('Full Screen')}, ], - tab=gui.PARAMETERS_TAB + tab=gui.PARAMETERS_TAB, ) desktopType = gui.ChoiceField( @@ -102,14 +103,16 @@ class BaseX2GOTransport(transports.Transport): {'id': 'gnome-session-cinnamon2d', 'text': 'Cinnamon 2.2 (see docs)'}, {'id': 'UDSVAPP', 'text': 'UDS vAPP'}, ], - tab=gui.PARAMETERS_TAB + tab=gui.PARAMETERS_TAB, ) customCmd = gui.TextField( order=12, label=_('vAPP'), - tooltip=_('If UDS vAPP is selected as "Desktop", the FULL PATH of the app to be executed. If UDS vAPP is not selected, this field will be ignored.'), - tab=gui.PARAMETERS_TAB + tooltip=_( + 'If UDS vAPP is selected as "Desktop", the FULL PATH of the app to be executed. If UDS vAPP is not selected, this field will be ignored.' + ), + tab=gui.PARAMETERS_TAB, ) sound = gui.CheckBoxField( @@ -117,15 +120,17 @@ class BaseX2GOTransport(transports.Transport): label=_('Enable sound'), tooltip=_('If checked, sound will be available'), defvalue=gui.TRUE, - tab=gui.PARAMETERS_TAB + tab=gui.PARAMETERS_TAB, ) exports = gui.CheckBoxField( order=14, label=_('Redirect home folder'), - tooltip=_('If checked, user home folder will be redirected. (On linux, also redirects /media)'), + tooltip=_( + 'If checked, user home folder will be redirected. (On linux, also redirects /media)' + ), defvalue=gui.FALSE, - tab=gui.PARAMETERS_TAB + tab=gui.PARAMETERS_TAB, ) speed = gui.ChoiceField( @@ -140,7 +145,7 @@ class BaseX2GOTransport(transports.Transport): {'id': '3', 'text': 'WAN'}, {'id': '4', 'text': 'LAN'}, ], - tab=gui.PARAMETERS_TAB + tab=gui.PARAMETERS_TAB, ) soundType = gui.ChoiceField( @@ -152,7 +157,7 @@ class BaseX2GOTransport(transports.Transport): {'id': 'pulse', 'text': 'Pulse'}, {'id': 'esd', 'text': 'ESD'}, ], - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) keyboardLayout = gui.TextField( @@ -160,7 +165,7 @@ class BaseX2GOTransport(transports.Transport): order=31, tooltip=_('Keyboard layout (es, us, fr, ...). Empty value means autodetect.'), defvalue='', - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) # 'nopack', '8', '64', '256', '512', '4k', '32k', '64k', '256k', '2m', '16m' # '256-rdp', '256-rdp-compressed', '32k-rdp', '32k-rdp-compressed', '64k-rdp' @@ -180,7 +185,7 @@ class BaseX2GOTransport(transports.Transport): order=32, tooltip=_('Pack format. Change with care!'), defvalue='16m-jpeg', - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) quality = gui.NumericField( @@ -192,7 +197,7 @@ class BaseX2GOTransport(transports.Transport): minValue=1, maxValue=9, required=True, - tab=gui.ADVANCED_TAB + tab=gui.ADVANCED_TAB, ) def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool: @@ -213,11 +218,18 @@ class BaseX2GOTransport(transports.Transport): def getScreenSize(self) -> typing.Tuple[int, int]: return CommonPrefs.getWidthHeight(self.screenSize.value) - def processedUser(self, userService: 'models.UserService', user: 'models.User') -> str: + def processedUser( + self, userService: 'models.UserService', user: 'models.User' + ) -> str: v = self.processUserPassword(userService, user, '') return v['username'] - def processUserPassword(self, userService: 'models.UserService', user: 'models.User', password: str) -> typing.Dict[str, str]: + def processUserPassword( + self, + userService: typing.Union['models.UserService', 'models.ServicePool'], + user: 'models.User', + password: str, + ) -> typing.Dict[str, str]: username = user.getUsernameForAuth() if self.fixedName.value != '': @@ -229,11 +241,11 @@ class BaseX2GOTransport(transports.Transport): return {'protocol': self.protocol, 'username': username, 'password': ''} def getConnectionInfo( - self, - userService: typing.Union['models.UserService', 'models.ServicePool'], - user: 'models.User', - password: str - ) -> typing.Dict[str, str]: + self, + userService: typing.Union['models.UserService', 'models.ServicePool'], + user: 'models.User', + password: str, + ) -> typing.Dict[str, str]: return self.processUserPassword(userService, user, password) def genKeyPairForSsh(self) -> typing.Tuple[str, str]: @@ -264,18 +276,24 @@ class BaseX2GOTransport(transports.Transport): return data.replace('__USER__', user).replace('__KEY__', pubKey) - def getAndPushKey(self, userName: str, userService: 'models.UserService') -> typing.Tuple[str, str]: + def getAndPushKey( + self, userName: str, userService: 'models.UserService' + ) -> typing.Tuple[str, str]: priv, pub = self.genKeyPairForSsh() authScript = self.getAuthorizeScript(userName, pub) userServiceManager().sendScript(userService, authScript) return priv, pub - def getScript(self, scriptNameTemplate: str, osName: str, params: typing.Dict[str, typing.Any]) -> typing.Tuple[str, str, typing.Dict[str, typing.Any]]: + def getScript( + self, scriptNameTemplate: str, osName: str, params: typing.Dict[str, typing.Any] + ) -> typing.Tuple[str, str, typing.Dict[str, typing.Any]]: # Reads script scriptNameTemplate = scriptNameTemplate.format(osName) with open(os.path.join(os.path.dirname(__file__), scriptNameTemplate)) as f: script = f.read() # Reads signature - with open(os.path.join(os.path.dirname(__file__), scriptNameTemplate + '.signature')) as f: + with open( + os.path.join(os.path.dirname(__file__), scriptNameTemplate + '.signature') + ) as f: signature = f.read() return script, signature, params diff --git a/server/src/uds/transports/X2GO/x2go_file.py b/server/src/uds/transports/X2GO/x2go_file.py index 5101282d..0d0c0a55 100644 --- a/server/src/uds/transports/X2GO/x2go_file.py +++ b/server/src/uds/transports/X2GO/x2go_file.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2016-2019 Virtual Cable S.L. +# Copyright (c) 2016-2021 Virtual Cable S.L.U. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -12,7 +12,7 @@ # * 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 +# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # @@ -95,7 +95,19 @@ sshproxykrblogin=false ''' -def getTemplate(speed, pack, quality, sound, soundSystem, windowManager, exports, rootless, width, height, user): +def getTemplate( + speed, + pack, + quality, + sound, + soundSystem, + windowManager, + exports, + rootless, + width, + height, + user, +): trueFalse = lambda x: 'true' if x else 'false' export = 'export="{export}"' if exports else '' if width == -1 or height == -1: @@ -116,5 +128,5 @@ def getTemplate(speed, pack, quality, sound, soundSystem, windowManager, exports width=width, height=height, fullscreen=fullscreen, - user=user + user=user, ) diff --git a/server/src/uds/transports/X2GO/x2go_tunnel.py b/server/src/uds/transports/X2GO/x2go_tunnel.py index 6953ad54..72315300 100644 --- a/server/src/uds/transports/X2GO/x2go_tunnel.py +++ b/server/src/uds/transports/X2GO/x2go_tunnel.py @@ -96,7 +96,6 @@ class TX2GOTransport(BaseX2GOTransport): tab=gui.TUNNEL_TAB, ) - fixedName = BaseX2GOTransport.fixedName screenSize = BaseX2GOTransport.screenSize desktopType = BaseX2GOTransport.desktopType diff --git a/server/src/uds/transports/__init__.py b/server/src/uds/transports/__init__.py index c244537e..6d05c4ee 100644 --- a/server/src/uds/transports/__init__.py +++ b/server/src/uds/transports/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2012 Virtual Cable S.L. +# Copyright (c) 2012-2021 Virtual Cable S.L.U. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -12,7 +12,7 @@ # * 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 +# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # @@ -48,6 +48,7 @@ import sys logger = logging.getLogger(__name__) + def __init__(): """ This imports all packages that are descendant of this package, and, after that, @@ -60,7 +61,7 @@ def __init__(): for _, name, _ in pkgutil.iter_modules([pkgpath]): # __import__(name, globals(), locals(), [], 1) importlib.import_module('.' + name, __name__) # import module - + importlib.invalidate_caches() # This is marked as error in IDE, but it's not (__subclasses__)