From cab09aea9c44105a0810f7deb053aaa92e06993a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Sat, 31 Oct 2020 07:21:01 +0100 Subject: [PATCH] Fixing up mac os RDP transport support --- server/src/uds/transports/RDP/rdp.py | 6 +- server/src/uds/transports/RDP/rdp_base.py | 2 + server/src/uds/transports/RDP/rdp_file.py | 77 ++++--------------- server/src/uds/transports/RDP/rdptunnel.py | 5 +- .../transports/RDP/scripts/macosx/direct.py | 33 ++++++-- .../RDP/scripts/macosx/direct.py.signature | 2 +- .../transports/RDP/scripts/macosx/tunnel.py | 36 +++++++-- .../RDP/scripts/macosx/tunnel.py.signature | 2 +- 8 files changed, 83 insertions(+), 80 deletions(-) diff --git a/server/src/uds/transports/RDP/rdp.py b/server/src/uds/transports/RDP/rdp.py index 571eab4b..3c640abd 100644 --- a/server/src/uds/transports/RDP/rdp.py +++ b/server/src/uds/transports/RDP/rdp.py @@ -87,6 +87,7 @@ class RDPTransport(BaseRDPTransport): printerString = BaseRDPTransport.printerString smartcardString = BaseRDPTransport.smartcardString customParameters = BaseRDPTransport.customParameters + allowMacMSRDC = BaseRDPTransport.allowMacMSRDC def getUDSTransportScript( # pylint: disable=too-many-locals self, @@ -164,13 +165,14 @@ class RDPTransport(BaseRDPTransport): elif osName == 'linux': sp.update({ 'as_new_xfreerdp_params': r.as_new_xfreerdp_params, - 'as_rdesktop_params': r.as_rdesktop_params, 'address': r.address, }) else: # Mac sp.update({ 'as_new_xfreerdp_params': r.as_new_xfreerdp_params, - 'as_rdp_url': r.as_rdp_url, + 'as_rdp_url': r.as_rdp_url if self.allowMacMSRDC.isTrue() else '', + 'as_file': r.as_file if self.allowMacMSRDC.isTrue() else '', + 'address': r.address, }) return self.getScript('scripts/{}/direct.py', osName, sp) diff --git a/server/src/uds/transports/RDP/rdp_base.py b/server/src/uds/transports/RDP/rdp_base.py index 05939fe4..59803dfe 100644 --- a/server/src/uds/transports/RDP/rdp_base.py +++ b/server/src/uds/transports/RDP/rdp_base.py @@ -139,6 +139,8 @@ class BaseRDPTransport(transports.Transport): smartcardString = gui.TextField(label=_('Smartcard string'), order=44, tooltip=_('If smartcard is checked, the smartcard string used with xfreerdp client'), tab='Linux Client', length=256) customParameters = gui.TextField(label=_('Custom parameters'), order=45, tooltip=_('If not empty, extra parameter to include for Linux Client (for example /usb:id,dev:054c:0268, or aything compatible with your xfreerdp client)'), tab='Linux Client', length=256) + allowMacMSRDC = gui.CheckBoxField(label=_('Allow Microsoft Rdp Client'), order=40, tooltip=_('If checked, allows use of Microsoft Remote Desktop Clien. PASSWORD WILL BE PRONPTED!'), tab='Mac OS X', defvalue=gui.FALSE) + def isAvailableFor(self, userService: 'models.UserService', ip: str) -> bool: """ Checks if the transport is available for the requested destination ip diff --git a/server/src/uds/transports/RDP/rdp_file.py b/server/src/uds/transports/RDP/rdp_file.py index cd16b76b..f5ce026c 100644 --- a/server/src/uds/transports/RDP/rdp_file.py +++ b/server/src/uds/transports/RDP/rdp_file.py @@ -85,10 +85,8 @@ class RDPFile: self.target = target def get(self): - if self.target in (OsDetector.Windows, OsDetector.Linux): + if self.target in (OsDetector.Windows, OsDetector.Linux, OsDetector.Macintosh): return self.getGeneric() - if self.target == OsDetector.Macintosh: - return self.getMacOsX() # Unknown target return '' @@ -114,7 +112,7 @@ class RDPFile: params.append('/smartcard') if self.redirectAudio: - if self.alsa: + if self.alsa and self.target != OsDetector.Macintosh: params.append('/sound:sys:alsa,format:1,quality:high') params.append('/microphone:sys:alsa') else: @@ -125,7 +123,10 @@ class RDPFile: params.append('/video') if self.redirectDrives != 'false': - params.append('/drive:media,/media') + if self.target == OsDetector.Linux: + params.append('/drive:media,/media') + else: + params.append('/drive:Users,/Users') # params.append('/home-drive') if self.redirectHome is True: @@ -151,7 +152,11 @@ class RDPFile: params.append('/multimon') if self.fullScreen: - params.append('/f') + if self.target != OsDetector.Macintosh: + params.append('/f') + else: # On mac, will fix this later... + params.append('/w:#WIDTH#') + params.append('/h:#HEIGHT#') else: params.append('/w:{}'.format(self.width)) params.append('/h:{}'.format(self.height)) @@ -183,61 +188,6 @@ class RDPFile: return params - @property - def as_rdesktop_params(self): # pylint: disable=too-many-branches - """ - Parameters for rdestop with self rdp description - Note that server is not added - """ - - params = ['-TUDS Connection', '-P'] - - if self.enableClipboard: - params.append('-rclipboard:PRIMARYCLIPBOARD') - - if self.redirectSmartcards: - params.append('-rsdcard') - - if self.redirectAudio: - params.append('-rsound:local') - else: - params.append('-rsound:off') - - if self.redirectDrives != 'false': - params.append('-rdisk:media=/media') - - if self.redirectSerials is True: - params.append('-rcomport:COM1=/dev/ttyS0') - - if self.redirectPrinters: - pass - - if self.compression: - params.append('-z') - - if self.showWallpaper: - params.append('-xl') - else: - params.append('-xb') - - if self.multimon: - pass - - if self.fullScreen: - params.append('-f') - else: - params.append('-g{}x{}'.format(self.width, self.height)) - - params.append('-a{}'.format(self.bpp)) - if self.username != '': - params.append('-u{}'.format(self.username)) - if self.password != '': - params.append('-p-') - if self.domain != '': - params.append('-d{}'.format(self.domain)) - - return params - def getGeneric(self): # pylint: disable=too-many-statements password = '{password}' screenMode = '2' if self.fullScreen else '1' @@ -253,8 +203,9 @@ class RDPFile: res = '' res += 'screen mode id:i:' + screenMode + '\n' - res += 'desktopwidth:i:' + self.width + '\n' - res += 'desktopheight:i:' + self.height + '\n' + if self.width[0] != '-' and self.height[0] != '-': + res += 'desktopwidth:i:' + self.width + '\n' + res += 'desktopheight:i:' + self.height + '\n' res += 'session bpp:i:' + self.bpp + '\n' res += 'use multimon:i:' + useMultimon + '\n' res += 'auto connect:i:1' + '\n' diff --git a/server/src/uds/transports/RDP/rdptunnel.py b/server/src/uds/transports/RDP/rdptunnel.py index 54ecabcb..b0b0d2a8 100644 --- a/server/src/uds/transports/RDP/rdptunnel.py +++ b/server/src/uds/transports/RDP/rdptunnel.py @@ -101,6 +101,7 @@ class TRDPTransport(BaseRDPTransport): printerString = BaseRDPTransport.printerString smartcardString = BaseRDPTransport.smartcardString customParameters = BaseRDPTransport.customParameters + allowMacMSRDC = BaseRDPTransport.allowMacMSRDC def initialize(self, values: 'Module.ValuesType'): if values: @@ -190,12 +191,12 @@ class TRDPTransport(BaseRDPTransport): elif osName == 'linux': sp.update({ 'as_new_xfreerdp_params': r.as_new_xfreerdp_params, - 'as_rdesktop_params': r.as_rdesktop_params, }) else: # Mac sp.update({ 'as_new_xfreerdp_params': r.as_new_xfreerdp_params, - 'as_rdp_url': r.as_rdp_url, + 'as_file': r.as_file if self.allowMacMSRDC.isTrue() else '', + 'as_rdp_url': r.as_rdp_url if self.allowMacMSRDC.isTrue() else '', }) diff --git a/server/src/uds/transports/RDP/scripts/macosx/direct.py b/server/src/uds/transports/RDP/scripts/macosx/direct.py index a208a5b9..d451854f 100644 --- a/server/src/uds/transports/RDP/scripts/macosx/direct.py +++ b/server/src/uds/transports/RDP/scripts/macosx/direct.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals # pylint: disable=import-error, no-name-in-module, too-many-format-args, undefined-variable, invalid-sequence-index import subprocess +import shutil import os from uds import tools # @UnresolvedImport @@ -12,17 +13,25 @@ from uds import tools # @UnresolvedImport globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable msrdc = '/Applications/Microsoft Remote Desktop.app/Contents/MacOS/Microsoft Remote Desktop' -xfreerdp = 'xfreerdp' # TODO +xfreerdp = '/usr/local/bin/xfreerdp' executable = None +def fixResolution(): + import re + import subprocess + results = str(subprocess.Popen(['system_profiler SPDisplaysDataType'],stdout=subprocess.PIPE, shell=True).communicate()[0]) + res = re.search(': \d* x \d*', results).group(0).split(' ') + width, height = str(int(res[1])-4), str(int(int(res[3])-128)) # Width and Height + return list(map(lambda x: x.replace('#WIDTH#', width).replace('#HEIGHT#', height), sp['as_new_xfreerdp_params'])) + # Check first xfreerdp, allow password redir if os.path.isfile(xfreerdp): executable = xfreerdp -elif os.path.isfile(msrdc) and sp['as_rdp_url']: +elif os.path.isfile(msrdc) and sp['as_file']: executable = msrdc if executable is None: - if sp['as_rdp_url']: + if sp['as_file']: raise Exception('''

Microsoft Remote Desktop or xfreerdp not found

In order to connect to UDS RDP Sessions, you need to have a

''') elif executable == msrdc: - url = sp['as_rdp_url'] # @UndefinedVariable + theFile = sp['as_file'] + filename = tools.saveTempFile(theFile) + # Rename as .rdp, so open recognizes it + shutil.move(filename, filename + '.rdp') + + tools.addTaskToWait(subprocess.Popen(['open', filename + '.rdp'])) + tools.addFileToUnlink(filename + '.rdp') +elif executable == xfreerdp: + # Fix resolution... + try: + xfparms = fixResolution() + except Exception as e: + xfparms = list(map(lambda x: x.replace('#WIDTH#', '1400').replace('#HEIGHT#', '800'), sp['as_new_xfreerdp_params'])) + + params = [executable] + xfparms + ['/v:{}'.format(sp['address'])] # @UndefinedVariable + subprocess.Popen(params) - tools.addTaskToWait(subprocess.Popen(['open', url])) diff --git a/server/src/uds/transports/RDP/scripts/macosx/direct.py.signature b/server/src/uds/transports/RDP/scripts/macosx/direct.py.signature index e05596d7..d762a588 100644 --- a/server/src/uds/transports/RDP/scripts/macosx/direct.py.signature +++ b/server/src/uds/transports/RDP/scripts/macosx/direct.py.signature @@ -1 +1 @@ -Nyiuosn1S6FeFLxz7BT7vOOt0WCnObOYM+vi6PkKbGj+hkwuFIPV/OFml7SxneujX3/197wVZxnhu0JTNb32sa8VB0FWz2OJoinH+l5cjcugA9Hsde9tjtMkhPc84tv0pQf+vPL3kHmfq7Qw1cQ/UuYfnp02HGmHDzIlnLmxoOy1CqxomTd8W4Ko0qVgLGUrvACinl8Z/Ya/LViECenIvC/ske8ZAlyIF/ICMp3VxB5QedNezwxm6KthL/BtgttX6IYNcr+caxnYfVO+VAzpfe4P9hg+91OE71zG0DpY1/CQIOEBd3ejxhRjfGnNGGisimxrQ1sutzsNBMjUJYxJNFGVdRlRNp4phM1pIrb9LWRoKaqXlRbSNyXn041oL10EP9wf3GzG0KnQVLhZ/bYl88tTIBJC7res9Q90fffw1EzbPFkcG6QyCaabv6mQ+9GsIH/zOPQsihqREtCL2HCDc+wlY9DBiU5q4KJp3hRzHFjwzzqqXpejV/cJfOENhlJA5AGRmlu3hLREsfyC9QR3G26dgSXF/FR6VeZZzB44KEY3DI7hq6CplyTwoOgGzUJW7wxkqRhdzV3tpZereBYJW3ntkeNsBOzzzEJax+robmzHPiYPQM7WCWsGWdP3jux+yDPAtFnAC5YKGyhXhOgjeLiByI/nmw3k+/g5M8XOASQ= \ No newline at end of file +Hfx61+xy7yzVCe4mq8/9rekZvTpbW64z3rPRV7ythmT+zLjOdd07nCresS/mA5FwfK1B2dGqkUw2Sj7XYfPVHp+pfxa1MSVDeAeyh12mhLNi9AcEvrkRw7kfQ59ZHgm4fZvAtOpkWqN/pU+V73T5eTdhIBATRS9PCwJwbYOTiEw7ndF+nZpvW/n6E0grpSoqr2QuEqj8tK+4Sb7OTtwHeYku3KDM/CZ8RYP5+OLW1OcyjpqkbbL9xgN+8zPu0wNpBMHSzwRNkQ8I0WVvWhtyhbx2RpwaFBd2ETOAUzaczJoZ/R8dNOBqBbqUk3YkuJdGhUQ+bo8ZL9Ga14Ew/wKyht+G9IkiyLzVgOxKCPT05g0ept2DU2PqJw3isK3vzkhHV7JQC7T75Aqouc/N37YNcv/OWsTD+HcLHpZoo8kMaG6PQxyfg9smrcuJPoeOHVbklRLR7cptuZ8HPEyTCKjvCx5rpi2uvXw/LsHsEWesqYt69o8BOOMhm23Hz0LK/ZAhQ7Ll/9p17+g/JeUIFeBxuXNg5A28fvTdbK6GwzbSf54Y7/woyFFcw+ii/FRUpjehN0R9M6JVqLa0XTYgQuIwrPApL5uepdZZcNFXn/ax9lK7HPkJy55iun4buQFODxMi4slgJaPrjkiY8/LwQzh0cohwWBOy05U2nOEahxUQXrA= \ No newline at end of file diff --git a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py index 9a4a79ba..a2fbaf65 100644 --- a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py +++ b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py @@ -4,7 +4,9 @@ from __future__ import unicode_literals # pylint: disable=import-error, no-name-in-module, too-many-format-args, undefined-variable, invalid-sequence-index import subprocess +import shutil import os + from uds.forward import forward # @UnresolvedImport from uds import tools # @UnresolvedImport @@ -12,8 +14,14 @@ from uds import tools # @UnresolvedImport # Inject local passed sp into globals for functions globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable -# Inject local passed sp into globals for functions -globals()['sp'] = sp # type: ignore # pylint: disable=undefined-variable +def fixResolution(): + import re + import subprocess + results = str(subprocess.Popen(['system_profiler SPDisplaysDataType'],stdout=subprocess.PIPE, shell=True).communicate()[0]) + res = re.search(': \d* x \d*', results).group(0).split(' ') + width, height = str(int(res[1])-4), str(int(int(res[3])-128)) # Width and Height + return list(map(lambda x: x.replace('#WIDTH#', width).replace('#HEIGHT#', height), sp['as_new_xfreerdp_params'])) + msrdc = '/Applications/Microsoft Remote Desktop.app/Contents/MacOS/Microsoft Remote Desktop' xfreerdp = 'xfreerdp' # TODO @@ -22,7 +30,7 @@ executable = None # Check first xfreerdp, allow password redir if os.path.isfile(xfreerdp): executable = xfreerdp -elif os.path.isfile(msrdc) and sp['as_rdp_url']: +elif os.path.isfile(msrdc) and sp['as_file']: executable = msrdc if executable is None: @@ -47,7 +55,6 @@ if executable is None: ''') -elif executable == msrdc: forwardThread, port = forward(sp['tunHost'], sp['tunPort'], sp['tunUser'], sp['tunPass'], sp['ip'], 3389, waitTime=sp['tunWait']) # @UndefinedVariable address = '127.0.0.1:{}'.format(port) @@ -57,6 +64,23 @@ if forwardThread.status == 2: else: if executable == msrdc: - url = sp['as_rdp_url'] # @UndefinedVariable + theFile = theFile = sp['as_file'].format( + address='127.0.0.1:{}'.format(port) + ) + + filename = tools.saveTempFile(theFile) + # Rename as .rdp, so open recognizes it + shutil.move(filename, filename + '.rdp') + + tools.addTaskToWait(subprocess.Popen(['open', filename + '.rdp'])) + tools.addFileToUnlink(filename + '.rdp') + elif executable == xfreerdp: + # Fix resolution... + try: + xfparms = fixResolution() + except Exception as e: + xfparms = list(map(lambda x: x.replace('#WIDTH#', '1400').replace('#HEIGHT#', '800'), sp['as_new_xfreerdp_params'])) + + params = [executable] + xfparms + ['/v:{}'.format(address)] + subprocess.Popen(params) - tools.addTaskToWait(subprocess.Popen(['open', url])) diff --git a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py.signature b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py.signature index 3408a532..fd519675 100644 --- a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py.signature +++ b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py.signature @@ -1 +1 @@ -DBEvNnwbYQG8ycmmkatf1kBDFYbyZvOLG34Xb4WDu+JVvZarWJVwcgqJL6N7dHY3oTl0X8wqnMQJ4zXB5ee3UoXISoHiglCprov/DvvgF5O0ZY+Gw4qeW+J+BZ9HgUUeIBI1aKTt0EcfsqMwy/QubsdZqMVkBhorU+0il5WxSU5tbMsE6Z0t3p65diT2YgIE85LHtcaSVYGYXD93d+UcnQIxFm5WJWXQrXad9mcfZNhME98ITvtnYOlUQJPN2JbTqwEPCKOzptiY2mPOuObZiXZ4ziWRdTZr/ANP+dpX63/L0yWdKIlb4kpBJHYTpYxHd8ncVPT+qFhGV3mJ5wi3uHB1bkO8dJ7vsMk+3oYabXjPDPyXixaGTLqtF9NnYOsLJHO6238dtprAd+FvOw2oqR5Mm4oXvV661nyc27y7HqjhoMN3fqO0UDR94xUxJWucD8AwypRADYhrQifvJZMVRZ/UWjdGlp/VBTKW7UhJNGu4fg1SSgCCMSCbLCCylaqRg0bSwvrR3NR7Mv+OsKxqNBh7D83c7LkL551ccL/+LVTatKbuZd9Ely1x9ngjxplkvOWYS90i3rfDN2oLnkGKWz/xuDvkZUtXZbJD95GL51vm8BUxYlB6SebwVGd829BL5eV/tpq4xdL7uin6cFc6lvOexHM1eIbaayOsn1o75so= \ No newline at end of file +rFojgaIeYnTAmzNEhZU1N1Tf8I4p4zm4MrJAQM3evy9B6VDKEFSsF1iHh93AP8HVsYzwgHhvLil19f7PfGvdTi8lS3fBNuz7MB9lEV3EP6uXOkVXIvTzGIRJgQGybT0ibJMqLHAfYZISMLIZkU/yE5thlydWCQjUjUsaDoGqCYSQ7u2kz6ggNcxOUYN1KuDuRKGO01k3wRFC5wymvoId4iRPbS17F2WZxB0PbofYkJyn3ZI3eTvQENjWkL6hIA7MdRsYMzBzx/xyIjmZPeOn5pIIn7fqtGZkUTW9nw25egf8VtIUsHaY/SaP04plDDaTt2vRpeHSBpLvW9uhzektFEMZ2clzblYv2xqd5HUrTp9MUWDauyCJ8r3H/MAC01akqSaOiTbmfJ8pT8gLu+Tlo7FOJN37YhDYUs22z61A4Po0DaiCGj9nP1S9hOplbBTWgfkZQQxJlsdZX6iw0co3c59TTtgNKn1QB9wMlbb6ukdH7xqE3d10cGXzBQC0cz9thnaWdCh+wqVyZI8YeEdS8aqF0C2AogfXjrxbU6obVnU0h2r+epOhvPzKpLO5y9RKnWFFSNqrvMluQlGmEt25AQSpS/KRuGwpsVjSOt55OpXA9BMf6qTU/QE+UDO3DRpBAljzJJOPGhmKNRr59wT0g+SaRg4YkQg2NT5ZN6vTntw= \ No newline at end of file