mirror of
https://github.com/dkmstr/openuds.git
synced 2024-12-22 13:34:04 +03:00
Adding support for teams optimizations on virtual machines. To be tested!!!
This commit is contained in:
parent
d81b68eaa7
commit
a38716e1b0
@ -42,6 +42,9 @@ class ServiceException(UDSException):
|
||||
"""
|
||||
Base class for all service exceptions
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Eats "kwargs" to avoid "unexpected keyword argument" error
|
||||
super().__init__(*args)
|
||||
|
||||
|
||||
class UnsupportedException(ServiceException):
|
||||
|
@ -94,6 +94,7 @@ class RDPTransport(BaseRDPTransport):
|
||||
customParameters = BaseRDPTransport.customParameters
|
||||
customParametersMAC = BaseRDPTransport.customParametersMAC
|
||||
customParametersWindows = BaseRDPTransport.customParametersWindows
|
||||
optimizeTeams = BaseRDPTransport.optimizeTeams
|
||||
|
||||
def getUDSTransportScript( # pylint: disable=too-many-locals
|
||||
self,
|
||||
@ -145,6 +146,7 @@ class RDPTransport(BaseRDPTransport):
|
||||
r.printerString = self.printerString.value
|
||||
r.enforcedShares = self.enforceDrives.value
|
||||
r.redirectUSB = self.usbRedirection.value
|
||||
r.optimizeTeams = self.optimizeTeams.isTrue()
|
||||
|
||||
sp: typing.MutableMapping[str, typing.Any] = {
|
||||
'password': password,
|
||||
@ -154,16 +156,17 @@ class RDPTransport(BaseRDPTransport):
|
||||
'address': r.address,
|
||||
}
|
||||
|
||||
if os == os_detector.KnownOS.WINDOWS:
|
||||
if os.os == os_detector.KnownOS.WINDOWS:
|
||||
r.customParameters = self.customParametersWindows.value
|
||||
if password:
|
||||
r.password = '{password}' # nosec: password is not hardcoded
|
||||
sp.update(
|
||||
{
|
||||
'as_file': r.as_file,
|
||||
'optimize_teams': self.optimizeTeams.isTrue(),
|
||||
}
|
||||
)
|
||||
elif os == os_detector.KnownOS.LINUX:
|
||||
elif os.os == os_detector.KnownOS.LINUX:
|
||||
r.customParameters = self.customParameters.value
|
||||
sp.update(
|
||||
{
|
||||
@ -171,7 +174,7 @@ class RDPTransport(BaseRDPTransport):
|
||||
'address': r.address,
|
||||
}
|
||||
)
|
||||
elif os == os_detector.KnownOS.MAC_OS:
|
||||
elif os.os == os_detector.KnownOS.MAC_OS:
|
||||
r.customParameters = self.customParametersMAC.value
|
||||
sp.update(
|
||||
{
|
||||
|
@ -87,9 +87,7 @@ class BaseRDPTransport(transports.Transport):
|
||||
fixedDomain = gui.TextField(
|
||||
label=_('Domain'),
|
||||
order=15,
|
||||
tooltip=_(
|
||||
'If not empty, this domain will be always used as credential (used as DOMAIN\\user)'
|
||||
),
|
||||
tooltip=_('If not empty, this domain will be always used as credential (used as DOMAIN\\user)'),
|
||||
tab=gui.Tab.CREDENTIALS,
|
||||
)
|
||||
|
||||
@ -265,34 +263,26 @@ class BaseRDPTransport(transports.Transport):
|
||||
multimedia = gui.CheckBoxField(
|
||||
label=_('Multimedia sync'),
|
||||
order=40,
|
||||
tooltip=_(
|
||||
'If checked. Linux client will use multimedia parameter for xfreerdp'
|
||||
),
|
||||
tooltip=_('If checked. Linux client will use multimedia parameter for xfreerdp'),
|
||||
tab='Linux Client',
|
||||
)
|
||||
alsa = gui.CheckBoxField(
|
||||
label=_('Use Alsa'),
|
||||
order=41,
|
||||
tooltip=_(
|
||||
'If checked, Linux client will try to use ALSA, otherwise Pulse will be used'
|
||||
),
|
||||
tooltip=_('If checked, Linux client will try to use ALSA, otherwise Pulse will be used'),
|
||||
tab='Linux Client',
|
||||
)
|
||||
printerString = gui.TextField(
|
||||
label=_('Printer string'),
|
||||
order=43,
|
||||
tooltip=_(
|
||||
'If printer is checked, the printer string used with xfreerdp client'
|
||||
),
|
||||
tooltip=_('If printer is checked, the printer string used with xfreerdp client'),
|
||||
tab='Linux Client',
|
||||
length=256,
|
||||
)
|
||||
smartcardString = gui.TextField(
|
||||
label=_('Smartcard string'),
|
||||
order=44,
|
||||
tooltip=_(
|
||||
'If smartcard is checked, the smartcard string used with xfreerdp client'
|
||||
),
|
||||
tooltip=_('If smartcard is checked, the smartcard string used with xfreerdp client'),
|
||||
tab='Linux Client',
|
||||
length=256,
|
||||
)
|
||||
@ -309,9 +299,7 @@ class BaseRDPTransport(transports.Transport):
|
||||
allowMacMSRDC = gui.CheckBoxField(
|
||||
label=_('Allow Microsoft Rdp Client'),
|
||||
order=50,
|
||||
tooltip=_(
|
||||
'If checked, allows use of Microsoft Remote Desktop Client. PASSWORD WILL BE PROMPTED!'
|
||||
),
|
||||
tooltip=_('If checked, allows use of Microsoft Remote Desktop Client. PASSWORD WILL BE PROMPTED!'),
|
||||
tab='Mac OS X',
|
||||
defvalue=gui.FALSE,
|
||||
)
|
||||
@ -329,14 +317,18 @@ class BaseRDPTransport(transports.Transport):
|
||||
customParametersWindows = gui.TextField(
|
||||
label=_('Custom parameters'),
|
||||
order=45,
|
||||
tooltip=_(
|
||||
'If not empty, extra parameters to include for Windows Client'
|
||||
),
|
||||
tooltip=_('If not empty, extra parameters to include for Windows Client'),
|
||||
length=4096,
|
||||
multiline=10,
|
||||
tab='Windows Client',
|
||||
)
|
||||
|
||||
optimizeTeams = gui.CheckBoxField(
|
||||
label=_('Optimize Teams'),
|
||||
order=46,
|
||||
tooltip=_('If checked, Teams will be optimized (only works on Windows clients)'),
|
||||
tab='Windows Client',
|
||||
)
|
||||
|
||||
def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool:
|
||||
"""
|
||||
@ -353,9 +345,7 @@ class BaseRDPTransport(transports.Transport):
|
||||
self.cache.put(ip, 'N', READY_CACHE_TIMEOUT)
|
||||
return ready == 'Y'
|
||||
|
||||
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, '', altUsername=None)
|
||||
return v['username']
|
||||
|
||||
@ -412,6 +402,9 @@ class BaseRDPTransport(transports.Transport):
|
||||
if azureAd:
|
||||
username = 'AzureAD\\' + username
|
||||
|
||||
if self.optimizeTeams.isTrue():
|
||||
password = '' # nosec
|
||||
|
||||
return {
|
||||
'protocol': self.protocol,
|
||||
'username': username,
|
||||
@ -425,7 +418,6 @@ class BaseRDPTransport(transports.Transport):
|
||||
user: 'models.User',
|
||||
password: str,
|
||||
) -> typing.Mapping[str, str]:
|
||||
|
||||
username = None
|
||||
if isinstance(userService, UserService):
|
||||
cdata = userService.getInstance().getConnectionData()
|
||||
|
@ -71,6 +71,7 @@ class RDPFile:
|
||||
enableClipboard = False
|
||||
customParameters: typing.Optional[str] = None
|
||||
enforcedShares: typing.Optional[str] = None
|
||||
optimizeTeams = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -193,7 +194,7 @@ class RDPFile:
|
||||
params += shlex.split(self.customParameters.strip())
|
||||
|
||||
# On MacOSX, /rfx /gfx:rfx are almost inprescindible, as it seems the only way to get a decent performance
|
||||
if self.target == OsDetector.KnownOS.Macintosh:
|
||||
if self.target == OsDetector.KnownOS.MAC_OS:
|
||||
for i in ('/rfx', '/gfx:rfx'):
|
||||
if i not in params:
|
||||
params.append(i)
|
||||
@ -233,7 +234,7 @@ class RDPFile:
|
||||
if self.username:
|
||||
res += 'username:s:' + self.username + '\n'
|
||||
res += 'domain:s:' + self.domain + '\n'
|
||||
if self.target == OsDetector.KnownOS.WINDOWS:
|
||||
if self.target == OsDetector.KnownOS.WINDOWS and not self.optimizeTeams:
|
||||
res += 'password 51:b:' + password + '\n'
|
||||
|
||||
res += 'alternate shell:s:' + '\n'
|
||||
|
@ -131,6 +131,7 @@ class TRDPTransport(BaseRDPTransport):
|
||||
customParameters = BaseRDPTransport.customParameters
|
||||
customParametersMAC = BaseRDPTransport.customParametersMAC
|
||||
customParametersWindows = BaseRDPTransport.customParametersWindows
|
||||
optimizeTeams = BaseRDPTransport.optimizeTeams
|
||||
|
||||
def initialize(self, values: 'Module.ValuesType'):
|
||||
if values:
|
||||
@ -193,6 +194,7 @@ class TRDPTransport(BaseRDPTransport):
|
||||
r.printerString = self.printerString.value
|
||||
r.enforcedShares = self.enforceDrives.value
|
||||
r.redirectUSB = self.usbRedirection.value
|
||||
r.optimizeTeams = self.optimizeTeams.isTrue()
|
||||
|
||||
sp: typing.MutableMapping[str, typing.Any] = {
|
||||
'tunHost': tunHost,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import subprocess
|
||||
import os
|
||||
import subprocess # nosec: B404
|
||||
import win32crypt # type: ignore
|
||||
import codecs
|
||||
|
||||
@ -23,27 +24,39 @@ except Exception:
|
||||
).decode()
|
||||
|
||||
try:
|
||||
key = wreg.OpenKey(
|
||||
wreg.HKEY_CURRENT_USER,
|
||||
key = wreg.OpenKey( # type: ignore
|
||||
wreg.HKEY_CURRENT_USER, # type: ignore
|
||||
'Software\\Microsoft\\Terminal Server Client\\LocalDevices',
|
||||
0,
|
||||
wreg.KEY_SET_VALUE,
|
||||
wreg.KEY_SET_VALUE, # type: ignore
|
||||
)
|
||||
wreg.SetValueEx(key, sp['ip'], 0, wreg.REG_DWORD, 255) # type: ignore
|
||||
wreg.CloseKey(key)
|
||||
except Exception as e:
|
||||
wreg.CloseKey(key) # type: ignore
|
||||
except Exception as e: # nosec: Not really interested in the exception
|
||||
# logger.warn('Exception fixing redirection dialog: %s', e)
|
||||
pass # Key does not exists, ok...
|
||||
|
||||
# The password must be encoded, to be included in a .rdp file, as 'UTF-16LE' before protecting (CtrpyProtectData) it in order to work with mstsc
|
||||
theFile = sp['as_file'].format(password=password) # type: ignore
|
||||
filename = tools.saveTempFile(theFile)
|
||||
executable = tools.findApp('mstsc.exe')
|
||||
|
||||
if executable is None:
|
||||
raise Exception(
|
||||
'Unable to find mstsc.exe. Check that path points to your SYSTEM32 folder'
|
||||
)
|
||||
if sp['optimize_teams'] == True: # type: ignore
|
||||
try:
|
||||
h = wreg.OpenKey(wreg.HKEY_CLASSES_ROOT, '.rdp\OpenWithProgids', 0, wreg.KEY_READ) # type: ignore
|
||||
h.Close()
|
||||
except Exception:
|
||||
raise Exception('Required Microsoft RDP Client is not found. Please, install it from Microsoft store.')
|
||||
# Add .rdp to filename for open with
|
||||
os.rename(filename, filename + '.rdp')
|
||||
filename = filename + '.rdp'
|
||||
os.startfile(filename) # type: ignore # nosec
|
||||
else:
|
||||
executable = tools.findApp('mstsc.exe')
|
||||
if executable is None:
|
||||
raise Exception(
|
||||
'Unable to find mstsc.exe. Check that path points to your SYSTEM32 folder'
|
||||
)
|
||||
|
||||
subprocess.Popen([executable, filename])
|
||||
tools.addFileToUnlink(filename)
|
||||
subprocess.Popen([executable, filename]) # nosec
|
||||
|
||||
# tools.addFileToUnlink(filename)
|
||||
|
@ -1 +1 @@
|
||||
qKyGy2EIPrAzb4VsZ4fTAjMDyGb82LJXm+u04ro6IzddOyhEuPz1NleV3x8acIgPlx1K0A128voYabD78nQBfJ5Xm/TzPcwuN2qtjGtTTkc04urpsMwxVXjl4gsFAhY3G9KDqkg5Ik3wkskBDq1ahZI95uVufUejefl+r1J94g5VjhRUMVM3hctvPQFM4/6LY8VQrnGx19LGbHf4T1yUXrZMUeodReqkDBfWnJOqQOQ+9+USRxWlglgLNb/9zYbIn/Ca6qVyCsuYS1L9Gms/ioDVUd8R0jWxCCzmvHsVw9q0Lq3BZAqmFA8xonjpP+dVR53O2R/76/XY82f3vWQaL1oC5DJf5R29x6FFi9CbhRnmxfYZRjedNLYhUBeXL59SKYh83ZEqkzMmUha9j7lThVtidhk9PUPDaV8KlVJnoQwOTXrG/hfok181nvoPTt4QfADoxne4JeTWqrfDgNwLWhcpryY/yXfnUYEZChZOUqm5MF7raHsF5P3lZRazq1Zaces630pPgOfw8Zb/J2deUd0vf5BZnBgug5h6clibPude70iepv7Gt/9ks82hl7gFAYguY5AzeQFsQ9RVngmFoyQjYaAv+BSb9Z4Qbf+DB/gTCGZx7rn7YsZgD5PFaVAlRq0J6ZR3fRn88YSBliXh9HcD5CD/yRW6koXm3tTvLKo=
|
||||
hPF/H21BzZ0VU9HjimiOa1go9TJVsqmKsgGqB4V4X3cjB6G3NkSa1O45ub3gf+gOriElibPRbXzet4zma4qnBACLzAZQjmmxDRK9gC7eN6p0z0TKg18U6/hKf5gs6ICjQZyONg2gvBBrYUz7JhYoefq9SZRAna7373N0minKoJoBPLB+ylkemBNhKcsN5bRQlEGU03mLREGk/h642qN6ebQhIzY+JMo3c9CwtRS6SCiLhiaYkPFxdEX9e7AGSpTgGSFh4+Mc3QEge4sOquWszX4ocJJc23SHl5GdZSfhn3Bst5lLKILVUT5w7zaZOqa/xx/HjpCmxROJKm/bkR+HK8VMRh4N5c5yvavXid0IwgN8Uc+SOIUh4+wxbOyJI3ySS/77gUI/1TDw+r/gRkSUPwcRSFKuyQMN2yR6yr2BgOXlGmlNwZ/MzsDIIwgGeMlkKZZzLI64aj9VG2QsWHrlw2HWuFfBGGIX4T49p0tvdRm5o1jg/cdsLsHC8of5Vn4wgwyZwlScndDLcBJq76v4wnWUMg4IQpeOoI/PEbgeUfZDuntSt/ZT5icB78nN07hUo56d5Z5q1ktuWEHJSWCVSg59KGOcvaaPub50+anm6Uzac5rynZ0/gqA8Y0IV3dgRalBMZCiCy89lHW1YyO52A4DBka6hG4gKt5VUs+eT+vI=
|
@ -1,4 +1,5 @@
|
||||
import subprocess
|
||||
import os
|
||||
import subprocess # nosec
|
||||
import win32crypt # type: ignore
|
||||
import codecs
|
||||
|
||||
@ -16,21 +17,28 @@ fs = forward(remote=(sp['tunHost'], int(sp['tunPort'])), ticket=sp['ticket'], ti
|
||||
|
||||
# Check that tunnel works..
|
||||
if fs.check() is False:
|
||||
raise Exception(
|
||||
'<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>'
|
||||
)
|
||||
raise Exception('<p>Could not connect to tunnel server.</p><p>Please, check your network settings.</p>')
|
||||
|
||||
thePass = sp['password'].encode('UTF-16LE') # type: ignore
|
||||
|
||||
try:
|
||||
password = codecs.encode(
|
||||
win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01), 'hex'
|
||||
).decode()
|
||||
password = codecs.encode(win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01), 'hex').decode()
|
||||
except Exception:
|
||||
# Cannot encrypt for user, trying for machine
|
||||
password = codecs.encode(
|
||||
win32crypt.CryptProtectData(thePass, None, None, None, None, 0x05), 'hex'
|
||||
).decode()
|
||||
password = codecs.encode(win32crypt.CryptProtectData(thePass, None, None, None, None, 0x05), 'hex').decode()
|
||||
|
||||
try:
|
||||
key = wreg.OpenKey( # type: ignore
|
||||
wreg.HKEY_CURRENT_USER, # type: ignore
|
||||
'Software\\Microsoft\\Terminal Server Client\\LocalDevices',
|
||||
0,
|
||||
wreg.KEY_SET_VALUE, # type: ignore
|
||||
)
|
||||
wreg.SetValueEx(key, '127.0.0.1', 0, wreg.REG_DWORD, 255) # type: ignore
|
||||
wreg.CloseKey(key) # type: ignore
|
||||
except Exception as e: # nosec: Not really interested in the exception
|
||||
# logger.warn('Exception fixing redirection dialog: %s', e)
|
||||
pass # Key does not exists, but it's ok
|
||||
|
||||
# The password must be encoded, to be included in a .rdp file, as 'UTF-16LE' before protecting (CtrpyProtectData) it in order to work with mstsc
|
||||
theFile = sp['as_file'].format( # type: ignore
|
||||
@ -38,24 +46,27 @@ theFile = sp['as_file'].format( # type: ignore
|
||||
)
|
||||
|
||||
filename = tools.saveTempFile(theFile)
|
||||
|
||||
if sp['optimize_teams']: # type: ignore
|
||||
try:
|
||||
h = wreg.OpenKey(wreg.HKEY_CLASSES_ROOT, '.rdp\OpenWithProgids', 0, wreg.KEY_READ) # type: ignore
|
||||
h.Close()
|
||||
except Exception:
|
||||
raise Exception('<p>Required Microsoft RDP Client is not found.</p><p>Please, install it from <b>Microsoft store</b>.</p>')
|
||||
# Add .rdp to filename for open with
|
||||
os.rename(filename, filename + '.rdp')
|
||||
filename = filename + '.rdp'
|
||||
os.startfile(filename) # type: ignore # nosec
|
||||
else:
|
||||
executable = tools.findApp('mstsc.exe')
|
||||
if executable is None:
|
||||
raise Exception('Unable to find mstsc.exe. Check that path points to your SYSTEM32 folder')
|
||||
|
||||
subprocess.Popen([executable, filename]) # nosec
|
||||
|
||||
executable = tools.findApp('mstsc.exe')
|
||||
if executable is None:
|
||||
raise Exception(
|
||||
'Unable to find mstsc.exe. Check that path points to your SYSTEM32 folder'
|
||||
)
|
||||
raise Exception('Unable to find mstsc.exe. Check that path points to your SYSTEM32 folder')
|
||||
|
||||
try:
|
||||
key = wreg.OpenKey(
|
||||
wreg.HKEY_CURRENT_USER,
|
||||
'Software\\Microsoft\\Terminal Server Client\\LocalDevices',
|
||||
0,
|
||||
wreg.KEY_SET_VALUE,
|
||||
)
|
||||
wreg.SetValueEx(key, '127.0.0.1', 0, wreg.REG_DWORD, 255) # type: ignore
|
||||
wreg.CloseKey(key)
|
||||
except Exception as e:
|
||||
# logger.warn('Exception fixing redirection dialog: %s', e)
|
||||
pass # Key does not exists, but it's ok
|
||||
|
||||
subprocess.Popen([executable, filename])
|
||||
subprocess.Popen([executable, filename]) # nosec
|
||||
tools.addFileToUnlink(filename)
|
||||
|
@ -1 +1 @@
|
||||
RkbX3fRuVnznJL4dv27wDJw+x4T6kegHOPRrMF04TunfV+jQr6RBK1vqt6YqLL0FccxT7JLv/kHJJOkT5b//IYS9TIt/M5DdJtg/WaNpsPsaNRBIU8QiaF9zTcNnvz8Rc4XY7infR9puSwbMvEznoUovAd2YUEvj7MHWKozieQQpG/UBECUKFad+S5TgmXmC4RGBSf9Da3x+jvQ45VkhYIWvrfw5xd8dNGwCCJjohc49YvNxGguNWwa/1zB2SY6XjbDd+inHZ+13IR917uU7qYu44UlAUUW9Uazav2XNLOmLoBaDiWUy4hDM4CNvqlQeau8Ppq0SnhiGrvq9/MEbdOeHOMHJqXalA0pLCqTPj/4/4hqQw4POMNEWqAjMA59iGSe/8F9RSPPXHp1mYoQasDalSGoZEPVRYOZUlIECpKMEVCredFK7Vu9sy+yL+2amFr47L9aRNVpaVMwAyP3TukH1/SGL7lPxQXIzu2hoFd6kGLlyBF0CBbKTX9Xlk76fEObN/3dHfDEuK1O+OiwVyX3YMurH4fxvABqMJqRtT1ASSfjLXpKohIGEpUSWNkh2mu5a3OL6lLQxxwDY6WieKQtvJgPiPAOJRVk06CLOSRy7ghaCYH9yn6tShCPTAnRJmGLuttU4mt5fKOC6cHH8GJahRi5FtSuzLigszL5bCaY=
|
||||
KzlVV3agaa2aeHqWhx6myDpHRbc9YdkwfbkD00NkU+U4w09CTnvcVE4fYJWc4Xnu72EMWDqGS9kYac0MzlwFsUflEQbNBm4wq4LpqTqvDi9YilTCpQHo3auENL9pEnGLZmhM12EufDrrQiDkCSJWB45cwdt8sK0xyLflOBvwpkADWf+vzX7bM64Lz9STVyr3YYjYTCa6IOGZqybfsKUimNnIApF+LZeKhA+MuPdJ2+ml5XzoKjjLPl6FP/UNwWbKXQLbntXyZ6iJZAi9sBdQYXwjhiDWPZI4rmYnAAlpsa/K10JJV9Y2oYjM0qZp1bWp7Sq1TgwbbezM1eScD7aV8+qoFu/17HOZTYpnXA38b9s+JCsLrZEomf/AJcYrLNZ0C6NR9hnMSJaDxSSU8CPdYMbNBi2sKjhfL//DS9qFVEYjZqnf5aRQ22h4WC6GyckjFWhVskxS3jEOYvuznjetD7NS+a0kIAf+gF4+pZGey6I5OnE2//OL0KqrOco2uljibLTlpAUdjth8WCQQpb/APPzcQBNiWhASymDJDV/rTQyq6/L6GCTchw2eIXC2faNa6LCcllZ/ytnrorck89IzwverMPx/6TTKljb0yVX7aGxjEVatXLU+4ZWcsMGcAtpdGpO/GA0iNWwC2aZKKYdtDuaFpF5bJwAKGzcbTCliUWA=
|
Loading…
Reference in New Issue
Block a user