forked from shaba/openuds
* Simplified Transports after tests
* Added direct linux support for xfreerdp right now
This commit is contained in:
parent
aef71ba48c
commit
bdef8b2e8c
3
client/src/UDSClient.py
Normal file → Executable file
3
client/src/UDSClient.py
Normal file → Executable file
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
41
server/src/uds/core/util/tools.py
Normal file
41
server/src/uds/core/util/tools.py
Normal file
@ -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)
|
||||
|
@ -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()
|
||||
|
2
server/src/uds/static/client/.gitignore
vendored
Normal file
2
server/src/uds/static/client/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
UDSClient.dmg
|
||||
UDSClientSetup.exe
|
0
server/src/uds/static/client/.placeholder
Normal file
0
server/src/uds/static/client/.placeholder
Normal file
@ -8,10 +8,11 @@
|
||||
{% block body %}
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2 bg-primary img-rounded">
|
||||
<h3 class="text-center">{% trans 'Download UDS Plugin for' %} {{ os|osName }}</h3>
|
||||
<p>{% trans 'In order to be able to execute UDS services, you need to have uds plugin installed.' %}</p>
|
||||
<p class="text-center"><a href="{{ os|pluginDownloadUrl }}" class="btn btn-success">{% trans 'Download UDS Plugin for' %} {{ os|osName }}</a></p>
|
||||
<h3>{% trans 'Or select another version' %}</h3>
|
||||
<h3>{% trans 'Download UDS Plugin for' %} {{ os|osName }}</h3>
|
||||
<p>{% trans 'In order to be able to execute UDS services, you need to have UDS plugin installed.' %}</p>
|
||||
<p class="text-center">{{ os|pluginDownloadUrl|safe }}</a></p>
|
||||
<h3>{% trans 'Or download another version' %}</h3>
|
||||
<p>{% trans 'In case that your platform has been incorrectly detected, you can download manually the version required for your Operating System' %}</p>
|
||||
<p>
|
||||
{% if os != 'linux' %}
|
||||
<p class="text-center">
|
||||
@ -31,15 +32,17 @@
|
||||
</p>
|
||||
|
||||
{% if request.user %}
|
||||
<p>{% trans 'If you already have UDS Plugin installed but this message persists to appear, you can disable it here' %}</p>
|
||||
<p>{% trans 'If you already have UDS Plugin installed but this message persists to appear, you can disable automatic detection here' %}</p>
|
||||
<p>
|
||||
<form>
|
||||
<select id="plugin" class="selectpicker show-menu-arrow" data-width="100%" data-size="2" style="display: none;">
|
||||
<option value="0">{% trans 'Automatic plugin detection is enabled' %}</option>
|
||||
<option value="1">{% trans 'Automatic plugin detection is disabled' %}</option>
|
||||
<option value="1">{% trans 'WARNING: Automatic plugin detection is disabled' %}</option>
|
||||
</select>
|
||||
</form>
|
||||
</p>
|
||||
<p>{% trans "Please, note that disabling automatic detection will not trigger this page again in case you don't have the plugin installed." %}<br/>
|
||||
{% trans "In this case, you will have to manually download the plugin by using the menu on upper right corner." %}</p>
|
||||
<p class="text-center">
|
||||
<a href="{% url 'uds.web.views.index' %}" class="btn btn-info"><i class="fa fa-home"></i> {% trans "Return" %}</a>
|
||||
</div>
|
||||
|
@ -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 = '<a href="{url}" class="btn btn-success">' + _('Download UDS Plugin for') + ' {os}</a>'
|
||||
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')
|
||||
|
@ -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'
|
||||
|
@ -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 ''
|
||||
|
@ -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 ''
|
||||
|
49
server/src/uds/transports/RDP/scripts/linux/direct.py
Normal file
49
server/src/uds/transports/RDP/scripts/linux/direct.py
Normal file
@ -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.')
|
@ -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:
|
||||
</li>
|
||||
<li>
|
||||
<p><b>CoRD</b> (A bit unstable from 10.7 onwards)</p>
|
||||
<p>You can get it from <a href="{this_server}static/other/CoRD.pkg">this link</a></p>
|
||||
<p>You can get it from <a href="{m.this_server}static/other/CoRD.pkg">this link</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>If both apps are installed, Remote Desktop Connection will be used as first option</p>
|
||||
@ -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]))
|
||||
|
@ -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:
|
||||
</li>
|
||||
<li>
|
||||
<p><b>CoRD</b> (A bit unstable from 10.7 onwards)</p>
|
||||
<p>You can get it from <a href="{this_server}static/other/CoRD.pkg">this link</a></p>
|
||||
<p>You can get it from <a href="{m.this_server}static/other/CoRD.pkg">this link</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>If both apps are installed, Remote Desktop Connection will be used as first option</p>
|
||||
@ -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]))
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user