diff --git a/client/src/UDSClient.py b/client/src/UDSClient.py
old mode 100644
new mode 100755
index f9124a2f..65ce3e8d
--- a/client/src/UDSClient.py
+++ b/client/src/UDSClient.py
@@ -172,7 +172,8 @@ if __name__ == "__main__":
QtCore.QCoreApplication.setOrganizationName('Virtual Cable S.L.U.')
QtCore.QCoreApplication.setApplicationName('UDS Connector')
- app.setStyle(QtGui.QStyleFactory.create('plastique'))
+ if 'darwin' not in sys.platform:
+ app.setStyle('plastique')
if six.PY3 is False:
import threading
diff --git a/client/src/uds/tools.py b/client/src/uds/tools.py
index 3c2c1714..77472b62 100644
--- a/client/src/uds/tools.py
+++ b/client/src/uds/tools.py
@@ -36,6 +36,7 @@ import tempfile
import string
import random
import os
+import stat
_unlinkFiles = []
_tasksToWait = []
@@ -53,6 +54,16 @@ def saveTempFile(content, filename=None):
return filename
+def findApp(appName):
+ for path in os.environ['PATH'].split(os.pathsep):
+ fileName = os.path.join(path, appName)
+ if os.path.isfile(fileName) and (os.stat(fileName).st_mode & stat.S_IXUSR) != 0:
+ return fileName
+ return None
+
+
+# Queing operations (to be executed before exit)
+
def addFileToUnlink(filename):
'''
Adds a file to the wait-and-unlink list
diff --git a/server/src/uds/REST/methods/client.py b/server/src/uds/REST/methods/client.py
index afb437e7..8e21a640 100644
--- a/server/src/uds/REST/methods/client.py
+++ b/server/src/uds/REST/methods/client.py
@@ -97,6 +97,9 @@ class Client(Handler):
'downloadUrl': url
})
+ if len(self._args) == 1:
+ return Client.result(_('Correct'))
+
try:
ticket, scrambler = self._args
except Exception:
@@ -121,7 +124,7 @@ class Client(Handler):
logger.debug('Script:\n{}'.format(transportScript))
- return Client.result(transportScript.encode('bz2').encode('base64'))
+ return Client.result(result=transportScript.encode('bz2').encode('base64'))
except Exception as e:
logger.exception("Exception")
return Client.result(error=six.text_type(e))
diff --git a/server/src/uds/core/util/tools.py b/server/src/uds/core/util/tools.py
new file mode 100644
index 00000000..7a4982d9
--- /dev/null
+++ b/server/src/uds/core/util/tools.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+#
+# Copyright (c) 2012 Virtual Cable S.L.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Virtual Cable S.L. nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''
+@author: Adolfo Gómez, dkmaster at dkmon dot com
+'''
+from __future__ import unicode_literals
+
+
+class DictAsObj(object):
+ def __init__(self, dct=None, **kwargs):
+ if dct is not None:
+ self.__dict__.update(dct)
+ self.__dict__.update(kwargs)
+
diff --git a/server/src/uds/core/workers/AssignedAndUnused.py b/server/src/uds/core/workers/AssignedAndUnused.py
index 3a5b4140..f913e117 100644
--- a/server/src/uds/core/workers/AssignedAndUnused.py
+++ b/server/src/uds/core/workers/AssignedAndUnused.py
@@ -69,5 +69,5 @@ class AssignedAndUnused(Job):
osm.processUnused(us)
else: # No os manager, simply remove unused services in specified time
for us in ds.assignedUserServices().filter(in_use=False, state_date__lt=since_state, state=State.USABLE, os_state=State.USABLE):
- logger.debug('Found unused assigned service {0}'.format(us))
+ logger.debug('Found unused assigned service with no OS Manager {0}'.format(us))
us.remove()
diff --git a/server/src/uds/static/client/.gitignore b/server/src/uds/static/client/.gitignore
new file mode 100644
index 00000000..61643f7e
--- /dev/null
+++ b/server/src/uds/static/client/.gitignore
@@ -0,0 +1,2 @@
+UDSClient.dmg
+UDSClientSetup.exe
diff --git a/server/src/uds/static/client/.placeholder b/server/src/uds/static/client/.placeholder
new file mode 100644
index 00000000..e69de29b
diff --git a/server/src/uds/templates/uds/html5/download_client.html b/server/src/uds/templates/uds/html5/download_client.html
index 65225ec5..fdff0fb7 100644
--- a/server/src/uds/templates/uds/html5/download_client.html
+++ b/server/src/uds/templates/uds/html5/download_client.html
@@ -8,10 +8,11 @@
{% block body %}
-
{% trans 'Download UDS Plugin for' %} {{ os|osName }}
-
{% trans 'In order to be able to execute UDS services, you need to have uds plugin installed.' %}
-
{% trans 'Download UDS Plugin for' %} {{ os|osName }}
-
{% trans 'Or select another version' %}
+
{% trans 'Download UDS Plugin for' %} {{ os|osName }}
+
{% trans 'In order to be able to execute UDS services, you need to have UDS plugin installed.' %}
+
{{ os|pluginDownloadUrl|safe }}
+
{% trans 'Or download another version' %}
+
{% trans 'In case that your platform has been incorrectly detected, you can download manually the version required for your Operating System' %}
{% if os != 'linux' %}
@@ -31,15 +32,17 @@
{% if request.user %}
-
{% trans 'If you already have UDS Plugin installed but this message persists to appear, you can disable it here' %}
+
{% trans 'If you already have UDS Plugin installed but this message persists to appear, you can disable automatic detection here' %}
+
{% trans "Please, note that disabling automatic detection will not trigger this page again in case you don't have the plugin installed." %}
+ {% trans "In this case, you will have to manually download the plugin by using the menu on upper right corner." %}
{% trans "Return" %}
diff --git a/server/src/uds/templatetags/html5.py b/server/src/uds/templatetags/html5.py
index ff036e6b..3c82446c 100644
--- a/server/src/uds/templatetags/html5.py
+++ b/server/src/uds/templatetags/html5.py
@@ -33,6 +33,9 @@
from __future__ import unicode_literals
from django import template
+from django.utils.translation import ugettext as _
+from django.templatetags.static import static
+
from uds.core.util import html
from uds.core.util.request import getRequest
from uds.core.auths.auth import ROOT_ID
@@ -213,9 +216,10 @@ def osName(os):
@register.filter(name='pluginDownloadUrl')
def pluginDownloadUrl(os):
+ tmpl = '
' + _('Download UDS Plugin for') + ' {os}'
if os == 'windows':
- return '1'
+ return tmpl.format(url=static('client/UDSClientSetup.exe'), os='Windows')
elif os == 'linux':
return '2'
else:
- return '3'
+ return tmpl.format(url=static('client/UDSClient.dmg'), os='Mac OSX')
diff --git a/server/src/uds/transports/RDP/RDPFile.py b/server/src/uds/transports/RDP/RDPFile.py
index 0314ebcb..2c30319f 100644
--- a/server/src/uds/transports/RDP/RDPFile.py
+++ b/server/src/uds/transports/RDP/RDPFile.py
@@ -67,12 +67,61 @@ class RDPFile(object):
self.target = target
def get(self):
- if self.target == OsDetector.Windows:
- return self.getWindows()
+ if self.target in (OsDetector.Windows, OsDetector.Linux):
+ return self.getGeneric()
elif self.target == OsDetector.Macintosh:
return self.getMacOsX()
+ # Unknown target
+ return ''
- def getWindows(self):
+ @property
+ def as_file(self):
+ return self.get()
+
+ @property
+ def as_new_xfreerdp_params(self):
+ params = ['/clipboard', '/t:UDS Connection', '/cert-ignore']
+
+ if self.redirectSmartcards:
+ params.append('/smartcard')
+
+ if self.redirectAudio:
+ params.append('/sound:sys:alsa')
+ params.append('/microphone:sys:alsa')
+ params.append('/multimedia:sys:alsa')
+
+ if self.redirectDrives is True:
+ params.append('/drive:media,/media')
+ params.append('/home-drive')
+
+ if self.redirectPrinters:
+ params.append('/printer')
+
+ if self.compression:
+ params.append('/compression:on')
+
+ if self.showWallpaper:
+ params.append('+themes')
+ params.append('+wallpaper')
+
+ if self.multimon:
+ params.append('/multimon')
+
+ if self.fullScreen:
+ params.append('/f')
+ else:
+ params.append('/w:{}'.format(self.width))
+ params.append('/h:{}'.format(self.height))
+
+ params.append('/bpp:{}'.format(self.bpp))
+ params.append('/u:{}'.format(self.username))
+ params.append('/p:{}'.format(self.password))
+ params.append('/d:{}'.format(self.domain))
+ params.append('/v:{}'.format(self.address))
+
+ return params
+
+ def getGeneric(self):
password = "{password}"
screenMode = self.fullScreen and "2" or "1"
audioMode = self.redirectAudio and "0" or "2"
@@ -105,7 +154,8 @@ class RDPFile(object):
if len(self.username) != 0:
res += 'username:s:' + self.username + '\n'
res += 'domain:s:' + self.domain + '\n'
- res += 'password 51:b:' + password + '\n'
+ if self.target == OsDetector.Windows:
+ res += 'password 51:b:' + password + '\n'
res += 'alternate shell:s:' + '\n'
res += 'shell working directory:s:' + '\n'
diff --git a/server/src/uds/transports/RDP/RDPTransport.py b/server/src/uds/transports/RDP/RDPTransport.py
index 9be6e8e4..5363b7a8 100644
--- a/server/src/uds/transports/RDP/RDPTransport.py
+++ b/server/src/uds/transports/RDP/RDPTransport.py
@@ -2,7 +2,7 @@
#
# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
+# All rights reservem.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
@@ -34,6 +34,7 @@
from django.utils.translation import ugettext_noop as _
from uds.core.managers.UserPrefsManager import CommonPrefs
from uds.core.util import OsDetector
+from uds.core.util import tools
from .BaseRDPTransport import BaseRDPTransport
from .RDPFile import RDPFile
@@ -66,47 +67,15 @@ class RDPTransport(BaseRDPTransport):
wallpaper = BaseRDPTransport.wallpaper
multimon = BaseRDPTransport.multimon
- def windowsScript(self, data):
- r = RDPFile(data['fullScreen'], data['width'], data['height'], data['depth'], target=OsDetector.Windows)
- r.address = '{}:{}'.format(data['ip'], 3389)
- r.username = data['username']
- r.password = '{password}'
- r.domain = data['domain']
- r.redirectPrinters = self.allowPrinters.isTrue()
- r.redirectSmartcards = self.allowSmartcards.isTrue()
- r.redirectDrives = self.allowDrives.isTrue()
- r.redirectSerials = self.allowSerials.isTrue()
- r.showWallpaper = self.wallpaper.isTrue()
- r.multimon = self.multimon.isTrue()
-
+ def windowsScript(self, m):
# 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
- return self.getScript('scripts/windows/direct.py').format(os=data['os'], file=r.get(), password=data['password'])
+ return self.getScript('scripts/windows/direct.py').format(m=m)
- def macOsXScript(self, data):
- r = RDPFile(data['fullScreen'], data['width'], data['height'], data['depth'], target=OsDetector.Macintosh)
- r.address = '{}:{}'.format(data['ip'], 3389)
- r.username = data['username']
- r.domain = data['domain']
- r.redirectPrinters = self.allowPrinters.isTrue()
- r.redirectSmartcards = self.allowSmartcards.isTrue()
- r.redirectDrives = self.allowDrives.isTrue()
- r.redirectSerials = self.allowSerials.isTrue()
- r.showWallpaper = self.wallpaper.isTrue()
- r.multimon = self.multimon.isTrue()
+ def macOsXScript(self, m):
+ return self.getScript('scripts/macosx/direct.py').format(m=m)
- if data['domain'] != '':
- username = '{}\\\\{}'.format(data['domain'], data['username'])
- else:
- username = data['username']
-
- return self.getScript('scripts/macosx/direct.py').format(os=data['os'],
- file=r.get(),
- password=data['password'],
- username=username,
- ip=data['ip'],
- this_server=data['this_server'],
- r=r
- )
+ def getLinuxScript(self, m):
+ return self.getScript('scripts/linux/direct.py').format(m=m)
def getUDSTransportScript(self, userService, transport, ip, os, user, password, request):
# We use helper to keep this clean
@@ -118,6 +87,18 @@ class RDPTransport(BaseRDPTransport):
width, height = CommonPrefs.getWidthHeight(prefs)
depth = CommonPrefs.getDepth(prefs)
+ r = RDPFile(width == -1 or height == -1, width, height, depth, target=os['OS'])
+ r.address = '{}:{}'.format(ip, 3389)
+ r.username = username
+ r.password = password
+ r.domain = domain
+ r.redirectPrinters = self.allowPrinters.isTrue()
+ r.redirectSmartcards = self.allowSmartcards.isTrue()
+ r.redirectDrives = self.allowDrives.isTrue()
+ r.redirectSerials = self.allowSerials.isTrue()
+ r.showWallpaper = self.wallpaper.isTrue()
+ r.multimon = self.multimon.isTrue()
+
# data
data = {
'os': os['OS'],
@@ -125,6 +106,7 @@ class RDPTransport(BaseRDPTransport):
'port': 3389,
'username': username,
'password': password,
+ 'hasCredentials': username != '' and password != '',
'domain': domain,
'width': width,
'height': height,
@@ -137,14 +119,23 @@ class RDPTransport(BaseRDPTransport):
'wallpaper': self.wallpaper.isTrue(),
'multimon': self.multimon.isTrue(),
'fullScreen': width == -1 or height == -1,
- 'this_server': request.build_absolute_uri('/')
+ 'this_server': request.build_absolute_uri('/'),
+ 'r': r,
}
- logger.debug('Detected os: {}'.format(data['os']))
+ m = tools.DictAsObj(data)
- if data['os'] == OsDetector.Windows:
- return self.windowsScript(data)
- elif data['os'] == OsDetector.Macintosh:
- return self.macOsXScript(data)
+ if m.domain != '':
+ m.usernameWithDomain = '{}\\\\{}'.format(m.domain, m.username)
+ else:
+ m.usernameWithDomain = m.username
+
+ if m.os == OsDetector.Windows:
+ m.r.password = '{password}'
+ return self.windowsScript(m)
+ if m.os == OsDetector.Macintosh:
+ return self.macOsXScript(m)
+ if m.os == OsDetector.Linux:
+ return self.getLinuxScript(m)
return ''
diff --git a/server/src/uds/transports/RDP/TSRDPTransport.py b/server/src/uds/transports/RDP/TSRDPTransport.py
index 65709ab3..778a9049 100644
--- a/server/src/uds/transports/RDP/TSRDPTransport.py
+++ b/server/src/uds/transports/RDP/TSRDPTransport.py
@@ -38,6 +38,7 @@ from uds.core.transports.BaseTransport import Transport
from uds.core.transports import protocols
from uds.models import TicketStore
from uds.core.util import OsDetector
+from uds.core.util import tools
from .BaseRDPTransport import BaseRDPTransport
from .RDPFile import RDPFile
@@ -84,61 +85,13 @@ class TSRDPTransport(BaseRDPTransport):
if values['tunnelServer'].count(':') != 1:
raise Transport.ValidationException(_('Must use HOST:PORT in Tunnel Server Field'))
- def windowsScript(self, data):
- r = RDPFile(data['fullScreen'], data['width'], data['height'], data['depth'], target=OsDetector.Windows)
- r.address = '{address}'
- r.username = data['username']
- r.password = '{password}'
- r.domain = data['domain']
- r.redirectPrinters = self.allowPrinters.isTrue()
- r.redirectSmartcards = self.allowSmartcards.isTrue()
- r.redirectDrives = self.allowDrives.isTrue()
- r.redirectSerials = self.allowSerials.isTrue()
- r.showWallpaper = self.wallpaper.isTrue()
- r.multimon = self.multimon.isTrue()
+ def windowsScript(self, m):
# 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
- return self.getScript('scripts/windows/tunnel.py').format(
- file=r.get(), password=data['password'],
- server=data['ip'],
- port=3389,
- tunUser=data['tunUser'],
- tunPass=data['tunPass'],
- tunHost=data['tunHost'],
- tunPort=data['tunPort']
- )
+ return self.getScript('scripts/windows/tunnel.py').format(m=m)
- def macOsXScript(self, data):
- r = RDPFile(data['fullScreen'], data['width'], data['height'], data['depth'], target=OsDetector.Macintosh)
- r.address = '{address}'
- r.username = data['username']
- r.domain = data['domain']
- r.redirectPrinters = self.allowPrinters.isTrue()
- r.redirectSmartcards = self.allowSmartcards.isTrue()
- r.redirectDrives = self.allowDrives.isTrue()
- r.redirectSerials = self.allowSerials.isTrue()
- r.showWallpaper = self.wallpaper.isTrue()
- r.multimon = self.multimon.isTrue()
-
- if data['domain'] != '':
- username = '{}\\\\{}'.format(data['domain'], data['username'])
- else:
- username = data['username']
-
- return self.getScript('scripts/macosx/tunnel.py').format(
- os=data['os'],
- file=r.get(),
- password=data['password'],
- username=username,
- server=data['ip'],
- this_server=data['this_server'],
- r=r,
- port=3389,
- tunUser=data['tunUser'],
- tunPass=data['tunPass'],
- tunHost=data['tunHost'],
- tunPort=data['tunPort']
- )
+ def macOsXScript(self, m):
+ return self.getScript('scripts/macosx/tunnel.py').format(m=m)
def getUDSTransportScript(self, userService, transport, ip, os, user, password, request):
# We use helper to keep this clean
@@ -157,6 +110,18 @@ class TSRDPTransport(BaseRDPTransport):
logger.debug('Username generated: {0}, password: {1}'.format(tunuser, tunpass))
+ r = RDPFile(width == -1 or height == -1, width, height, depth, target=os['OS'])
+ r.address = '{address}'
+ r.username = username
+ r.domain = domain
+ r.redirectPrinters = self.allowPrinters.isTrue()
+ r.redirectSmartcards = self.allowSmartcards.isTrue()
+ r.redirectDrives = self.allowDrives.isTrue()
+ r.redirectSerials = self.allowSerials.isTrue()
+ r.showWallpaper = self.wallpaper.isTrue()
+ r.multimon = self.multimon.isTrue()
+
+
# data
data = {
'os': os['OS'],
@@ -167,6 +132,7 @@ class TSRDPTransport(BaseRDPTransport):
'tunPort': sshPort,
'username': username,
'password': password,
+ 'hasCredentials': username != '' and password != '',
'domain': domain,
'width': width,
'height': height,
@@ -179,12 +145,21 @@ class TSRDPTransport(BaseRDPTransport):
'wallpaper': self.wallpaper.isTrue(),
'multimon': self.multimon.isTrue(),
'fullScreen': width == -1 or height == -1,
- 'this_server': request.build_absolute_uri('/')
+ 'this_server': request.build_absolute_uri('/'),
+ 'r': r,
}
- if data['os'] == OsDetector.Windows:
- return self.windowsScript(data)
- elif data['os'] == OsDetector.Macintosh:
- return self.macOsXScript(data)
+ m = tools.DictAsObj(data)
+
+ if m.domain != '':
+ m.usernameWithDomain = '{}\\\\{}'.format(m.domain, m.username)
+ else:
+ m.usernameWithDomain = m.username
+
+ if m.os == OsDetector.Windows:
+ r.password = '{password}'
+ return self.windowsScript(m)
+ if m.os == OsDetector.Macintosh:
+ return self.macOsXScript(m)
return ''
diff --git a/server/src/uds/transports/RDP/scripts/linux/direct.py b/server/src/uds/transports/RDP/scripts/linux/direct.py
new file mode 100644
index 00000000..99146be7
--- /dev/null
+++ b/server/src/uds/transports/RDP/scripts/linux/direct.py
@@ -0,0 +1,49 @@
+# 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
+from PyQt4 import QtCore, QtGui
+import subprocess
+import os
+import re
+
+from uds import tools # @UnresolvedImport
+
+import six
+
+
+def execOldXFreeRdp(parent, xfreerdp):
+ QtGui.QMessageBox.critical(parent, 'Notice', 'Old xfreerdp', QtGui.QMessageBox.Ok) # @UndefinedVariable
+
+
+def execNewXFreeRdp(parent, xfreerdp):
+ import subprocess
+ params = [xfreerdp] + {m.r.as_new_xfreerdp_params} # @UndefinedVariable
+ tools.addTaskToWait(subprocess.Popen(params))
+
+
+def execRdesktop(parent, rdesktop):
+ return
+
+# Try to locate a "valid" version of xfreerdp as first option
+xfreerdp = tools.findApp('xfreerdp')
+if xfreerdp is not None:
+ # Check for nice version
+ try:
+ version = subprocess.check_output([xfreerdp, '--version'])
+ version = float(re.search(r'version ([0-9]*\.[0-9]*)', version).groups()[0])
+ if version < 1.0:
+ raise Exception()
+ if version < 1.1:
+ execOldXFreeRdp(parent, xfreerdp) # @UndefinedVariable
+ else:
+ execNewXFreeRdp(parent, xfreerdp) # @UndefinedVariable
+
+ except Exception as e: # Valid version not found, pass to check rdesktop
+ QtGui.QMessageBox.critical(parent, 'Notice', six.text_type(e), QtGui.QMessageBox.Ok) # @UndefinedVariable
+ pass
+else:
+ rdesktop = tools.findApp('rdesktop')
+ if rdesktop is None:
+ raise Exception('You need to have installed xfreerdp or rdesktop to connect to theese UDS services.\nPlease, install apropiate package for your system.')
diff --git a/server/src/uds/transports/RDP/scripts/macosx/direct.py b/server/src/uds/transports/RDP/scripts/macosx/direct.py
index 4931d5ca..c6e32d6d 100644
--- a/server/src/uds/transports/RDP/scripts/macosx/direct.py
+++ b/server/src/uds/transports/RDP/scripts/macosx/direct.py
@@ -12,7 +12,7 @@ from uds import tools # @UnresolvedImport
import six
-theFile = '''{file}'''
+theFile = '''{m.r.as_file}'''
# First, try to locate Remote Desktop Connection (version 2, from Microsoft website, not the app store one)
@@ -35,8 +35,8 @@ def onExit():
[
'security',
'delete-generic-password',
- '-a', '{username}',
- '-s', 'Remote Desktop Connection 2 Password for {ip}',
+ '-a', '{m.usernameWithDomain}',
+ '-s', 'Remote Desktop Connection 2 Password for {m.ip}',
]
)
@@ -52,7 +52,7 @@ if executable is None:
CoRD (A bit unstable from 10.7 onwards)
- You can get it from this link
+ You can get it from this link
If both apps are installed, Remote Desktop Connection will be used as first option
@@ -60,54 +60,52 @@ if executable is None:
''', QtGui.QMessageBox.Ok)
elif executable == msrdc:
try:
- if '{username}' != '' and '{password}' != '':
+ if {m.hasCredentials}: # @UndefinedVariable
subprocess.call(
[
'security',
'add-generic-password',
- '-w', '{password}',
+ '-w', '{m.password}',
'-U',
- '-a', '{username}',
- '-s', 'Remote Desktop Connection 2 Password for {ip}',
+ '-a', '{m.usernameWithDomain}',
+ '-s', 'Remote Desktop Connection 2 Password for {m.ip}',
'-T', '/Applications/Remote Desktop Connection.app',
]
)
+ tools.addExecBeforeExit(onExit)
# Call but do not wait for exit
tools.addTaskToWait(subprocess.Popen([executable, filename]))
- tools.addExecBeforeExit(onExit)
tools.addFileToUnlink(filename)
except Exception as e:
QtGui.QMessageBox.critical(parent, 'Notice', six.text_type(e), QtGui.QMessageBox.Ok) # @UndefinedVariable
else: # CoRD
url = 'rdp://'
- if '\\' in '{username}':
- username, domain = '{username}'.split('\\')
- else:
- username, domain = '{username}', ''
+
+ username, domain = '{m.username}', '{m.domain}'
if username != '':
url += username
- if '{password}' != '':
- url += ':' + urllib.quote('{password}')
+ if '{m.password}' != '':
+ url += ':' + urllib.quote('{m.password}')
url += '@'
- url += '{ip}/'
+ url += '{m.ip}/'
if domain != '':
url += domain
- url += '?screenDepth={r.bpp}'
+ url += '?screenDepth={m.r.bpp}'
- if {r.fullScreen}: # @UndefinedVariable
+ if {m.r.fullScreen}: # @UndefinedVariable
url += '&fullscreen=true'
else:
- url += 'screenWidth={r.width}&screenHeight={r.height}'
+ url += 'screenWidth={m.r.width}&screenHeight={m.r.height}'
- url += '&forwardAudio=' + '01'[{r.redirectAudio}] # @UndefinedVariable
+ url += '&forwardAudio=' + '01'[{m.r.redirectAudio}] # @UndefinedVariable
- if {r.redirectDrives}: # @UndefinedVariable
+ if {m.r.redirectDrives}: # @UndefinedVariable
url += '&forwardDisks=true'
- if {r.redirectPrinters}: # @UndefinedVariable
+ if {m.r.redirectPrinters}: # @UndefinedVariable
url += '&forwardPrinters=true'
tools.addTaskToWait(subprocess.Popen(['open', url]))
diff --git a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py
index 474eb2a3..0104cd2d 100644
--- a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py
+++ b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py
@@ -31,7 +31,7 @@ def onExit():
[
'security',
'delete-generic-password',
- '-a', '{username}',
+ '-a', '{m.username}',
'-s', 'Remote Desktop Connection 2 Password for 127.0.0.1',
]
)
@@ -48,7 +48,7 @@ if executable is None:
CoRD (A bit unstable from 10.7 onwards)
- You can get it from this link
+ You can get it from this link
If both apps are installed, Remote Desktop Connection will be used as first option
@@ -56,13 +56,13 @@ if executable is None:
''', QtGui.QMessageBox.Ok)
-forwardThread, port = forward('{tunHost}', '{tunPort}', '{tunUser}', '{tunPass}', '{server}', '{port}')
+forwardThread, port = forward('{m.tunHost}', '{m.tunPort}', '{m.tunUser}', '{m.tunPass}', '{m.ip}', 3389)
if forwardThread.status == 2:
QtGui.QMessageBox.critical(parent, 'Error', 'Unable to open tunnel', QtGui.QMessageBox.Ok) # @UndefinedVariable
else:
- theFile = '''{file}'''.format(
+ theFile = '''{m.r.as_file}'''.format(
address='127.0.0.1:{{}}'.format(port)
)
filename = tools.saveTempFile(theFile)
@@ -70,54 +70,51 @@ else:
if executable == msrdc:
try:
- if '{username}' != '' and '{password}' != '':
+ if {m.hasCredentials}: # @UndefinedVariable
subprocess.call(
[
'security',
'add-generic-password',
- '-w', '{password}',
+ '-w', '{m.password}',
'-U',
- '-a', '{username}',
+ '-a', '{m.username}',
'-s', 'Remote Desktop Connection 2 Password for 127.0.0.1'.format(port),
'-T', '/Applications/Remote Desktop Connection.app',
]
)
+ tools.addExecBeforeExit(onExit)
# Call but do not wait for exit
tools.addTaskToWait(subprocess.Popen([executable, filename]))
- tools.addExecBeforeExit(onExit)
tools.addFileToUnlink(filename)
except Exception as e:
QtGui.QMessageBox.critical(parent, 'Notice', six.text_type(e), QtGui.QMessageBox.Ok) # @UndefinedVariable
else: # CoRD
url = 'rdp://'
- if '\\' in '{username}':
- username, domain = '{username}'.split('\\')
- else:
- username, domain = '{username}', ''
+ username, domain = '{m.username}', '{m.domain}'
if username != '':
url += username
- if '{password}' != '':
- url += ':' + urllib.quote('{password}')
+ if '{m.password}' != '':
+ url += ':' + urllib.quote('{m.password}')
url += '@'
url += '127.0.0.1:3389/'
if domain != '':
url += domain
- url += '?screenDepth={r.bpp}'
+ url += '?screenDepth={m.r.bpp}'
- if {r.fullScreen}: # @UndefinedVariable
+ if {m.r.fullScreen}: # @UndefinedVariable
url += '&fullscreen=true'
else:
- url += 'screenWidth={r.width}&screenHeight={r.height}'
+ url += 'screenWidth={m.r.width}&screenHeight={m.r.height}'
- url += '&forwardAudio=' + '01'[{r.redirectAudio}] # @UndefinedVariable
+ url += '&forwardAudio=' + '01'[{m.r.redirectAudio}] # @UndefinedVariable
- if {r.redirectDrives}: # @UndefinedVariable
+ if {m.r.redirectDrives}: # @UndefinedVariable
url += '&forwardDisks=true'
- if {r.redirectPrinters}: # @UndefinedVariable
+ if {m.r.redirectPrinters}: # @UndefinedVariable
url += '&forwardPrinters=true'
tools.addTaskToWait(subprocess.Popen(['open', url]))
diff --git a/server/src/uds/transports/RDP/scripts/windows/direct.py b/server/src/uds/transports/RDP/scripts/windows/direct.py
index 09fbea5a..c07e90e7 100644
--- a/server/src/uds/transports/RDP/scripts/windows/direct.py
+++ b/server/src/uds/transports/RDP/scripts/windows/direct.py
@@ -12,10 +12,10 @@ from uds import tools # @UnresolvedImport
import six
-theFile = '''{file}'''.format(password=win32crypt.CryptProtectData(six.binary_type('{password}'.encode('UTF-16LE')), None, None, None, None, 0x01).encode('hex'))
+theFile = '''{m.r.as_file}'''.format(password=win32crypt.CryptProtectData(six.binary_type('{m.password}'.encode('UTF-16LE')), None, None, None, None, 0x01).encode('hex'))
filename = tools.saveTempFile(theFile)
-executable = os.path.join(os.path.join(os.environ['WINDIR'], 'system32'), 'mstsc.exe')
+executable = tools.findApp('mstsc.exe')
subprocess.call([executable, filename])
# tools.addFileToUnlink(filename)
diff --git a/server/src/uds/transports/RDP/scripts/windows/tunnel.py b/server/src/uds/transports/RDP/scripts/windows/tunnel.py
index 1c71c279..03cf97d1 100644
--- a/server/src/uds/transports/RDP/scripts/windows/tunnel.py
+++ b/server/src/uds/transports/RDP/scripts/windows/tunnel.py
@@ -14,22 +14,22 @@ from uds import tools # @UnresolvedImport
import six
-forwardThread, port = forward('{tunHost}', '{tunPort}', '{tunUser}', '{tunPass}', '{server}', '{port}')
+forwardThread, port = forward('{m.tunHost}', '{m.tunPort}', '{m.tunUser}', '{m.tunPass}', '{m.ip}', 3389)
if forwardThread.status == 2:
- QtGui.QMessageBox.critical(parent, 'Error', 'Unable to open tunnel', QtGui.QMessageBox.Ok) # @UndefinedVariable
+ raise Exception('Unable to open file')
-else:
+theFile = '''{m.r.as_file}'''.format(
+ password=win32crypt.CryptProtectData(six.binary_type('{m.password}'.encode('UTF-16LE')), None, None, None, None, 0x01).encode('hex'),
+ address='127.0.0.1:{{}}'.format(port)
+)
- theFile = '''{file}'''.format(
- password=win32crypt.CryptProtectData(six.binary_type('{password}'.encode('UTF-16LE')), None, None, None, None, 0x01).encode('hex'),
- address='127.0.0.1:{{}}'.format(port)
- )
+filename = tools.saveTempFile(theFile)
+executable = tools.findApp('mstsc.exe')
+if executable is None:
+ raise Exception('Unable to find mstsc.exe')
- filename = tools.saveTempFile(theFile)
- executable = os.path.join(os.path.join(os.environ['WINDIR'], 'system32'), 'mstsc.exe')
-
- subprocess.call([executable, filename])
- tools.addFileToUnlink(filename)
+subprocess.call([executable, filename])
+tools.addFileToUnlink(filename)
# QtGui.QMessageBox.critical(parent, 'Notice', filename + ", " + executable, QtGui.QMessageBox.Ok)