mirror of
https://github.com/dkmstr/openuds.git
synced 2025-03-20 06:50:23 +03:00
Advancing on x2go implementation
This commit is contained in:
parent
26c0532fd5
commit
a07f1d5b24
@ -38,6 +38,7 @@ from uds.core.ui.UserInterface import gui
|
||||
from uds.core.transports.BaseTransport import Transport
|
||||
from uds.core.transports import protocols
|
||||
from uds.core.util import OsDetector
|
||||
from uds.core.util import connection
|
||||
|
||||
# This transport is specific for oVirt, so we need to point to it
|
||||
|
||||
@ -46,7 +47,7 @@ import six
|
||||
import os
|
||||
import logging
|
||||
|
||||
__updated__ = '2016-10-23'
|
||||
__updated__ = '2016-10-24'
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -89,10 +90,58 @@ class BaseX2GOTransport(Transport):
|
||||
{'id': 'gnome-session-cinnamon2d', 'text': 'Cinnamon 2.2 (see docs)'},
|
||||
], tab=gui.PARAMETERS_TAB)
|
||||
|
||||
keyboardLayout = gui.TextField(label=_('Keyboard'), order=12, tooltip=_('Keyboard layout (es, us, fr, ...). Empty value means autodetect.'),
|
||||
default='',
|
||||
sound = gui.CheckBoxField(
|
||||
order=12,
|
||||
label=_('Enable sound'),
|
||||
tooltip=_('If checked, sound will be available'),
|
||||
defvalue=gui.TRUE,
|
||||
tab=gui.PARAMETERS_TAB
|
||||
)
|
||||
|
||||
exports = gui.CheckBoxField(
|
||||
order=13,
|
||||
label=_('Redirect root folder'),
|
||||
tooltip=_('If checked, user home folder will be redirected'),
|
||||
defvalue=gui.FALSE,
|
||||
tab=gui.PARAMETERS_TAB
|
||||
)
|
||||
|
||||
|
||||
soundType = gui.ChoiceField(label=_('Desktop'), order=30, tooltip=_('Desktop session'),
|
||||
defvalue='pulse',
|
||||
values=[
|
||||
{'id': 'pulse', 'text': 'Pulse'},
|
||||
{'id': 'esd', 'text': 'ESD'},
|
||||
], tab=gui.ADVANCED_TAB
|
||||
)
|
||||
|
||||
keyboardLayout = gui.TextField(label=_('Keyboard'), order=31, tooltip=_('Keyboard layout (es, us, fr, ...). Empty value means autodetect.'),
|
||||
defvalue='',
|
||||
tab=gui.ADVANCED_TAB
|
||||
)
|
||||
# 'nopack', '8', '64', '256', '512', '4k', '32k', '64k', '256k', '2m', '16m'
|
||||
# '256-rdp', '256-rdp-compressed', '32k-rdp', '32k-rdp-compressed', '64k-rdp'
|
||||
# '64k-rdp-compressed', '16m-rdp', '16m-rdp-compressed'
|
||||
# 'rfb-hextile', 'rfb-tight', 'rfb-tight-compressed'
|
||||
# '8-tight', '64-tight', '256-tight', '512-tight', '4k-tight', '32k-tight'
|
||||
# '64k-tight', '256k-tight', '2m-tight', '16m-tight'
|
||||
# '8-jpeg-%', '64-jpeg', '256-jpeg', '512-jpeg', '4k-jpeg', '32k-jpeg'
|
||||
# '64k-jpeg', '256k-jpeg', '2m-jpeg', '16m-jpeg-%'
|
||||
# '8-png-jpeg-%', '64-png-jpeg', '256-png-jpeg', '512-png-jpeg', '4k-png-jpeg'
|
||||
# '32k-png-jpeg', '64k-png-jpeg', '256k-png-jpeg', '2m-png-jpeg', '16m-png-jpeg-%'
|
||||
# '8-png-%', '64-png', '256-png', '512-png', '4k-png'
|
||||
# '32k-png', '64k-png', '256k-png', '2m-png', '16m-png-%'
|
||||
# '16m-rgb-%', '16m-rle-%'
|
||||
pack = gui.TextField(label=_('Pack'), order=32, tooltip=_('Pack format. Change with care!'),
|
||||
defvalue='4k-jpeg',
|
||||
tab=gui.ADVANCED_TAB
|
||||
)
|
||||
|
||||
quality = gui.NumericField(label=_('Quality'), order=33, tooltip=_('Quality value used on some pack formats.'),
|
||||
length=1, defvalue='8', minValue=1, maxValue=9, required=True,
|
||||
tab=gui.ADVANCED_TAB)
|
||||
|
||||
|
||||
|
||||
def isAvailableFor(self, userService, ip):
|
||||
'''
|
||||
@ -100,7 +149,15 @@ class BaseX2GOTransport(Transport):
|
||||
Override this in yours transports
|
||||
'''
|
||||
logger.debug('Checking availability for {0}'.format(ip))
|
||||
return True # Spice is available, no matter what IP machine has (even if it does not have one)
|
||||
ready = self.cache.get(ip)
|
||||
if ready is None:
|
||||
# Check again for ready
|
||||
if connection.testServer(ip, '22') is True:
|
||||
self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT)
|
||||
return True
|
||||
else:
|
||||
self.cache.put(ip, 'N', READY_CACHE_TIMEOUT)
|
||||
return ready == 'Y'
|
||||
|
||||
def processedUser(self, userService, userName):
|
||||
v = self.processUserPassword(userService, userName, '')
|
||||
@ -117,7 +174,7 @@ class BaseX2GOTransport(Transport):
|
||||
|
||||
return {'protocol': self.protocol, 'username': username, 'password': ''}
|
||||
|
||||
def getConnectionInfo(self, service, user, password):
|
||||
def getConnectionInfo(self, service, user, password): # Password is ignored in this transport, auth is done using SSH
|
||||
return self.processUserPassword(service, user, password)
|
||||
|
||||
def genKeyPairForSsh(self):
|
||||
|
@ -32,13 +32,15 @@
|
||||
'''
|
||||
|
||||
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 .BaseX2GOTransport import BaseX2GOTransport
|
||||
from . import x2gofile
|
||||
|
||||
import logging
|
||||
|
||||
__updated__ = '2016-10-23'
|
||||
__updated__ = '2016-10-24'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -53,9 +55,60 @@ class X2GOTransport(BaseX2GOTransport):
|
||||
typeDescription = _('X2Go Transport for direct connection (EXPERIMENTAL)')
|
||||
|
||||
fixedName = BaseX2GOTransport.fixedName
|
||||
fullScreen = BaseX2GOTransport.fullScreen
|
||||
# fullScreen = BaseX2GOTransport.fullScreen
|
||||
desktopType = BaseX2GOTransport.desktopType
|
||||
sound = BaseX2GOTransport.sound
|
||||
exports = BaseX2GOTransport.exports
|
||||
|
||||
soundType = BaseX2GOTransport.soundType
|
||||
keyboardLayout = BaseX2GOTransport.keyboardLayout
|
||||
pack = BaseX2GOTransport.pack
|
||||
quality = BaseX2GOTransport.quality
|
||||
|
||||
def getUDSTransportScript(self, userService, transport, ip, os, user, password, request):
|
||||
self.getAndPushKey('user', userService)
|
||||
return ''
|
||||
prefs = user.prefs('nx')
|
||||
|
||||
priv, pub = self.getAndPushKey('user', userService)
|
||||
|
||||
prefs = user.prefs('rdp')
|
||||
|
||||
ci = self.getConnectionInfo(userService, user, password)
|
||||
username = ci['username']
|
||||
|
||||
width, height = CommonPrefs.getWidthHeight(prefs)
|
||||
xf = x2gofile.getTemplate(
|
||||
pack=self.pack.value,
|
||||
quality=self.quality.value,
|
||||
sound=self.sound.isTrue(),
|
||||
soundSystem=self.sound.value,
|
||||
windowManager=self.desktopType.value,
|
||||
exports=self.exports.isTrue())
|
||||
|
||||
# data
|
||||
data = {
|
||||
'os': os['OS'],
|
||||
'ip': ip,
|
||||
'port': 22,
|
||||
'username': username,
|
||||
'key': priv,
|
||||
'width': width,
|
||||
'height': height,
|
||||
'printers': True,
|
||||
'drives': self.exports.isTrue(),
|
||||
'fullScreen': width == -1 or height == -1,
|
||||
'this_server': request.build_absolute_uri('/'),
|
||||
'xf': xf
|
||||
}
|
||||
|
||||
m = tools.DictAsObj(data)
|
||||
|
||||
os = {
|
||||
OsDetector.Windows: 'windows',
|
||||
OsDetector.Linux: 'linux',
|
||||
# OsDetector.Macintosh: 'macosx'
|
||||
}.get(m.os)
|
||||
|
||||
if os is None:
|
||||
return super(X2GOTransport, self).getUDSTransportScript(self, userService, transport, ip, os, user, password, request)
|
||||
|
||||
return self.getScript('scripts/{}/direct.py'.format(os)).format(m=m)
|
||||
|
@ -35,3 +35,7 @@ from django.utils.translation import ugettext_noop as _
|
||||
from uds.core.managers.UserPrefsManager import UserPrefsManager, CommonPrefs
|
||||
from .X2GOTransport import X2GOTransport
|
||||
from .TX2GOTransport import TX2GOTransport
|
||||
|
||||
|
||||
# We will use same prefs as for NX, X2GO is based on it
|
||||
UserPrefsManager.manager().registerPrefs('nx', _('NX Protocol'), [CommonPrefs.screenSizePref])
|
||||
|
27
server/src/uds/transports/X2GO/scripts/windows/direct.py
Normal file
27
server/src/uds/transports/X2GO/scripts/windows/direct.py
Normal file
@ -0,0 +1,27 @@
|
||||
# This is a template
|
||||
# Saved as .py for easier editing
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# pylint: disable=import-error, no-name-in-module
|
||||
from PyQt4 import QtCore, QtGui
|
||||
import win32crypt # @UnresolvedImport
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from uds import tools # @UnresolvedImport
|
||||
|
||||
import six
|
||||
|
||||
# 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
|
||||
keyFile = tools.saveTempFile('''{m.key}''')
|
||||
theFile = '''{m.xf}'''.format(exports='c:\\', keyFile=keyFile.replace('\\', '/'), ip='{m.ip}')
|
||||
filename = tools.saveTempFile(theFile)
|
||||
|
||||
x2goPath = os.environ['PROGRAMFILES(X86)'] + '\\x2goclient'
|
||||
executable = tools.findApp('x2goclient.exe', [x2goPath])
|
||||
|
||||
# executable = tools.findApp('mstsc.exe')
|
||||
# subprocess.Popen([executable, filename])
|
||||
# tools.addFileToUnlink(filename)
|
||||
|
||||
QtGui.QMessageBox.critical(parent, 'Notice', executable + ' -- ' + keyFile + ', ' + filename, QtGui.QMessageBox.Ok) # @UndefinedVariable
|
38
server/src/uds/transports/X2GO/scripts/windows/tunnel.py
Normal file
38
server/src/uds/transports/X2GO/scripts/windows/tunnel.py
Normal file
@ -0,0 +1,38 @@
|
||||
# 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
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
import win32crypt # @UnresolvedImport
|
||||
import os
|
||||
import subprocess
|
||||
from uds.forward import forward # @UnresolvedImport
|
||||
|
||||
from uds import tools # @UnresolvedImport
|
||||
|
||||
import six
|
||||
|
||||
forwardThread, port = forward('{m.tunHost}', '{m.tunPort}', '{m.tunUser}', '{m.tunPass}', '{m.ip}', 3389)
|
||||
|
||||
if forwardThread.status == 2:
|
||||
raise Exception('Unable to open tunnel')
|
||||
|
||||
tools.addTaskToWait(forwardThread)
|
||||
|
||||
# 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 = '''{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)
|
||||
)
|
||||
|
||||
filename = tools.saveTempFile(theFile)
|
||||
executable = tools.findApp('mstsc.exe')
|
||||
if executable is None:
|
||||
raise Exception('Unable to find mstsc.exe')
|
||||
|
||||
subprocess.Popen([executable, filename])
|
||||
tools.addFileToUnlink(filename)
|
||||
|
||||
# QtGui.QMessageBox.critical(parent, 'Notice', filename + ", " + executable, QtGui.QMessageBox.Ok)
|
@ -34,12 +34,12 @@
|
||||
template = '''[General]
|
||||
UDS=@ByteArray()
|
||||
|
||||
[20161019100758147]
|
||||
[20160101100758147]
|
||||
speed=4
|
||||
pack=16m-jpeg
|
||||
quality=8
|
||||
pack={pack}
|
||||
quality={quality}
|
||||
fstunnel=true
|
||||
export="/home/user:1;"
|
||||
{export}
|
||||
iconvto=UTF-8
|
||||
iconvfrom=ISO8859-1
|
||||
useiconv=false
|
||||
@ -57,18 +57,18 @@ xinerama=false
|
||||
clipboard=both
|
||||
usekbd=true
|
||||
type=auto
|
||||
sound=true
|
||||
soundsystem=pulse
|
||||
sound={sound}
|
||||
soundsystem={soundSystem}
|
||||
startsoundsystem=true
|
||||
soundtunnel=true
|
||||
defsndport=true
|
||||
sndport=4713
|
||||
print=true
|
||||
name=UDS/uds-test
|
||||
name=UDS/connect
|
||||
icon=:/img/icons/128x128/x2gosession.png
|
||||
host=172.27.0.208
|
||||
host={{ip}}
|
||||
user=user
|
||||
key=/home/user/remotekey.txt
|
||||
key={{keyFile}}
|
||||
rdpport=3389
|
||||
sshport=22
|
||||
autologin=false
|
||||
@ -78,7 +78,7 @@ directrdp=false
|
||||
rootless=false
|
||||
published=false
|
||||
applications=WWWBROWSER, MAILCLIENT, OFFICE, TERMINAL
|
||||
command=XFCE
|
||||
command={windowManager}
|
||||
rdpoptions=
|
||||
rdpserver=
|
||||
xdmcpserver=localhost
|
||||
@ -93,3 +93,8 @@ sshproxysameuser=false
|
||||
sshproxyautologin=false
|
||||
sshproxykrblogin=false
|
||||
'''
|
||||
|
||||
def getTemplate(pack, quality, sound, soundSystem, windowManager, exports):
|
||||
trueFalse = lambda(x): 'true' if x else 'false'
|
||||
export = 'export="{{export}}"' if exports else ''
|
||||
return template.format(pack=pack, quality=quality, sound=trueFalse(sound), soundSystem=soundSystem, windowManager=windowManager, export=export)
|
||||
|
Loading…
x
Reference in New Issue
Block a user