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.
|
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
|
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')
|
typeName = _('HTML5 VNC Experimental')
|
||||||
typeType = 'HTML5VNCTransport'
|
typeType = 'HTML5VNCTransport'
|
||||||
typeDescription = _('VNC protocol using HTML5 client (EXPERIMENTAL)')
|
typeDescription = _('VNC protocol using HTML5 client (EXPERIMENTAL)')
|
||||||
@ -70,10 +71,30 @@ class HTML5VNCTransport(transports.Transport):
|
|||||||
protocol = transports.protocols.VNC
|
protocol = transports.protocols.VNC
|
||||||
group = transports.TUNNELED_GROUP
|
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)
|
username = gui.TextField(
|
||||||
password = gui.PasswordField(label=_('Password'), order=21, tooltip=_('Password for VNC connection authentication'), tab=gui.PARAMETERS_TAB)
|
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(
|
vncPort = gui.NumericField(
|
||||||
length=22,
|
length=22,
|
||||||
@ -82,7 +103,7 @@ class HTML5VNCTransport(transports.Transport):
|
|||||||
order=2,
|
order=2,
|
||||||
tooltip=_('Port of the VNC server.'),
|
tooltip=_('Port of the VNC server.'),
|
||||||
required=True,
|
required=True,
|
||||||
tab=gui.PARAMETERS_TAB
|
tab=gui.PARAMETERS_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
colorDepth = gui.ChoiceField(
|
colorDepth = gui.ChoiceField(
|
||||||
@ -98,21 +119,40 @@ class HTML5VNCTransport(transports.Transport):
|
|||||||
gui.choiceItem('32', '33 bits'),
|
gui.choiceItem('32', '33 bits'),
|
||||||
],
|
],
|
||||||
defvalue='-',
|
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)
|
swapRedBlue = gui.CheckBoxField(
|
||||||
cursor = gui.CheckBoxField(label=_('Remote cursor'), order=28, tooltip=_('If set, force to show remote cursor'), tab=gui.PARAMETERS_TAB)
|
label=_('Swap red/blue'),
|
||||||
readOnly = gui.CheckBoxField(label=_('Read only'), order=29, tooltip=_('If set, the connection will be read only'), tab=gui.PARAMETERS_TAB)
|
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(
|
ticketValidity = gui.NumericField(
|
||||||
length=3,
|
length=3,
|
||||||
label=_('Ticket Validity'),
|
label=_('Ticket Validity'),
|
||||||
defvalue='60',
|
defvalue='60',
|
||||||
order=90,
|
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,
|
required=True,
|
||||||
minValue=60,
|
minValue=60,
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
forceNewWindow = gui.ChoiceField(
|
forceNewWindow = gui.ChoiceField(
|
||||||
order=91,
|
order=91,
|
||||||
@ -120,12 +160,20 @@ class HTML5VNCTransport(transports.Transport):
|
|||||||
tooltip=_('Select windows behavior for new connections on HTML5'),
|
tooltip=_('Select windows behavior for new connections on HTML5'),
|
||||||
required=True,
|
required=True,
|
||||||
values=[
|
values=[
|
||||||
gui.choiceItem(gui.FALSE, _('Open every connection on the same window, but keeps UDS window.')),
|
gui.choiceItem(
|
||||||
gui.choiceItem(gui.TRUE, _('Force every connection to be opened on a new window.')),
|
gui.FALSE,
|
||||||
gui.choiceItem('overwrite', _('Override UDS window and replace it with the connection.')),
|
_('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,
|
defvalue=gui.FALSE,
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
def initialize(self, values: 'Module.ValuesType'):
|
def initialize(self, values: 'Module.ValuesType'):
|
||||||
@ -134,7 +182,9 @@ class HTML5VNCTransport(transports.Transport):
|
|||||||
# Strip spaces
|
# Strip spaces
|
||||||
self.guacamoleServer.value = self.guacamoleServer.value.strip()
|
self.guacamoleServer.value = self.guacamoleServer.value.strip()
|
||||||
if self.guacamoleServer.value[0:4] != 'http':
|
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:
|
def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -152,15 +202,15 @@ class HTML5VNCTransport(transports.Transport):
|
|||||||
return ready == 'Y'
|
return ready == 'Y'
|
||||||
|
|
||||||
def getLink( # pylint: disable=too-many-locals
|
def getLink( # pylint: disable=too-many-locals
|
||||||
self,
|
self,
|
||||||
userService: 'models.UserService',
|
userService: 'models.UserService',
|
||||||
transport: 'models.Transport',
|
transport: 'models.Transport',
|
||||||
ip: str,
|
ip: str,
|
||||||
os: typing.Dict[str, str],
|
os: typing.Dict[str, str],
|
||||||
user: 'models.User',
|
user: 'models.User',
|
||||||
password: str,
|
password: str,
|
||||||
request: 'HttpRequest'
|
request: 'HttpRequest',
|
||||||
) -> str:
|
) -> str:
|
||||||
# Build params dict
|
# Build params dict
|
||||||
params = {
|
params = {
|
||||||
'protocol': 'vnc',
|
'protocol': 'vnc',
|
||||||
@ -200,9 +250,6 @@ class HTML5VNCTransport(transports.Transport):
|
|||||||
|
|
||||||
return str(
|
return str(
|
||||||
"{}/guacamole/#/?data={}.{}{}".format(
|
"{}/guacamole/#/?data={}.{}{}".format(
|
||||||
self.guacamoleServer.value,
|
self.guacamoleServer.value, ticket, scrambler, onw
|
||||||
ticket,
|
|
||||||
scrambler,
|
|
||||||
onw
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -53,6 +53,7 @@ class RDPTransport(BaseRDPTransport):
|
|||||||
Provides access via RDP to service.
|
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
|
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')
|
typeName = _('RDP')
|
||||||
typeType = 'RDPTransport'
|
typeType = 'RDPTransport'
|
||||||
typeDescription = _('RDP Protocol. Direct connection.')
|
typeDescription = _('RDP Protocol. Direct connection.')
|
||||||
@ -91,15 +92,15 @@ class RDPTransport(BaseRDPTransport):
|
|||||||
customParametersMAC = BaseRDPTransport.customParametersMAC
|
customParametersMAC = BaseRDPTransport.customParametersMAC
|
||||||
|
|
||||||
def getUDSTransportScript( # pylint: disable=too-many-locals
|
def getUDSTransportScript( # pylint: disable=too-many-locals
|
||||||
self,
|
self,
|
||||||
userService: 'models.UserService',
|
userService: 'models.UserService',
|
||||||
transport: 'models.Transport',
|
transport: 'models.Transport',
|
||||||
ip: str,
|
ip: str,
|
||||||
os: typing.Dict[str, str],
|
os: typing.Dict[str, str],
|
||||||
user: 'models.User',
|
user: 'models.User',
|
||||||
password: str,
|
password: str,
|
||||||
request: 'HttpRequest'
|
request: 'HttpRequest',
|
||||||
) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]:
|
) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]:
|
||||||
# We use helper to keep this clean
|
# We use helper to keep this clean
|
||||||
# prefs = user.prefs('rdp')
|
# prefs = user.prefs('rdp')
|
||||||
|
|
||||||
@ -114,7 +115,9 @@ class RDPTransport(BaseRDPTransport):
|
|||||||
width, height = self.screenSize.value.split('x')
|
width, height = self.screenSize.value.split('x')
|
||||||
depth = self.colorDepth.value
|
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.enablecredsspsupport = ci.get('sso') == 'True' or self.credssp.isTrue()
|
||||||
r.address = '{}:{}'.format(ip, self.rdpPort.value)
|
r.address = '{}:{}'.format(ip, self.rdpPort.value)
|
||||||
r.username = username
|
r.username = username
|
||||||
@ -143,13 +146,17 @@ class RDPTransport(BaseRDPTransport):
|
|||||||
osName = {
|
osName = {
|
||||||
OsDetector.Windows: 'windows',
|
OsDetector.Windows: 'windows',
|
||||||
OsDetector.Linux: 'linux',
|
OsDetector.Linux: 'linux',
|
||||||
OsDetector.Macintosh: 'macosx'
|
OsDetector.Macintosh: 'macosx',
|
||||||
|
|
||||||
}.get(os['OS'])
|
}.get(os['OS'])
|
||||||
|
|
||||||
if osName is None:
|
if osName is None:
|
||||||
logger.error('Os not detected for RDP Transport: %s', request.META.get('HTTP_USER_AGENT', 'Unknown'))
|
logger.error(
|
||||||
return super().getUDSTransportScript(userService, transport, ip, os, user, password, request)
|
'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] = {
|
sp: typing.MutableMapping[str, typing.Any] = {
|
||||||
'password': password,
|
'password': password,
|
||||||
@ -162,21 +169,27 @@ class RDPTransport(BaseRDPTransport):
|
|||||||
if osName == 'windows':
|
if osName == 'windows':
|
||||||
if password != '':
|
if password != '':
|
||||||
r.password = '{password}'
|
r.password = '{password}'
|
||||||
sp.update({
|
sp.update(
|
||||||
'as_file': r.as_file,
|
{
|
||||||
})
|
'as_file': r.as_file,
|
||||||
|
}
|
||||||
|
)
|
||||||
elif osName == 'linux':
|
elif osName == 'linux':
|
||||||
sp.update({
|
sp.update(
|
||||||
'as_new_xfreerdp_params': r.as_new_xfreerdp_params,
|
{
|
||||||
'address': r.address,
|
'as_new_xfreerdp_params': r.as_new_xfreerdp_params,
|
||||||
})
|
'address': r.address,
|
||||||
|
}
|
||||||
|
)
|
||||||
else: # Mac
|
else: # Mac
|
||||||
r.linuxCustomParameters = self.customParametersMAC.value
|
r.linuxCustomParameters = self.customParametersMAC.value
|
||||||
sp.update({
|
sp.update(
|
||||||
'as_new_xfreerdp_params': r.as_new_xfreerdp_params,
|
{
|
||||||
'as_rdp_url': r.as_rdp_url if self.allowMacMSRDC.isTrue() else '',
|
'as_new_xfreerdp_params': r.as_new_xfreerdp_params,
|
||||||
'as_file': r.as_file if self.allowMacMSRDC.isTrue() else '',
|
'as_rdp_url': r.as_rdp_url if self.allowMacMSRDC.isTrue() else '',
|
||||||
'address': r.address,
|
'as_file': r.as_file if self.allowMacMSRDC.isTrue() else '',
|
||||||
})
|
'address': r.address,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return self.getScript('scripts/{}/direct.py', osName, sp)
|
return self.getScript('scripts/{}/direct.py', osName, sp)
|
||||||
|
@ -167,16 +167,16 @@ class BaseRDPTransport(transports.Transport):
|
|||||||
tab=gui.PARAMETERS_TAB,
|
tab=gui.PARAMETERS_TAB,
|
||||||
defvalue=gui.TRUE,
|
defvalue=gui.TRUE,
|
||||||
)
|
)
|
||||||
rdpPort = gui.NumericField(order = 29,
|
rdpPort = gui.NumericField(
|
||||||
length = 5, # That is, max allowed value is 65535
|
order=29,
|
||||||
|
length=5, # That is, max allowed value is 65535
|
||||||
label=_('RDP Port'),
|
label=_('RDP Port'),
|
||||||
tooltip=_('Use this port as RDP port. Defaults to 3389.'),
|
tooltip=_('Use this port as RDP port. Defaults to 3389.'),
|
||||||
tab=gui.PARAMETERS_TAB,
|
tab=gui.PARAMETERS_TAB,
|
||||||
required = True, #: Numeric fields have always a value, so this not really needed
|
required=True, #: Numeric fields have always a value, so this not really needed
|
||||||
defvalue = '3389',
|
defvalue='3389',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
screenSize = gui.ChoiceField(
|
screenSize = gui.ChoiceField(
|
||||||
label=_('Screen Size'),
|
label=_('Screen Size'),
|
||||||
order=30,
|
order=30,
|
||||||
@ -359,7 +359,7 @@ class BaseRDPTransport(transports.Transport):
|
|||||||
|
|
||||||
if self.fixedPassword.value:
|
if self.fixedPassword.value:
|
||||||
password = self.fixedPassword.value
|
password = self.fixedPassword.value
|
||||||
|
|
||||||
azureAd = False
|
azureAd = False
|
||||||
if self.fixedDomain.value != '':
|
if self.fixedDomain.value != '':
|
||||||
if self.fixedDomain.value.lower() == 'azuread':
|
if self.fixedDomain.value.lower() == 'azuread':
|
||||||
@ -391,7 +391,7 @@ class BaseRDPTransport(transports.Transport):
|
|||||||
'protocol': self.protocol,
|
'protocol': self.protocol,
|
||||||
'username': username,
|
'username': username,
|
||||||
'password': password,
|
'password': password,
|
||||||
'domain': domain
|
'domain': domain,
|
||||||
}
|
}
|
||||||
|
|
||||||
def getConnectionInfo(
|
def getConnectionInfo(
|
||||||
@ -408,7 +408,10 @@ class BaseRDPTransport(transports.Transport):
|
|||||||
_, username, password = cdata # Host is unused
|
_, username, password = cdata # Host is unused
|
||||||
|
|
||||||
return self.processUserPassword(
|
return self.processUserPassword(
|
||||||
typing.cast('models.UserService', userService), user, password, altUsername=username
|
typing.cast('models.UserService', userService),
|
||||||
|
user,
|
||||||
|
password,
|
||||||
|
altUsername=username,
|
||||||
)
|
)
|
||||||
|
|
||||||
def getScript(
|
def getScript(
|
||||||
|
@ -39,6 +39,7 @@ import typing
|
|||||||
|
|
||||||
from uds.core.util import os_detector as OsDetector
|
from uds.core.util import os_detector as OsDetector
|
||||||
|
|
||||||
|
|
||||||
class RDPFile:
|
class RDPFile:
|
||||||
fullScreen = False
|
fullScreen = False
|
||||||
width = '800'
|
width = '800'
|
||||||
@ -71,13 +72,13 @@ class RDPFile:
|
|||||||
enforcedShares: typing.Optional[str] = None
|
enforcedShares: typing.Optional[str] = None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
fullScreen: bool,
|
fullScreen: bool,
|
||||||
width: typing.Union[str, int],
|
width: typing.Union[str, int],
|
||||||
height: typing.Union[str, int],
|
height: typing.Union[str, int],
|
||||||
bpp: str,
|
bpp: str,
|
||||||
target: str = OsDetector.Windows
|
target: str = OsDetector.Windows,
|
||||||
):
|
):
|
||||||
self.width = str(width)
|
self.width = str(width)
|
||||||
self.height = str(height)
|
self.height = str(height)
|
||||||
self.bpp = str(bpp)
|
self.bpp = str(bpp)
|
||||||
@ -95,7 +96,9 @@ class RDPFile:
|
|||||||
return self.get()
|
return self.get()
|
||||||
|
|
||||||
@property
|
@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
|
Parameters for xfreerdp >= 1.1.0 with self rdp description
|
||||||
Note that server is not added
|
Note that server is not added
|
||||||
@ -188,7 +191,7 @@ class RDPFile:
|
|||||||
def getGeneric(self): # pylint: disable=too-many-statements
|
def getGeneric(self): # pylint: disable=too-many-statements
|
||||||
password = '{password}'
|
password = '{password}'
|
||||||
screenMode = '2' if self.fullScreen else '1'
|
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'
|
serials = '1' if self.redirectSerials else '0'
|
||||||
scards = '1' if self.redirectSmartcards else '0'
|
scards = '1' if self.redirectSmartcards else '0'
|
||||||
printers = '1' if self.redirectPrinters else '0'
|
printers = '1' if self.redirectPrinters else '0'
|
||||||
@ -250,7 +253,11 @@ class RDPFile:
|
|||||||
if self.redirectWebcam:
|
if self.redirectWebcam:
|
||||||
res += 'camerastoredirect:s:*\n'
|
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 != 'false':
|
||||||
if self.redirectDrives == 'true':
|
if self.redirectDrives == 'true':
|
||||||
@ -259,7 +266,9 @@ class RDPFile:
|
|||||||
res += 'drivestoredirect:s:{}DynamicDrives\n'.format(enforcedSharesStr)
|
res += 'drivestoredirect:s:{}DynamicDrives\n'.format(enforcedSharesStr)
|
||||||
res += 'devicestoredirect:s:*\n'
|
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?
|
# DirectX?
|
||||||
res += 'redirectdirectx:i:1\n'
|
res += 'redirectdirectx:i:1\n'
|
||||||
@ -273,12 +282,11 @@ class RDPFile:
|
|||||||
def as_rdp_url(self) -> str:
|
def as_rdp_url(self) -> str:
|
||||||
# Some parameters
|
# Some parameters
|
||||||
screenMode = '2' if self.fullScreen else '1'
|
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'
|
useMultimon = '1' if self.multimon else '0'
|
||||||
disableWallpaper = '0' if self.showWallpaper else '1'
|
disableWallpaper = '0' if self.showWallpaper else '1'
|
||||||
printers = '1' if self.redirectPrinters else '0'
|
printers = '1' if self.redirectPrinters else '0'
|
||||||
credsspsupport = '1' if self.enablecredsspsupport else '0'
|
credsspsupport = '1' if self.enablecredsspsupport else '0'
|
||||||
|
|
||||||
|
|
||||||
parameters = [
|
parameters = [
|
||||||
('full address', f's:{self.address}'),
|
('full address', f's:{self.address}'),
|
||||||
@ -295,7 +303,7 @@ class RDPFile:
|
|||||||
('disable full window drag', 'i:1'),
|
('disable full window drag', 'i:1'),
|
||||||
('authentication level', f'i:0'),
|
('authentication level', f'i:0'),
|
||||||
# Not listed, but maybe usable?
|
# Not listed, but maybe usable?
|
||||||
('enablecredsspsupport', f'i:{credsspsupport}')
|
('enablecredsspsupport', f'i:{credsspsupport}'),
|
||||||
]
|
]
|
||||||
if self.username:
|
if self.username:
|
||||||
parameters.append(('username', f's:{urllib.parse.quote(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
|
if self.redirectDrives != 'false': # Only "all drives" is supported
|
||||||
parameters.append(('drivestoredirect', 's:*'))
|
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
|
import subprocess # noqa
|
||||||
# Saved as .py for easier editing
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from uds import tools # type: ignore
|
from uds import tools # type: ignore
|
||||||
|
|
||||||
# Inject local passed sp into globals for inner functions
|
# Inject local passed sp into globals for inner functions
|
||||||
globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable
|
globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable
|
||||||
|
|
||||||
|
|
||||||
def execUdsRdp(udsrdp):
|
def execUdsRdp(udsrdp):
|
||||||
import subprocess # @Reimport
|
import subprocess # @Reimport
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
params = [os.path.expandvars(i) for i in [udsrdp] + sp['as_new_xfreerdp_params'] + ['/v:{}'.format(sp['address'])]] # type: ignore
|
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))
|
tools.addTaskToWait(subprocess.Popen(params))
|
||||||
|
|
||||||
@ -19,9 +17,11 @@ def execUdsRdp(udsrdp):
|
|||||||
def execNewXFreeRdp(xfreerdp):
|
def execNewXFreeRdp(xfreerdp):
|
||||||
import subprocess # @Reimport
|
import subprocess # @Reimport
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
params = [os.path.expandvars(i) for i in [xfreerdp] + sp['as_new_xfreerdp_params'] + ['/v:{}'.format(sp['address'])]] # type: ignore
|
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))
|
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)
|
# 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')
|
xfreerdp = tools.findApp('xfreerdp')
|
||||||
udsrdp = tools.findApp('udsrdp')
|
udsrdp = tools.findApp('udsrdp')
|
||||||
@ -34,9 +34,11 @@ if udsrdp is not None:
|
|||||||
fnc, app = execUdsRdp, udsrdp
|
fnc, app = execUdsRdp, udsrdp
|
||||||
|
|
||||||
if app is None or fnc is None:
|
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>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>
|
<p>Also note that xfreerdp prior to version 1.1 will not be taken into consideration.</p>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
fnc(app) # @UndefinedVariable
|
fnc(app) # @UndefinedVariable
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
# This is a template
|
import subprocess # noqa
|
||||||
# Saved as .py for easier editing
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
from uds.tunnel import forward # type: ignore
|
from uds.tunnel import forward # type: ignore
|
||||||
|
|
||||||
from uds import tools # 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
|
# Inject local passed sp into globals for functions
|
||||||
globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable
|
globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable
|
||||||
|
|
||||||
|
|
||||||
def execUdsRdp(udsrdp, port):
|
def execUdsRdp(udsrdp, port):
|
||||||
import subprocess # @Reimport
|
import subprocess # @Reimport
|
||||||
import os.path
|
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
|
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))
|
tools.addTaskToWait(subprocess.Popen(params))
|
||||||
|
|
||||||
@ -20,9 +19,11 @@ def execUdsRdp(udsrdp, port):
|
|||||||
def execNewXFreeRdp(xfreerdp, port):
|
def execNewXFreeRdp(xfreerdp, port):
|
||||||
import subprocess # @Reimport
|
import subprocess # @Reimport
|
||||||
import os.path
|
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
|
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))
|
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)
|
# 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')
|
xfreerdp = tools.findApp('xfreerdp')
|
||||||
udsrdp = tools.findApp('udsrdp')
|
udsrdp = tools.findApp('udsrdp')
|
||||||
@ -35,16 +36,20 @@ if udsrdp:
|
|||||||
fnc, app = execUdsRdp, udsrdp
|
fnc, app = execUdsRdp, udsrdp
|
||||||
|
|
||||||
if app is None or fnc is None:
|
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>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>
|
<p>Also note that xfreerdp prior to version 1.1 will not be taken into consideration.</p>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# Open tunnel
|
# 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..
|
# Check that tunnel works..
|
||||||
if fs.check() is False:
|
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])
|
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
|
# pylint: disable=import-error, no-name-in-module, too-many-format-args, undefined-variable, invalid-sequence-index
|
||||||
import subprocess
|
import subprocess
|
||||||
import shutil
|
import shutil
|
||||||
@ -13,21 +9,32 @@ from uds import tools # type: ignore
|
|||||||
# Inject local passed sp into globals for functions
|
# Inject local passed sp into globals for functions
|
||||||
globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable
|
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')
|
xfreerdp = tools.findApp('xfreerdp')
|
||||||
executable = None
|
executable = None
|
||||||
|
|
||||||
|
|
||||||
def fixResolution():
|
def fixResolution():
|
||||||
import re
|
import re
|
||||||
import subprocess
|
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)
|
groups = re.search(r': \d* x \d*', results)
|
||||||
width, height = '1024', '768' # Safe default values
|
width, height = '1024', '768' # Safe default values
|
||||||
if groups:
|
if groups:
|
||||||
res = groups.group(0).split(' ')
|
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
|
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
|
# Check first xfreerdp, allow password redir
|
||||||
if xfreerdp and os.path.isfile(xfreerdp):
|
if xfreerdp and os.path.isfile(xfreerdp):
|
||||||
executable = 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 executable is None:
|
||||||
if sp['as_file']: # type: ignore
|
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>
|
<p>In order to connect to UDS RDP Sessions, you need to have a<p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@ -46,9 +54,11 @@ if executable is None:
|
|||||||
<p><b>Xfreerdp</b> from homebrew</p>
|
<p><b>Xfreerdp</b> from homebrew</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
else:
|
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>
|
<p>In order to connect to UDS RDP Sessions, you need to have a<p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@ -65,16 +75,26 @@ if executable is None:
|
|||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
elif executable == msrdc:
|
elif executable == msrdc:
|
||||||
theFile = sp['as_file'] # type: ignore
|
theFile = sp['as_file'] # type: ignore
|
||||||
filename = tools.saveTempFile(theFile)
|
filename = tools.saveTempFile(theFile)
|
||||||
# Rename as .rdp, so open recognizes it
|
# Rename as .rdp, so open recognizes it
|
||||||
shutil.move(filename, filename + '.rdp')
|
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) )
|
# 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')
|
tools.addFileToUnlink(filename + '.rdp')
|
||||||
elif executable == xfreerdp:
|
elif executable == xfreerdp:
|
||||||
# Fix resolution...
|
# 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
|
params = [os.path.expandvars(i) for i in [executable] + xfparms + ['/v:{}'.format(sp['address'])]] # type: ignore
|
||||||
subprocess.Popen(params)
|
subprocess.Popen(params)
|
||||||
|
|
||||||
|
@ -15,19 +15,29 @@ from uds import tools # type: ignore
|
|||||||
# Inject local passed sp into globals for functions
|
# Inject local passed sp into globals for functions
|
||||||
globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable
|
globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable
|
||||||
|
|
||||||
|
|
||||||
def fixResolution():
|
def fixResolution():
|
||||||
import re
|
import re
|
||||||
import subprocess
|
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)
|
groups = re.search(r': \d* x \d*', results)
|
||||||
width, height = '1024', '768' # Safe default values
|
width, height = '1024', '768' # Safe default values
|
||||||
if groups:
|
if groups:
|
||||||
res = groups.group(0).split(' ')
|
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
|
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')
|
xfreerdp = tools.findApp('xfreerdp')
|
||||||
executable = None
|
executable = None
|
||||||
|
|
||||||
@ -39,7 +49,8 @@ elif msrdc and os.path.isfile(msrdc) and sp['as_file']: # type: ignore
|
|||||||
|
|
||||||
if executable is None:
|
if executable is None:
|
||||||
if sp['as_rdp_url']: # type: ignore
|
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>
|
<p>In order to connect to UDS RDP Sessions, you need to have a<p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@ -49,9 +60,11 @@ if executable is None:
|
|||||||
<p><b>Xfreerdp</b> from homebrew</p>
|
<p><b>Xfreerdp</b> from homebrew</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
else:
|
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>
|
<p>In order to connect to UDS RDP Sessions, you need to have a<p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@ -68,7 +81,8 @@ if executable is None:
|
|||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
# Open tunnel
|
# 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
|
||||||
@ -76,12 +90,12 @@ address = '127.0.0.1:{}'.format(fs.server_address[1])
|
|||||||
|
|
||||||
# Check that tunnel works..
|
# Check that tunnel works..
|
||||||
if fs.check() is False:
|
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:
|
if executable == msrdc:
|
||||||
theFile = theFile = sp['as_file'].format( # type: ignore
|
theFile = theFile = sp['as_file'].format(address=address) # type: ignore
|
||||||
address=address
|
|
||||||
)
|
|
||||||
|
|
||||||
filename = tools.saveTempFile(theFile)
|
filename = tools.saveTempFile(theFile)
|
||||||
# Rename as .rdp, so open recognizes it
|
# Rename as .rdp, so open recognizes it
|
||||||
@ -89,7 +103,16 @@ if executable == msrdc:
|
|||||||
|
|
||||||
# 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) )
|
# 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')
|
tools.addFileToUnlink(filename + '.rdp')
|
||||||
elif executable == xfreerdp:
|
elif executable == xfreerdp:
|
||||||
# Fix resolution...
|
# Fix resolution...
|
||||||
@ -98,6 +121,8 @@ elif executable == xfreerdp:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
xfparms = list(map(lambda x: x.replace('#WIDTH#', '1400').replace('#HEIGHT#', '800'), sp['as_new_xfreerdp_params'])) # type: ignore
|
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)
|
subprocess.Popen(params)
|
||||||
|
|
||||||
|
@ -13,13 +13,22 @@ from uds import tools # type: ignore
|
|||||||
thePass = sp['password'].encode('UTF-16LE') # type: ignore
|
thePass = sp['password'].encode('UTF-16LE') # type: ignore
|
||||||
|
|
||||||
try:
|
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:
|
except Exception:
|
||||||
# logger.info('Cannot encrypt for user, trying for machine')
|
# 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:
|
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.SetValueEx(key, sp['ip'], 0, wreg.REG_DWORD, 255) # type: ignore
|
||||||
wreg.CloseKey(key)
|
wreg.CloseKey(key)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -27,15 +36,14 @@ except Exception as e:
|
|||||||
pass # Key does not exists, ok...
|
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
|
# 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
|
theFile = sp['as_file'].format(password=password) # type: ignore
|
||||||
password=password
|
|
||||||
)
|
|
||||||
filename = tools.saveTempFile(theFile)
|
filename = tools.saveTempFile(theFile)
|
||||||
executable = tools.findApp('mstsc.exe')
|
executable = tools.findApp('mstsc.exe')
|
||||||
|
|
||||||
if executable is None:
|
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])
|
subprocess.Popen([executable, filename])
|
||||||
tools.addFileToUnlink(filename)
|
tools.addFileToUnlink(filename)
|
||||||
|
|
||||||
|
@ -16,29 +16,41 @@ fs = forward(remote=(sp['tunHost'], int(sp['tunPort'])), ticket=sp['ticket'], ti
|
|||||||
|
|
||||||
# Check that tunnel works..
|
# Check that tunnel works..
|
||||||
if fs.check() is False:
|
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
|
thePass = sp['password'].encode('UTF-16LE') # type: ignore
|
||||||
|
|
||||||
try:
|
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:
|
except Exception:
|
||||||
# Cannot encrypt for user, trying for machine
|
# 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
|
# 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
|
theFile = sp['as_file'].format( # type: ignore
|
||||||
password=password,
|
password=password, address='127.0.0.1:{}'.format(fs.server_address[1])
|
||||||
address='127.0.0.1:{}'.format(fs.server_address[1])
|
|
||||||
)
|
)
|
||||||
|
|
||||||
filename = tools.saveTempFile(theFile)
|
filename = tools.saveTempFile(theFile)
|
||||||
executable = tools.findApp('mstsc.exe')
|
executable = tools.findApp('mstsc.exe')
|
||||||
if executable is None:
|
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:
|
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.SetValueEx(key, '127.0.0.1', 0, wreg.REG_DWORD, 255) # type: ignore
|
||||||
wreg.CloseKey(key)
|
wreg.CloseKey(key)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -67,15 +67,15 @@ class RemoteViewerFile:
|
|||||||
delete_file: bool = True
|
delete_file: bool = True
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
host: str,
|
host: str,
|
||||||
port: str,
|
port: str,
|
||||||
tls_port: str,
|
tls_port: str,
|
||||||
password: str,
|
password: str,
|
||||||
ca: str,
|
ca: str,
|
||||||
host_subject: str,
|
host_subject: str,
|
||||||
fullscreen: bool = False
|
fullscreen: bool = False,
|
||||||
):
|
):
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
self.tls_port = tls_port
|
self.tls_port = tls_port
|
||||||
@ -102,7 +102,9 @@ class RemoteViewerFile:
|
|||||||
usb_auto_share = '01'[self.usb_auto_share]
|
usb_auto_share = '01'[self.usb_auto_share]
|
||||||
new_usb_auto_share = '01'[self.new_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(
|
return TEMPLATE.format(
|
||||||
type=self.connectionType,
|
type=self.connectionType,
|
||||||
@ -118,5 +120,7 @@ class RemoteViewerFile:
|
|||||||
delete_file=delete_file,
|
delete_file=delete_file,
|
||||||
host_subject=self.host_subject if tls_port != '-1' else '',
|
host_subject=self.host_subject if tls_port != '-1' else '',
|
||||||
ca=ca 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')
|
executable = tools.findApp('remote-viewer')
|
||||||
|
|
||||||
if executable is None:
|
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>
|
<p>
|
||||||
Please, install appropriate package for your Linux system. (probably named something like <b>remote-viewer</b>)
|
Please, install appropriate package for your Linux system. (probably named something like <b>remote-viewer</b>)
|
||||||
</p>
|
</p>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
theFile = sp['as_file'] # type: ignore
|
theFile = sp['as_file'] # type: ignore
|
||||||
|
|
||||||
|
@ -11,14 +11,16 @@ from uds.tunnel import forward # type: ignore
|
|||||||
executable = tools.findApp('remote-viewer')
|
executable = tools.findApp('remote-viewer')
|
||||||
|
|
||||||
if executable is None:
|
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>
|
<p>
|
||||||
Please, install appropriate package for your system.
|
Please, install appropriate package for your system.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Please, install appropriate package for your Linux system. (probably named something like <b>virt-viewer</b>)
|
Please, install appropriate package for your Linux system. (probably named something like <b>virt-viewer</b>)
|
||||||
</p>
|
</p>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
theFile = sp['as_file_ns'] # type: ignore
|
theFile = sp['as_file_ns'] # type: ignore
|
||||||
@ -29,7 +31,9 @@ if sp['ticket']: # type: ignore
|
|||||||
|
|
||||||
# Check that tunnel works..
|
# Check that tunnel works..
|
||||||
if fs.check() is False:
|
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
|
fss = None
|
||||||
if sp['ticket_secure']: # type: ignore
|
if sp['ticket_secure']: # type: ignore
|
||||||
@ -38,11 +42,13 @@ if sp['ticket_secure']: # type: ignore
|
|||||||
|
|
||||||
# Check that tunnel works..
|
# Check that tunnel works..
|
||||||
if fss.check() is False:
|
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(
|
theFile = theFile.format(
|
||||||
secure_port='-1' if not fss else fss.server_address[1],
|
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)
|
filename = tools.saveTempFile(theFile)
|
||||||
|
@ -11,7 +11,8 @@ from uds import tools # type: ignore
|
|||||||
remoteViewer = '/Applications/RemoteViewer.app/Contents/MacOS/RemoteViewer'
|
remoteViewer = '/Applications/RemoteViewer.app/Contents/MacOS/RemoteViewer'
|
||||||
|
|
||||||
if not os.path.isfile(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>
|
<p>
|
||||||
Please, install appropriate package for your system.
|
Please, install appropriate package for your system.
|
||||||
</p>
|
</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/>
|
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
|
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>
|
</p>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
theFile = sp['as_file'] # type: ignore
|
theFile = sp['as_file'] # type: ignore
|
||||||
|
@ -12,7 +12,8 @@ from uds.tunnel import forward # type: ignore
|
|||||||
remoteViewer = '/Applications/RemoteViewer.app/Contents/MacOS/RemoteViewer'
|
remoteViewer = '/Applications/RemoteViewer.app/Contents/MacOS/RemoteViewer'
|
||||||
|
|
||||||
if not os.path.isfile(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>
|
<p>
|
||||||
Please, install appropriate package for your system.
|
Please, install appropriate package for your system.
|
||||||
</p>
|
</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/>
|
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
|
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>
|
</p>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
theFile = sp['as_file_ns'] # type: ignore
|
theFile = sp['as_file_ns'] # type: ignore
|
||||||
fs = None
|
fs = None
|
||||||
@ -33,7 +35,9 @@ if sp['ticket']: # type: ignore
|
|||||||
|
|
||||||
# Check that tunnel works..
|
# Check that tunnel works..
|
||||||
if fs.check() is False:
|
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
|
fss = None
|
||||||
if sp['ticket_secure']: # type: ignore
|
if sp['ticket_secure']: # type: ignore
|
||||||
@ -42,11 +46,13 @@ if sp['ticket_secure']: # type: ignore
|
|||||||
|
|
||||||
# Check that tunnel works..
|
# Check that tunnel works..
|
||||||
if fss.check() is False:
|
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(
|
theFile = theFile.format(
|
||||||
secure_port='-1' if not fss else fss.server_address[1],
|
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)
|
filename = tools.saveTempFile(theFile)
|
||||||
|
@ -19,14 +19,16 @@ for env in ('PROGRAMFILES', 'PROGRAMW6432'):
|
|||||||
executable = tools.findApp('remote-viewer.exe', extraPaths)
|
executable = tools.findApp('remote-viewer.exe', extraPaths)
|
||||||
|
|
||||||
if executable is None:
|
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>
|
<p>
|
||||||
Please, install appropriate package for your system.
|
Please, install appropriate package for your system.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a href="http://virt-manager.org/download/">Open download page</a>
|
<a href="http://virt-manager.org/download/">Open download page</a>
|
||||||
</p>
|
</p>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
theFile = sp['as_file'] # type: ignore
|
theFile = sp['as_file'] # type: ignore
|
||||||
|
|
||||||
|
@ -20,14 +20,16 @@ for env in ('PROGRAMFILES', 'PROGRAMW6432'):
|
|||||||
executable = tools.findApp('remote-viewer.exe', extraPaths)
|
executable = tools.findApp('remote-viewer.exe', extraPaths)
|
||||||
|
|
||||||
if executable is None:
|
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>
|
<p>
|
||||||
Please, install appropriate package for your system.
|
Please, install appropriate package for your system.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a href="http://virt-manager.org/download/">Open download page</a>
|
<a href="http://virt-manager.org/download/">Open download page</a>
|
||||||
</p>
|
</p>
|
||||||
''')
|
'''
|
||||||
|
)
|
||||||
theFile = sp['as_file_ns'] # type: ignore
|
theFile = sp['as_file_ns'] # type: ignore
|
||||||
fs = None
|
fs = None
|
||||||
if sp['ticket']: # type: ignore
|
if sp['ticket']: # type: ignore
|
||||||
@ -36,7 +38,9 @@ if sp['ticket']: # type: ignore
|
|||||||
|
|
||||||
# Check that tunnel works..
|
# Check that tunnel works..
|
||||||
if fs.check() is False:
|
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
|
fss = None
|
||||||
if sp['ticket_secure']: # type: ignore
|
if sp['ticket_secure']: # type: ignore
|
||||||
@ -45,11 +49,13 @@ if sp['ticket_secure']: # type: ignore
|
|||||||
|
|
||||||
# Check that tunnel works..
|
# Check that tunnel works..
|
||||||
if fss.check() is False:
|
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(
|
theFile = theFile.format(
|
||||||
secure_port='-1' if not fss else fss.server_address[1],
|
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)
|
filename = tools.saveTempFile(theFile)
|
||||||
|
@ -51,6 +51,7 @@ class SPICETransport(BaseSpiceTransport):
|
|||||||
Provides access via SPICE to service.
|
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
|
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')
|
typeName = _('SPICE')
|
||||||
typeType = 'SPICETransport'
|
typeType = 'SPICETransport'
|
||||||
typeDescription = _('SPICE Protocol. Direct connection.')
|
typeDescription = _('SPICE Protocol. Direct connection.')
|
||||||
@ -65,15 +66,15 @@ class SPICETransport(BaseSpiceTransport):
|
|||||||
smartCardRedirect = BaseSpiceTransport.smartCardRedirect
|
smartCardRedirect = BaseSpiceTransport.smartCardRedirect
|
||||||
|
|
||||||
def getUDSTransportScript( # pylint: disable=too-many-locals
|
def getUDSTransportScript( # pylint: disable=too-many-locals
|
||||||
self,
|
self,
|
||||||
userService: 'models.UserService',
|
userService: 'models.UserService',
|
||||||
transport: 'models.Transport',
|
transport: 'models.Transport',
|
||||||
ip: str,
|
ip: str,
|
||||||
os: typing.Dict[str, str],
|
os: typing.Dict[str, str],
|
||||||
user: 'models.User',
|
user: 'models.User',
|
||||||
password: str,
|
password: str,
|
||||||
request: 'HttpRequest'
|
request: 'HttpRequest',
|
||||||
) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]:
|
) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]:
|
||||||
userServiceInstance: typing.Any = userService.getInstance()
|
userServiceInstance: typing.Any = userService.getInstance()
|
||||||
|
|
||||||
con = userServiceInstance.getConsoleConnection()
|
con = userServiceInstance.getConsoleConnection()
|
||||||
@ -85,7 +86,15 @@ class SPICETransport(BaseSpiceTransport):
|
|||||||
port: str = con['port'] or '-1'
|
port: str = con['port'] or '-1'
|
||||||
secure_port: str = con['secure_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.usb_auto_share = self.usbShare.isTrue()
|
||||||
r.new_usb_auto_share = self.autoNewUsbShare.isTrue()
|
r.new_usb_auto_share = self.autoNewUsbShare.isTrue()
|
||||||
r.smartcard = self.smartCardRedirect.isTrue()
|
r.smartcard = self.smartCardRedirect.isTrue()
|
||||||
@ -93,11 +102,13 @@ class SPICETransport(BaseSpiceTransport):
|
|||||||
osName = {
|
osName = {
|
||||||
OsDetector.Windows: 'windows',
|
OsDetector.Windows: 'windows',
|
||||||
OsDetector.Linux: 'linux',
|
OsDetector.Linux: 'linux',
|
||||||
OsDetector.Macintosh: 'macosx'
|
OsDetector.Macintosh: 'macosx',
|
||||||
}.get(os['OS'])
|
}.get(os['OS'])
|
||||||
|
|
||||||
if osName is None:
|
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
|
# if sso: # If SSO requested, and when supported by platform
|
||||||
# userServiceInstance.desktopLogin(user, password, '')
|
# userServiceInstance.desktopLogin(user, password, '')
|
||||||
|
@ -54,6 +54,7 @@ class BaseSpiceTransport(transports.Transport):
|
|||||||
Provides access via SPICE to service.
|
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
|
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'
|
iconFile = 'spice.png'
|
||||||
protocol = protocols.SPICE
|
protocol = protocols.SPICE
|
||||||
|
|
||||||
@ -61,54 +62,56 @@ class BaseSpiceTransport(transports.Transport):
|
|||||||
order=1,
|
order=1,
|
||||||
label=_('Empty credentials'),
|
label=_('Empty credentials'),
|
||||||
tooltip=_('If checked, the credentials used to connect will be emtpy'),
|
tooltip=_('If checked, the credentials used to connect will be emtpy'),
|
||||||
tab=gui.CREDENTIALS_TAB
|
tab=gui.CREDENTIALS_TAB,
|
||||||
)
|
)
|
||||||
fixedName = gui.TextField(
|
fixedName = gui.TextField(
|
||||||
order=2,
|
order=2,
|
||||||
label=_('Username'),
|
label=_('Username'),
|
||||||
tooltip=_('If not empty, this username will be always used as credential'),
|
tooltip=_('If not empty, this username will be always used as credential'),
|
||||||
tab=gui.CREDENTIALS_TAB
|
tab=gui.CREDENTIALS_TAB,
|
||||||
)
|
)
|
||||||
fixedPassword = gui.PasswordField(
|
fixedPassword = gui.PasswordField(
|
||||||
order=3,
|
order=3,
|
||||||
label=_('Password'),
|
label=_('Password'),
|
||||||
tooltip=_('If not empty, this password will be always used as credential'),
|
tooltip=_('If not empty, this password will be always used as credential'),
|
||||||
tab=gui.CREDENTIALS_TAB
|
tab=gui.CREDENTIALS_TAB,
|
||||||
)
|
)
|
||||||
serverCertificate = gui.TextField(
|
serverCertificate = gui.TextField(
|
||||||
order=4,
|
order=4,
|
||||||
length=4096,
|
length=4096,
|
||||||
multiline=4,
|
multiline=4,
|
||||||
label=_('Certificate'),
|
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).'),
|
tooltip=_(
|
||||||
required=False
|
'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(
|
fullScreen = gui.CheckBoxField(
|
||||||
order=5,
|
order=5,
|
||||||
label=_('Fullscreen Mode'),
|
label=_('Fullscreen Mode'),
|
||||||
tooltip=_('If checked, viewer will be shown on fullscreen mode-'),
|
tooltip=_('If checked, viewer will be shown on fullscreen mode-'),
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
smartCardRedirect = gui.CheckBoxField(
|
smartCardRedirect = gui.CheckBoxField(
|
||||||
order=6,
|
order=6,
|
||||||
label=_('Smartcard Redirect'),
|
label=_('Smartcard Redirect'),
|
||||||
tooltip=_('If checked, SPICE protocol will allow smartcard redirection.'),
|
tooltip=_('If checked, SPICE protocol will allow smartcard redirection.'),
|
||||||
defvalue=gui.FALSE,
|
defvalue=gui.FALSE,
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
usbShare = gui.CheckBoxField(
|
usbShare = gui.CheckBoxField(
|
||||||
order=7,
|
order=7,
|
||||||
label=_('Enable USB'),
|
label=_('Enable USB'),
|
||||||
tooltip=_('If checked, USB redirection will be allowed.'),
|
tooltip=_('If checked, USB redirection will be allowed.'),
|
||||||
defvalue=gui.FALSE,
|
defvalue=gui.FALSE,
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
autoNewUsbShare = gui.CheckBoxField(
|
autoNewUsbShare = gui.CheckBoxField(
|
||||||
order=8,
|
order=8,
|
||||||
label=_('New USB Auto Sharing'),
|
label=_('New USB Auto Sharing'),
|
||||||
tooltip=_('Auto-redirect USB devices when plugged in.'),
|
tooltip=_('Auto-redirect USB devices when plugged in.'),
|
||||||
defvalue=gui.FALSE,
|
defvalue=gui.FALSE,
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool:
|
def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool:
|
||||||
@ -117,7 +120,9 @@ class BaseSpiceTransport(transports.Transport):
|
|||||||
"""
|
"""
|
||||||
ready = self.cache.get(ip)
|
ready = self.cache.get(ip)
|
||||||
if ready is None:
|
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()
|
con = userServiceInstance.getConsoleConnection()
|
||||||
|
|
||||||
logger.debug('Connection data: %s', con)
|
logger.debug('Connection data: %s', con)
|
||||||
@ -130,13 +135,19 @@ class BaseSpiceTransport(transports.Transport):
|
|||||||
# test ANY of the ports
|
# test ANY of the ports
|
||||||
port_to_test = port if port != -1 else secure_port
|
port_to_test = port if port != -1 else secure_port
|
||||||
if port_to_test == -1:
|
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)
|
logger.info('SPICE didn\'t find has any port: %s', con)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.cache.put('cachedMsg',
|
self.cache.put(
|
||||||
'Could not reach server "{}" on port "{}" from broker (prob. causes are name resolution & firewall rules)'.format(con['address'], port_to_test),
|
'cachedMsg',
|
||||||
120)
|
'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:
|
if self.testServer(userService, con['address'], port_to_test) is True:
|
||||||
self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT)
|
self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT)
|
||||||
@ -144,17 +155,25 @@ class BaseSpiceTransport(transports.Transport):
|
|||||||
|
|
||||||
return ready == 'Y'
|
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')
|
msg = self.cache.get('cachedMsg')
|
||||||
if msg is None:
|
if msg is None:
|
||||||
return transports.Transport.getCustomAvailableErrorMsg(self, userService, ip)
|
return transports.Transport.getCustomAvailableErrorMsg(
|
||||||
|
self, userService, ip
|
||||||
|
)
|
||||||
return msg
|
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, '')
|
v = self.processUserPassword(userService, user, '')
|
||||||
return v['username']
|
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()
|
username = user.getUsernameForAuth()
|
||||||
|
|
||||||
if self.fixedName.value:
|
if self.fixedName.value:
|
||||||
@ -172,19 +191,23 @@ class BaseSpiceTransport(transports.Transport):
|
|||||||
return {'protocol': self.protocol, 'username': username, 'password': password}
|
return {'protocol': self.protocol, 'username': username, 'password': password}
|
||||||
|
|
||||||
def getConnectionInfo(
|
def getConnectionInfo(
|
||||||
self,
|
self,
|
||||||
userService: typing.Union['models.UserService', 'models.ServicePool'],
|
userService: typing.Union['models.UserService', 'models.ServicePool'],
|
||||||
user: 'models.User',
|
user: 'models.User',
|
||||||
password: str
|
password: str,
|
||||||
) -> typing.Dict[str, str]:
|
) -> typing.Dict[str, str]:
|
||||||
return self.processUserPassword(userService, user, password)
|
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
|
# Reads script
|
||||||
scriptNameTemplate = scriptNameTemplate.format(osName)
|
scriptNameTemplate = scriptNameTemplate.format(osName)
|
||||||
with open(os.path.join(os.path.dirname(__file__), scriptNameTemplate)) as f:
|
with open(os.path.join(os.path.dirname(__file__), scriptNameTemplate)) as f:
|
||||||
script = f.read()
|
script = f.read()
|
||||||
# Reads signature
|
# 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()
|
signature = f.read()
|
||||||
return script, signature, params
|
return script, signature, params
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
# may be executed on old python version
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import errno
|
import errno
|
||||||
import pwd
|
import pwd
|
||||||
import six
|
|
||||||
|
|
||||||
USER = '__USER__'
|
USER = '__USER__'
|
||||||
KEY = '__KEY__'
|
KEY = '__KEY__'
|
||||||
|
@ -17,9 +17,21 @@ filename = tools.saveTempFile(theFile)
|
|||||||
|
|
||||||
executable = tools.findApp('x2goclient')
|
executable = tools.findApp('x2goclient')
|
||||||
if executable is None:
|
if executable is None:
|
||||||
raise Exception('''<p>You must have installed latest X2GO Client in order to connect to this UDS service.</p>
|
raise Exception(
|
||||||
<p>Please, install the required packages for your platform</p>''')
|
'''<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(filename)
|
||||||
# tools.addFileToUnlink(keyFile)
|
# tools.addFileToUnlink(keyFile)
|
||||||
|
@ -15,7 +15,9 @@ fs = forward(remote=(sp['tunHost'], int(sp['tunPort'])), ticket=sp['ticket'], ti
|
|||||||
|
|
||||||
# Check that tunnel works..
|
# Check that tunnel works..
|
||||||
if fs.check() is False:
|
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;'
|
home = expanduser('~') + ':1;/media:1;'
|
||||||
keyFile = tools.saveTempFile(sp['key']) # type: ignore
|
keyFile = tools.saveTempFile(sp['key']) # type: ignore
|
||||||
@ -26,7 +28,19 @@ filename = tools.saveTempFile(theFile)
|
|||||||
|
|
||||||
executable = tools.findApp('x2goclient')
|
executable = tools.findApp('x2goclient')
|
||||||
if executable is None:
|
if executable is None:
|
||||||
raise Exception('''<p>You must have installed latest X2GO Client in order to connect to this UDS service.</p>
|
raise Exception(
|
||||||
<p>Please, install the required packages for your platform</p>''')
|
'''<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'
|
x2goPath = os.environ['PROGRAMFILES(X86)'] + '\\x2goclient'
|
||||||
executable = tools.findApp('x2goclient.exe', [x2goPath])
|
executable = tools.findApp('x2goclient.exe', [x2goPath])
|
||||||
if executable is None:
|
if executable is None:
|
||||||
raise Exception('''<p>You must have installed latest X2GO Client in order to connect to this UDS service.</p>
|
raise Exception(
|
||||||
<p>You can download it for windows from <a href="http://wiki.x2go.org/doku.php">X2Go Site</a>.</p>''')
|
'''<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
|
# 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(filename)
|
||||||
# tools.addFileToUnlink(keyFile)
|
# tools.addFileToUnlink(keyFile)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# This is a template
|
# This is a template
|
||||||
# Saved as .py for easier editing
|
# 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
|
# 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..
|
# Check that tunnel works..
|
||||||
if fs.check() is False:
|
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
|
# Care, expanduser is encoding using "mcbs", so treat it as bytes on python 2.7
|
||||||
home = expanduser('~').replace('\\', '\\\\') + '#1;'
|
home = expanduser('~').replace('\\', '\\\\') + '#1;'
|
||||||
@ -27,7 +29,19 @@ filename = tools.saveTempFile(theFile)
|
|||||||
x2goPath = os.environ['PROGRAMFILES(X86)'] + '\\x2goclient'
|
x2goPath = os.environ['PROGRAMFILES(X86)'] + '\\x2goclient'
|
||||||
executable = tools.findApp('x2goclient.exe', [x2goPath])
|
executable = tools.findApp('x2goclient.exe', [x2goPath])
|
||||||
if executable is None:
|
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>
|
raise Exception(
|
||||||
<p>You can download it for windows from <a href="http://wiki.x2go.org/doku.php">X2Go Site</a>.</p>''')
|
'''<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.
|
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
|
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')
|
typeName = _('X2Go')
|
||||||
typeType = 'X2GOTransport'
|
typeType = 'X2GOTransport'
|
||||||
typeDescription = _('X2Go access (Experimental). Direct connection.')
|
typeDescription = _('X2Go access (Experimental). Direct connection.')
|
||||||
@ -69,15 +70,15 @@ class X2GOTransport(BaseX2GOTransport):
|
|||||||
quality = BaseX2GOTransport.quality
|
quality = BaseX2GOTransport.quality
|
||||||
|
|
||||||
def getUDSTransportScript( # pylint: disable=too-many-locals
|
def getUDSTransportScript( # pylint: disable=too-many-locals
|
||||||
self,
|
self,
|
||||||
userService: 'models.UserService',
|
userService: 'models.UserService',
|
||||||
transport: 'models.Transport',
|
transport: 'models.Transport',
|
||||||
ip: str,
|
ip: str,
|
||||||
os: typing.Dict[str, str],
|
os: typing.Dict[str, str],
|
||||||
user: 'models.User',
|
user: 'models.User',
|
||||||
password: str,
|
password: str,
|
||||||
request: 'HttpRequest'
|
request: 'HttpRequest',
|
||||||
) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]:
|
) -> typing.Tuple[str, str, typing.Mapping[str, typing.Any]]:
|
||||||
ci = self.getConnectionInfo(userService, user, password)
|
ci = self.getConnectionInfo(userService, user, password)
|
||||||
username = ci['username']
|
username = ci['username']
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ class X2GOTransport(BaseX2GOTransport):
|
|||||||
rootless=rootless,
|
rootless=rootless,
|
||||||
width=width,
|
width=width,
|
||||||
height=height,
|
height=height,
|
||||||
user=username
|
user=username,
|
||||||
)
|
)
|
||||||
|
|
||||||
osName = {
|
osName = {
|
||||||
@ -111,13 +112,10 @@ class X2GOTransport(BaseX2GOTransport):
|
|||||||
}.get(os['OS'])
|
}.get(os['OS'])
|
||||||
|
|
||||||
if osName is None:
|
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 = {
|
sp = {'ip': ip, 'port': '22', 'key': priv, 'xf': xf}
|
||||||
'ip': ip,
|
|
||||||
'port': '22',
|
|
||||||
'key': priv,
|
|
||||||
'xf': xf
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.getScript('scripts/{}/direct.py', osName, sp)
|
return self.getScript('scripts/{}/direct.py', osName, sp)
|
||||||
|
@ -60,6 +60,7 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
Provides access via X2GO to service.
|
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
|
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'
|
iconFile = 'x2go.png'
|
||||||
protocol = transports.protocols.X2GO
|
protocol = transports.protocols.X2GO
|
||||||
supportedOss = (OsDetector.Linux, OsDetector.Windows)
|
supportedOss = (OsDetector.Linux, OsDetector.Windows)
|
||||||
@ -68,7 +69,7 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
order=2,
|
order=2,
|
||||||
label=_('Username'),
|
label=_('Username'),
|
||||||
tooltip=_('If not empty, this username will be always used as credential'),
|
tooltip=_('If not empty, this username will be always used as credential'),
|
||||||
tab=gui.CREDENTIALS_TAB
|
tab=gui.CREDENTIALS_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
screenSize = gui.ChoiceField(
|
screenSize = gui.ChoiceField(
|
||||||
@ -82,9 +83,9 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
{'id': CommonPrefs.SZ_1024x768, 'text': '1024x768'},
|
{'id': CommonPrefs.SZ_1024x768, 'text': '1024x768'},
|
||||||
{'id': CommonPrefs.SZ_1366x768, 'text': '1366x768'},
|
{'id': CommonPrefs.SZ_1366x768, 'text': '1366x768'},
|
||||||
{'id': CommonPrefs.SZ_1920x1080, 'text': '1920x1080'},
|
{'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(
|
desktopType = gui.ChoiceField(
|
||||||
@ -102,14 +103,16 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
{'id': 'gnome-session-cinnamon2d', 'text': 'Cinnamon 2.2 (see docs)'},
|
{'id': 'gnome-session-cinnamon2d', 'text': 'Cinnamon 2.2 (see docs)'},
|
||||||
{'id': 'UDSVAPP', 'text': 'UDS vAPP'},
|
{'id': 'UDSVAPP', 'text': 'UDS vAPP'},
|
||||||
],
|
],
|
||||||
tab=gui.PARAMETERS_TAB
|
tab=gui.PARAMETERS_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
customCmd = gui.TextField(
|
customCmd = gui.TextField(
|
||||||
order=12,
|
order=12,
|
||||||
label=_('vAPP'),
|
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.'),
|
tooltip=_(
|
||||||
tab=gui.PARAMETERS_TAB
|
'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(
|
sound = gui.CheckBoxField(
|
||||||
@ -117,15 +120,17 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
label=_('Enable sound'),
|
label=_('Enable sound'),
|
||||||
tooltip=_('If checked, sound will be available'),
|
tooltip=_('If checked, sound will be available'),
|
||||||
defvalue=gui.TRUE,
|
defvalue=gui.TRUE,
|
||||||
tab=gui.PARAMETERS_TAB
|
tab=gui.PARAMETERS_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
exports = gui.CheckBoxField(
|
exports = gui.CheckBoxField(
|
||||||
order=14,
|
order=14,
|
||||||
label=_('Redirect home folder'),
|
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,
|
defvalue=gui.FALSE,
|
||||||
tab=gui.PARAMETERS_TAB
|
tab=gui.PARAMETERS_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
speed = gui.ChoiceField(
|
speed = gui.ChoiceField(
|
||||||
@ -140,7 +145,7 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
{'id': '3', 'text': 'WAN'},
|
{'id': '3', 'text': 'WAN'},
|
||||||
{'id': '4', 'text': 'LAN'},
|
{'id': '4', 'text': 'LAN'},
|
||||||
],
|
],
|
||||||
tab=gui.PARAMETERS_TAB
|
tab=gui.PARAMETERS_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
soundType = gui.ChoiceField(
|
soundType = gui.ChoiceField(
|
||||||
@ -152,7 +157,7 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
{'id': 'pulse', 'text': 'Pulse'},
|
{'id': 'pulse', 'text': 'Pulse'},
|
||||||
{'id': 'esd', 'text': 'ESD'},
|
{'id': 'esd', 'text': 'ESD'},
|
||||||
],
|
],
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
keyboardLayout = gui.TextField(
|
keyboardLayout = gui.TextField(
|
||||||
@ -160,7 +165,7 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
order=31,
|
order=31,
|
||||||
tooltip=_('Keyboard layout (es, us, fr, ...). Empty value means autodetect.'),
|
tooltip=_('Keyboard layout (es, us, fr, ...). Empty value means autodetect.'),
|
||||||
defvalue='',
|
defvalue='',
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
# 'nopack', '8', '64', '256', '512', '4k', '32k', '64k', '256k', '2m', '16m'
|
# 'nopack', '8', '64', '256', '512', '4k', '32k', '64k', '256k', '2m', '16m'
|
||||||
# '256-rdp', '256-rdp-compressed', '32k-rdp', '32k-rdp-compressed', '64k-rdp'
|
# '256-rdp', '256-rdp-compressed', '32k-rdp', '32k-rdp-compressed', '64k-rdp'
|
||||||
@ -180,7 +185,7 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
order=32,
|
order=32,
|
||||||
tooltip=_('Pack format. Change with care!'),
|
tooltip=_('Pack format. Change with care!'),
|
||||||
defvalue='16m-jpeg',
|
defvalue='16m-jpeg',
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
quality = gui.NumericField(
|
quality = gui.NumericField(
|
||||||
@ -192,7 +197,7 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
minValue=1,
|
minValue=1,
|
||||||
maxValue=9,
|
maxValue=9,
|
||||||
required=True,
|
required=True,
|
||||||
tab=gui.ADVANCED_TAB
|
tab=gui.ADVANCED_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool:
|
def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool:
|
||||||
@ -213,11 +218,18 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
def getScreenSize(self) -> typing.Tuple[int, int]:
|
def getScreenSize(self) -> typing.Tuple[int, int]:
|
||||||
return CommonPrefs.getWidthHeight(self.screenSize.value)
|
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, '')
|
v = self.processUserPassword(userService, user, '')
|
||||||
return v['username']
|
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()
|
username = user.getUsernameForAuth()
|
||||||
|
|
||||||
if self.fixedName.value != '':
|
if self.fixedName.value != '':
|
||||||
@ -229,11 +241,11 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
return {'protocol': self.protocol, 'username': username, 'password': ''}
|
return {'protocol': self.protocol, 'username': username, 'password': ''}
|
||||||
|
|
||||||
def getConnectionInfo(
|
def getConnectionInfo(
|
||||||
self,
|
self,
|
||||||
userService: typing.Union['models.UserService', 'models.ServicePool'],
|
userService: typing.Union['models.UserService', 'models.ServicePool'],
|
||||||
user: 'models.User',
|
user: 'models.User',
|
||||||
password: str
|
password: str,
|
||||||
) -> typing.Dict[str, str]:
|
) -> typing.Dict[str, str]:
|
||||||
return self.processUserPassword(userService, user, password)
|
return self.processUserPassword(userService, user, password)
|
||||||
|
|
||||||
def genKeyPairForSsh(self) -> typing.Tuple[str, str]:
|
def genKeyPairForSsh(self) -> typing.Tuple[str, str]:
|
||||||
@ -264,18 +276,24 @@ class BaseX2GOTransport(transports.Transport):
|
|||||||
|
|
||||||
return data.replace('__USER__', user).replace('__KEY__', pubKey)
|
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()
|
priv, pub = self.genKeyPairForSsh()
|
||||||
authScript = self.getAuthorizeScript(userName, pub)
|
authScript = self.getAuthorizeScript(userName, pub)
|
||||||
userServiceManager().sendScript(userService, authScript)
|
userServiceManager().sendScript(userService, authScript)
|
||||||
return priv, pub
|
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
|
# Reads script
|
||||||
scriptNameTemplate = scriptNameTemplate.format(osName)
|
scriptNameTemplate = scriptNameTemplate.format(osName)
|
||||||
with open(os.path.join(os.path.dirname(__file__), scriptNameTemplate)) as f:
|
with open(os.path.join(os.path.dirname(__file__), scriptNameTemplate)) as f:
|
||||||
script = f.read()
|
script = f.read()
|
||||||
# Reads signature
|
# 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()
|
signature = f.read()
|
||||||
return script, signature, params
|
return script, signature, params
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Virtual Cable S.L.
|
# Copyright (c) 2016-2021 Virtual Cable S.L.U.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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,
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
# and/or other materials provided with the distribution.
|
# 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
|
# may be used to endorse or promote products derived from this software
|
||||||
# without specific prior written permission.
|
# 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'
|
trueFalse = lambda x: 'true' if x else 'false'
|
||||||
export = 'export="{export}"' if exports else ''
|
export = 'export="{export}"' if exports else ''
|
||||||
if width == -1 or height == -1:
|
if width == -1 or height == -1:
|
||||||
@ -116,5 +128,5 @@ def getTemplate(speed, pack, quality, sound, soundSystem, windowManager, exports
|
|||||||
width=width,
|
width=width,
|
||||||
height=height,
|
height=height,
|
||||||
fullscreen=fullscreen,
|
fullscreen=fullscreen,
|
||||||
user=user
|
user=user,
|
||||||
)
|
)
|
||||||
|
@ -96,7 +96,6 @@ class TX2GOTransport(BaseX2GOTransport):
|
|||||||
tab=gui.TUNNEL_TAB,
|
tab=gui.TUNNEL_TAB,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
fixedName = BaseX2GOTransport.fixedName
|
fixedName = BaseX2GOTransport.fixedName
|
||||||
screenSize = BaseX2GOTransport.screenSize
|
screenSize = BaseX2GOTransport.screenSize
|
||||||
desktopType = BaseX2GOTransport.desktopType
|
desktopType = BaseX2GOTransport.desktopType
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2012 Virtual Cable S.L.
|
# Copyright (c) 2012-2021 Virtual Cable S.L.U.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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,
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
# and/or other materials provided with the distribution.
|
# 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
|
# may be used to endorse or promote products derived from this software
|
||||||
# without specific prior written permission.
|
# without specific prior written permission.
|
||||||
#
|
#
|
||||||
@ -48,6 +48,7 @@ import sys
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def __init__():
|
def __init__():
|
||||||
"""
|
"""
|
||||||
This imports all packages that are descendant of this package, and, after that,
|
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]):
|
for _, name, _ in pkgutil.iter_modules([pkgpath]):
|
||||||
# __import__(name, globals(), locals(), [], 1)
|
# __import__(name, globals(), locals(), [], 1)
|
||||||
importlib.import_module('.' + name, __name__) # import module
|
importlib.import_module('.' + name, __name__) # import module
|
||||||
|
|
||||||
importlib.invalidate_caches()
|
importlib.invalidate_caches()
|
||||||
|
|
||||||
# This is marked as error in IDE, but it's not (__subclasses__)
|
# This is marked as error in IDE, but it's not (__subclasses__)
|
||||||
|
Loading…
Reference in New Issue
Block a user