forked from shaba/openuds
Formating and type fixing all transports
This commit is contained in:
parent
c72bcf4200
commit
3934f2b88d
@ -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
|
||||
)
|
||||
)
|
||||
|
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
)
|
||||
|
@ -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('''<p>You need to have installed xfreerdp (>= 1.1) or rdesktop, and have them in your PATH in order to connect to this UDS service.</p>
|
||||
raise Exception(
|
||||
'''<p>You need to have installed xfreerdp (>= 1.1) or rdesktop, and have them in your PATH in order to connect to this UDS service.</p>
|
||||
<p>Please, install the proper package for your system.</p>
|
||||
<p>Also note that xfreerdp prior to version 1.1 will not be taken into consideration.</p>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
else:
|
||||
fnc(app) # @UndefinedVariable
|
||||
|
@ -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('''<p>You need to have installed xfreerdp (>= 1.1) or rdesktop, and have them in your PATH in order to connect to this UDS service.</p>
|
||||
raise Exception(
|
||||
'''<p>You need to have installed xfreerdp (>= 1.1) or rdesktop, and have them in your PATH in order to connect to this UDS service.</p>
|
||||
<p>Please, install apropiate package for your system.</p>
|
||||
<p>Also note that xfreerdp prior to version 1.1 will not be taken into consideration.</p>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
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('<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
fnc(app, fs.server_address[1])
|
||||
|
@ -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('''<p><b>Microsoft Remote Desktop or xfreerdp not found</b></p>
|
||||
raise Exception(
|
||||
'''<p><b>Microsoft Remote Desktop or xfreerdp not found</b></p>
|
||||
<p>In order to connect to UDS RDP Sessions, you need to have a<p>
|
||||
<ul>
|
||||
<li>
|
||||
@ -46,9 +54,11 @@ if executable is None:
|
||||
<p><b>Xfreerdp</b> from homebrew</p>
|
||||
</li>
|
||||
</ul>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
else:
|
||||
raise Exception('''<p><b>xfreerdp not found</b></p>
|
||||
raise Exception(
|
||||
'''<p><b>xfreerdp not found</b></p>
|
||||
<p>In order to connect to UDS RDP Sessions, you need to have a<p>
|
||||
<ul>
|
||||
<li>
|
||||
@ -65,16 +75,26 @@ if executable is None:
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
elif executable == msrdc:
|
||||
theFile = sp['as_file'] # type: ignore
|
||||
filename = tools.saveTempFile(theFile)
|
||||
# Rename as .rdp, so open recognizes it
|
||||
shutil.move(filename, filename + '.rdp')
|
||||
|
||||
#tools.addTaskToWait(subprocess.Popen(['open', filename + '.rdp']))
|
||||
# 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...
|
||||
@ -85,4 +105,3 @@ elif executable == xfreerdp:
|
||||
|
||||
params = [os.path.expandvars(i) for i in [executable] + xfparms + ['/v:{}'.format(sp['address'])]] # type: ignore
|
||||
subprocess.Popen(params)
|
||||
|
||||
|
@ -15,19 +15,29 @@ from uds import tools # type: ignore
|
||||
# Inject local passed sp into globals for functions
|
||||
globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
@ -39,7 +49,8 @@ elif msrdc and os.path.isfile(msrdc) and sp['as_file']: # type: ignore
|
||||
|
||||
if executable is None:
|
||||
if sp['as_rdp_url']: # type: ignore
|
||||
raise Exception('''<p><b>Microsoft Remote Desktop or xfreerdp not found</b></p>
|
||||
raise Exception(
|
||||
'''<p><b>Microsoft Remote Desktop or xfreerdp not found</b></p>
|
||||
<p>In order to connect to UDS RDP Sessions, you need to have a<p>
|
||||
<ul>
|
||||
<li>
|
||||
@ -49,9 +60,11 @@ if executable is None:
|
||||
<p><b>Xfreerdp</b> from homebrew</p>
|
||||
</li>
|
||||
</ul>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
else:
|
||||
raise Exception('''<p><b>xfreerdp not found</b></p>
|
||||
raise Exception(
|
||||
'''<p><b>xfreerdp not found</b></p>
|
||||
<p>In order to connect to UDS RDP Sessions, you need to have a<p>
|
||||
<ul>
|
||||
<li>
|
||||
@ -68,7 +81,8 @@ if executable is None:
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
|
||||
# Open tunnel
|
||||
fs = forward(remote=(sp['tunHost'], int(sp['tunPort'])), ticket=sp['ticket'], timeout=sp['tunWait'], check_certificate=sp['tunChk']) # type: ignore
|
||||
@ -76,12 +90,12 @@ address = '127.0.0.1:{}'.format(fs.server_address[1])
|
||||
|
||||
# Check that tunnel works..
|
||||
if fs.check() is False:
|
||||
raise Exception('<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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('<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
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:
|
||||
|
@ -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 '',
|
||||
)
|
||||
|
@ -10,11 +10,13 @@ from uds import tools # type: ignore
|
||||
executable = tools.findApp('remote-viewer')
|
||||
|
||||
if executable is None:
|
||||
raise Exception('''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
raise Exception(
|
||||
'''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
<p>
|
||||
Please, install appropriate package for your Linux system. (probably named something like <b>remote-viewer</b>)
|
||||
</p>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
|
||||
theFile = sp['as_file'] # type: ignore
|
||||
|
||||
|
@ -11,14 +11,16 @@ from uds.tunnel import forward # type: ignore
|
||||
executable = tools.findApp('remote-viewer')
|
||||
|
||||
if executable is None:
|
||||
raise Exception('''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
raise Exception(
|
||||
'''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
<p>
|
||||
Please, install appropriate package for your system.
|
||||
</p>
|
||||
<p>
|
||||
Please, install appropriate package for your Linux system. (probably named something like <b>virt-viewer</b>)
|
||||
</p>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
|
||||
|
||||
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('<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
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('<p>Could not connect to tunnel server 2.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server 2.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
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)
|
||||
|
@ -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('''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
raise Exception(
|
||||
'''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
<p>
|
||||
Please, install appropriate package for your system.
|
||||
</p>
|
||||
@ -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.<br/>
|
||||
Also remember, that in order to allow this app to run on your system, you must open it one time once it is copied to your App folder
|
||||
</p>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
|
||||
|
||||
theFile = sp['as_file'] # type: ignore
|
||||
|
@ -12,7 +12,8 @@ from uds.tunnel import forward # type: ignore
|
||||
remoteViewer = '/Applications/RemoteViewer.app/Contents/MacOS/RemoteViewer'
|
||||
|
||||
if not os.path.isfile(remoteViewer):
|
||||
raise Exception('''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
raise Exception(
|
||||
'''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
<p>
|
||||
Please, install appropriate package for your system.
|
||||
</p>
|
||||
@ -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.<br/>
|
||||
Also remember, that in order to allow this app to run on your system, you must open it one time once it is copied to your App folder
|
||||
</p>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
|
||||
theFile = sp['as_file_ns'] # type: ignore
|
||||
fs = None
|
||||
@ -33,7 +35,9 @@ if sp['ticket']: # type: ignore
|
||||
|
||||
# Check that tunnel works..
|
||||
if fs.check() is False:
|
||||
raise Exception('<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
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('<p>Could not connect to tunnel server 2.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server 2.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
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)
|
||||
|
@ -19,14 +19,16 @@ for env in ('PROGRAMFILES', 'PROGRAMW6432'):
|
||||
executable = tools.findApp('remote-viewer.exe', extraPaths)
|
||||
|
||||
if executable is None:
|
||||
raise Exception('''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
raise Exception(
|
||||
'''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
<p>
|
||||
Please, install appropriate package for your system.
|
||||
</p>
|
||||
<p>
|
||||
<a href="http://virt-manager.org/download/">Open download page</a>
|
||||
</p>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
|
||||
theFile = sp['as_file'] # type: ignore
|
||||
|
||||
|
@ -20,14 +20,16 @@ for env in ('PROGRAMFILES', 'PROGRAMW6432'):
|
||||
executable = tools.findApp('remote-viewer.exe', extraPaths)
|
||||
|
||||
if executable is None:
|
||||
raise Exception('''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
raise Exception(
|
||||
'''<p>You need to have installed virt-viewer to connect to this UDS service.</p>
|
||||
<p>
|
||||
Please, install appropriate package for your system.
|
||||
</p>
|
||||
<p>
|
||||
<a href="http://virt-manager.org/download/">Open download page</a>
|
||||
</p>
|
||||
''')
|
||||
'''
|
||||
)
|
||||
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('<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
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('<p>Could not connect to tunnel server 2.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server 2.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
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)
|
||||
|
@ -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, '')
|
||||
|
@ -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
|
||||
|
@ -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__'
|
||||
|
@ -17,9 +17,21 @@ filename = tools.saveTempFile(theFile)
|
||||
|
||||
executable = tools.findApp('x2goclient')
|
||||
if executable is None:
|
||||
raise Exception('''<p>You must have installed latest X2GO Client in order to connect to this UDS service.</p>
|
||||
<p>Please, install the required packages for your platform</p>''')
|
||||
raise Exception(
|
||||
'''<p>You must have installed latest X2GO Client in order to connect to this UDS service.</p>
|
||||
<p>Please, install the required packages for your platform</p>'''
|
||||
)
|
||||
|
||||
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)
|
||||
|
@ -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('<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
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('''<p>You must have installed latest X2GO Client in order to connect to this UDS service.</p>
|
||||
<p>Please, install the required packages for your platform</p>''')
|
||||
raise Exception(
|
||||
'''<p>You must have installed latest X2GO Client in order to connect to this UDS service.</p>
|
||||
<p>Please, install the required packages for your platform</p>'''
|
||||
)
|
||||
|
||||
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',
|
||||
]
|
||||
)
|
||||
|
@ -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('''<p>You must have installed latest X2GO Client in order to connect to this UDS service.</p>
|
||||
<p>You can download it for windows from <a href="http://wiki.x2go.org/doku.php">X2Go Site</a>.</p>''')
|
||||
raise Exception(
|
||||
'''<p>You must have installed latest X2GO Client in order to connect to this UDS service.</p>
|
||||
<p>You can download it for windows from <a href="http://wiki.x2go.org/doku.php">X2Go Site</a>.</p>'''
|
||||
)
|
||||
|
||||
# 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)
|
||||
|
@ -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('<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>')
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
|
||||
# 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('''<p>You must have installed latest X2GO Client in default program file folder in order to connect to this UDS service.</p>
|
||||
<p>You can download it for windows from <a href="http://wiki.x2go.org/doku.php">X2Go Site</a>.</p>''')
|
||||
raise Exception(
|
||||
'''<p>You must have installed latest X2GO Client in default program file folder in order to connect to this UDS service.</p>
|
||||
<p>You can download it for windows from <a href="http://wiki.x2go.org/doku.php">X2Go Site</a>.</p>'''
|
||||
)
|
||||
|
||||
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',
|
||||
]
|
||||
)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -96,7 +96,6 @@ class TX2GOTransport(BaseX2GOTransport):
|
||||
tab=gui.TUNNEL_TAB,
|
||||
)
|
||||
|
||||
|
||||
fixedName = BaseX2GOTransport.fixedName
|
||||
screenSize = BaseX2GOTransport.screenSize
|
||||
desktopType = BaseX2GOTransport.desktopType
|
||||
|
@ -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__)
|
||||
|
Loading…
Reference in New Issue
Block a user