Moved several transports to newer "form storage" model, much more simple

than "hand made" marshalling/unmarshallig (Note: Nx has been keeped
using "old" method because it will be not be updated anymore, we are
moving to use x2go instead in future releas)
This commit is contained in:
Adolfo Gómez García 2014-12-08 12:14:36 +01:00
parent 7c916397e4
commit 06a00d00b9
12 changed files with 442 additions and 553 deletions

View File

@ -152,12 +152,11 @@ class Transport(Module):
''' '''
return None return None
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password): def renderForHtml(self, userService, transport, ip, os, user, password):
''' '''
Requests the html rendering of connector for the destination ip, (dbUser) and password Requests the html rendering of connector for the destination ip, (dbUser) and password
@param: userService: DeployedUserService for witch we are rendering the connection (db model) @param: userService: UserService for witch we are rendering the connection (db model)
@param idUserService: id of the user service ((scrambled). You will need this to "notify" anythig to broker (such as log, hostname of client, ip, ...) @param transport: Transport (self db model)
@param idTransport: id of the transport (scrambled)
@param ip: ip of the destination @param ip: ip of the destination
@param user: user (dbUser) logged in @param user: user (dbUser) logged in
@param pass: password used in authentication @param pass: password used in authentication

View File

@ -33,6 +33,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.utils.translation import get_language, ugettext as _ from django.utils.translation import get_language, ugettext as _
import six
import pickle import pickle
import logging import logging
@ -357,7 +358,11 @@ class gui(object):
''' '''
Return value as integer Return value as integer
''' '''
return int(self.value) try:
v = int(self.value)
except Exception:
v = 0
return v
class PasswordField(InputField): class PasswordField(InputField):
''' '''
@ -695,13 +700,15 @@ class UserInterface(object):
# Generate a deep copy of inherited Gui, so each User Interface instance has its own "field" set, and do not share the "fielset" with others, what can be really dangerous # Generate a deep copy of inherited Gui, so each User Interface instance has its own "field" set, and do not share the "fielset" with others, what can be really dangerous
# Till now, nothing bad happened cause there where being used "serialized", but this do not have to be this way # Till now, nothing bad happened cause there where being used "serialized", but this do not have to be this way
self._gui = copy.deepcopy(self._gui) # Ensure "gui" is our own instance, deep copied from base self._gui = copy.deepcopy(self._gui) # Ensure "gui" is our own instance, deep copied from base
for key, val in self._gui.iteritems(): # And refresg references to them for key, val in self._gui.iteritems(): # And refresh references to them
setattr(self, key, val) setattr(self, key, val)
if values is not None: if values is not None:
for k, v in self._gui.iteritems(): for k, v in self._gui.iteritems():
if k in values: if k in values:
v.value = values[k] v.value = values[k]
else:
logger.warn('Field {} not found'.format(k))
def initGui(self): def initGui(self):
''' '''
@ -782,6 +789,8 @@ class UserInterface(object):
if v.isType(gui.InputField.EDITABLE_LIST) or v.isType(gui.InputField.MULTI_CHOICE_TYPE): if v.isType(gui.InputField.EDITABLE_LIST) or v.isType(gui.InputField.MULTI_CHOICE_TYPE):
logger.debug('Serializing value {0}'.format(v.value)) logger.debug('Serializing value {0}'.format(v.value))
val = '\001' + pickle.dumps(v.value) val = '\001' + pickle.dumps(v.value)
elif v.isType(gui.InputField.NUMERIC_TYPE):
val = six.text_type(int(v.num()))
else: else:
val = v.value val = v.value
if val is True: if val is True:

View File

@ -0,0 +1,215 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from uds.core.ui.UserInterface import gui
from uds.transports.RDP.RDPTransport import RDPTransport
from uds.transports.RDP.TSRDPTransport import TSRDPTransport
try:
from uds.transports.RGS import RGSTransport # @UnresolvedImport, pylint: disable=import-error, no-name-in-module
from uds.transports.RGS import TRGSTransport # @UnresolvedImport, pylint: disable=import-error, no-name-in-module
except Exception:
from uds.transports.RGS_enterprise import RGSTransport # @UnresolvedImport @Reimport, pylint: disable=import-error, no-name-in-module
from uds.transports.RGS_enterprise import TRGSTransport # @UnresolvedImport @Reimport, pylint: disable=import-error, no-name-in-module
from uds.core.Environment import Environment
def unmarshalRDP(str_):
data = str_.split('\t')
if data[0] in ('v1', 'v2', 'v3'):
useEmptyCreds = gui.strToBool(data[1])
allowSmartcards = gui.strToBool(data[2])
allowPrinters = gui.strToBool(data[3])
allowDrives = gui.strToBool(data[4])
allowSerials = gui.strToBool(data[5])
if data[0] == 'v1':
wallpaper = False
i = 0
if data[0] in ('v2', 'v3'):
wallpaper = gui.strToBool(data[6])
i = 1
fixedName = data[6 + i]
fixedPassword = data[7 + i]
fixedDomain = data[8 + i]
if data[0] == 'v3':
withoutDomain = gui.strToBool(data[9 + i])
else:
withoutDomain = False
return {
'useEmptyCreds': useEmptyCreds,
'allowSmartcards': allowSmartcards,
'allowPrinters': allowPrinters,
'allowDrives': allowDrives,
'allowSerials': allowSerials,
'wallpaper': wallpaper,
'fixedName': fixedName,
'fixedPassword': fixedPassword,
'fixedDomain': fixedDomain,
'withoutDomain': withoutDomain
}
def unmarshalTSRDP(str_):
data = str_.split('\t')
if data[0] in ('v1', 'v2', 'v3'):
useEmptyCreds = gui.strToBool(data[1])
allowSmartcards = gui.strToBool(data[2])
allowPrinters = gui.strToBool(data[3])
allowDrives = gui.strToBool(data[4])
allowSerials = gui.strToBool(data[5])
if data[0] == 'v1':
wallpaper = False
i = 0
if data[0] in ('v2', 'v3'):
wallpaper = gui.strToBool(data[6])
i = 1
fixedName = data[6 + i]
fixedPassword = data[7 + i]
fixedDomain = data[8 + i]
tunnelServer = data[9 + i]
tunnelCheckServer = data[10 + i]
if data[0] == 'v3':
withoutDomain = gui.strToBool(data[11 + i])
else:
withoutDomain = False
return {
'useEmptyCreds': useEmptyCreds,
'allowSmartcards': allowSmartcards,
'allowPrinters': allowPrinters,
'allowDrives': allowDrives,
'allowSerials': allowSerials,
'wallpaper': wallpaper,
'fixedName': fixedName,
'fixedPassword': fixedPassword,
'fixedDomain': fixedDomain,
'withoutDomain': withoutDomain,
'tunnelServer': tunnelServer,
'tunnelCheckServer': tunnelCheckServer
}
def unmarshalRGS(data):
data = data.split('\t')
if data[0] == 'v1':
useEmptyCreds = gui.strToBool(data[1])
fixedName = data[2]
fixedPassword = data[3]
fixedDomain = data[4]
imageQuality = data[5]
adjustableQuality = gui.strToBool(data[6])
minAdjustableQuality = data[7]
minAdjustableRate = data[8]
matchLocalDisplay = gui.strToBool(data[9])
redirectUSB = gui.strToBool(data[10])
redirectAudio = gui.strToBool(data[11])
redirectMIC = gui.strToBool(data[12])
return {
'fixedName': fixedName,
'fixedPassword': fixedPassword,
'fixedDomain': fixedDomain,
'useEmptyCreds': useEmptyCreds,
'imageQuality': imageQuality,
'adjustableQuality': adjustableQuality,
'minAdjustableQuality': minAdjustableQuality,
'minAdjustableRate': minAdjustableRate,
'matchLocalDisplay': matchLocalDisplay,
'redirectUSB': redirectUSB,
'redirectAudio': redirectAudio,
'redirectMIC': redirectMIC
}
def unmarshalTRGS(data):
data = data.split('\t')
if data[0] == 'v1':
useEmptyCreds = gui.strToBool(data[1])
fixedName = data[2]
fixedPassword = data[3]
fixedDomain = data[4]
imageQuality = int(data[5])
adjustableQuality = gui.strToBool(data[6])
minAdjustableQuality = int(data[7])
minAdjustableRate = int(data[8])
matchLocalDisplay = gui.strToBool(data[9])
redirectUSB = gui.strToBool(data[10])
redirectAudio = gui.strToBool(data[11])
redirectMIC = gui.strToBool(data[12])
tunnelServer = data[13]
tunnelCheckServer = data[14]
return {
'fixedName': fixedName,
'fixedPassword': fixedPassword,
'fixedDomain': fixedDomain,
'useEmptyCreds': useEmptyCreds,
'imageQuality': imageQuality,
'adjustableQuality': adjustableQuality,
'minAdjustableQuality': minAdjustableQuality,
'minAdjustableRate': minAdjustableRate,
'matchLocalDisplay': matchLocalDisplay,
'redirectUSB': redirectUSB,
'redirectAudio': redirectAudio,
'redirectMIC': redirectMIC,
'tunnelServer': tunnelServer,
'tunnelCheckServer': tunnelCheckServer
}
def transformTransports(apps, schema_editor):
'''
Adds uuids values to migrated models
'''
model = apps.get_model("uds", 'Transport')
for t in model.objects.all():
if t.data_type == RDPTransport.typeType:
values = unmarshalRDP(t.data.decode(RDPTransport.CODEC))
rdp = RDPTransport(Environment.getTempEnv(), values)
t.data = rdp.serialize()
t.save()
if t.data_type == TSRDPTransport.typeType:
values = unmarshalTSRDP(t.data.decode(TSRDPTransport.CODEC))
rdp = TSRDPTransport(Environment.getTempEnv(), values)
t.data = rdp.serialize()
t.save()
if t.data_type == RGSTransport.typeType:
values = unmarshalRGS(t.data.decode(RGSTransport.CODEC))
rgs = RGSTransport(Environment.getTempEnv(), values)
t.data = rgs.serialize()
t.save()
if t.data_type == TRGSTransport.typeType:
values = unmarshalTRGS(t.data.decode(TRGSTransport.CODEC))
rgs = TRGSTransport(Environment.getTempEnv(), values)
t.data = rgs.serialize()
t.save()
def untransformTransports(apps, schema_editor):
raise Exception('This migration can\'t be undone')
class Migration(migrations.Migration):
dependencies = [
('uds', '0008_userserviceproperty'),
]
operations = [
migrations.RunPython(
transformTransports,
untransformTransports
),
]

View File

@ -42,6 +42,7 @@ from uds.core.transports import protocols
from uds.core.util import connection from uds.core.util import connection
from uds.core.util import OsDetector from uds.core.util import OsDetector
import uuid
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -87,53 +88,51 @@ class HTML5RDPTransport(Transport):
ready = self.cache().get(ip) ready = self.cache().get(ip)
if ready is None: if ready is None:
# Check again for readyness # Check again for readyness
if connection.testServer(ip, '3389') == True: if connection.testServer(ip, '3389') is True:
self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT) self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT)
return True return True
else: else:
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT) self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y' return ready == 'Y'
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password): def renderForHtml(self, userService, transport, ip, os, user, password):
# We use helper to keep this clean # We use helper to keep this clean
import uuid
username = user.getUsernameForAuth() username = user.getUsernameForAuth()
if self.fixedName.value is not '': if self._fixedName is not '':
username = self.fixedName.value username = self._fixedName
domain = '' proc = username.split('@')
if username.find('@') != -1: if len(proc) > 1:
username, domain = username.split('@') domain = proc[1]
elif username.find('\\') != -1: else:
domain, username = username.split('\\') domain = ''
username = proc[0]
if self.fixedPassword.value is not '': if self._fixedPassword is not '':
password = self.fixedPassword.value password = self._fixedPassword
if self.fixedDomain.value is not '': if self._fixedDomain is not '':
domain = self.fixedDomain.value domain = self._fixedDomain
if self.useEmptyCreds.isTrue(): if self._useEmptyCreds is True:
username, password, domain = '', '', '' username, password, domain = '', '', ''
if self.withoutDomain.isTrue(): if self._withoutDomain is True:
domain = '' domain = ''
if '.' in domain: # Dotter domain form
username = username + '@' + domain
domain = ''
# Fix username/password acording to os manager # Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password) username, password = userService.processUserPassword(username, password)
if domain != '':
if domain.find('.') == -1:
username = domain + '\\' + username
else:
username = username + '@' + domain
# Build params dict # Build params dict
params = { 'protocol':'rdp', params = {
'hostname':ip, 'username': username, 'password': password, 'protocol': 'rdp',
'ignore-cert': 'true' 'hostname': ip,
'username': username,
'password': password,
'ignore-cert': 'true'
} }
if self.enableAudio.isTrue() is False: if self.enableAudio.isTrue() is False:

View File

@ -64,39 +64,42 @@ class NXTransport(Transport):
fixedName = gui.TextField(label=_('Username'), order=2, tooltip=_('If not empty, this username will be always used as credential')) fixedName = gui.TextField(label=_('Username'), order=2, tooltip=_('If not empty, this username will be always used as credential'))
fixedPassword = gui.PasswordField(label=_('Password'), order=3, tooltip=_('If not empty, this password will be always used as credential')) fixedPassword = gui.PasswordField(label=_('Password'), order=3, tooltip=_('If not empty, this password will be always used as credential'))
listenPort = gui.NumericField(label=_('Listen port'), length=5, order=4, tooltip=_('Listening port of NX (ssh) at client machine'), defvalue='22') listenPort = gui.NumericField(label=_('Listen port'), length=5, order=4, tooltip=_('Listening port of NX (ssh) at client machine'), defvalue='22')
connection = gui.ChoiceField(label=_('Connection'), order=6, tooltip=_('Connection speed for this transport (quality)'), values=[ connection = gui.ChoiceField(label=_('Connection'), order=6, tooltip=_('Connection speed for this transport (quality)'),
{'id' : 'modem', 'text' : 'modem'}, values=[
{'id' : 'isdn', 'text' : 'isdn'}, {'id': 'modem', 'text': 'modem'},
{'id' : 'adsl', 'text' : 'adsl'}, {'id': 'isdn', 'text': 'isdn'},
{'id' : 'wan', 'text' : 'wan'}, {'id': 'adsl', 'text': 'adsl'},
{'id' : 'lan', 'text' : 'lan'}, {'id': 'wan', 'text': 'wan'},
]) {'id': 'lan', 'text': 'lan'}
session = gui.ChoiceField(label=_('Session'), order=7, tooltip=_('Desktop session'), values=[ ])
{'id' : 'gnome', 'text' : 'gnome'}, session = gui.ChoiceField(label=_('Session'), order=7, tooltip=_('Desktop session'),
{'id' : 'kde', 'text' : 'kde'}, values=[
{'id' : 'cde', 'text' : 'cde'}, {'id': 'gnome', 'text': 'gnome'},
]) {'id': 'kde', 'text': 'kde'},
cacheDisk = gui.ChoiceField(label=_('Disk Cache'), order=8, tooltip=_('Cache size en Mb stored at disk'), values=[ {'id': 'cde', 'text': 'cde'},
{'id' : '0', 'text' : '0 Mb'}, ])
{'id' : '32', 'text' : '32 Mb'}, cacheDisk = gui.ChoiceField(label=_('Disk Cache'), order=8, tooltip=_('Cache size en Mb stored at disk'),
{'id' : '64', 'text' : '64 Mb'}, values=[
{'id' : '128', 'text' : '128 Mb'}, {'id': '0', 'text': '0 Mb'},
{'id' : '256', 'text' : '256 Mb'}, {'id': '32', 'text': '32 Mb'},
{'id' : '512', 'text' : '512 Mb'}, {'id': '64', 'text': '64 Mb'},
]) {'id': '128', 'text': '128 Mb'},
cacheMem = gui.ChoiceField(label=_('Memory Cache'), order=9, tooltip=_('Cache size en Mb keept at memory'), values=[ {'id': '256', 'text': '256 Mb'},
{'id' : '4', 'text' : '4 Mb'}, {'id': '512', 'text': '512 Mb'},
{'id' : '8', 'text' : '8 Mb'}, ])
{'id' : '16', 'text' : '16 Mb'}, cacheMem = gui.ChoiceField(label=_('Memory Cache'), order=9, tooltip=_('Cache size en Mb keept at memory'),
{'id' : '32', 'text' : '32 Mb'}, values=[
{'id' : '64', 'text' : '64 Mb'}, {'id': '4', 'text': '4 Mb'},
{'id' : '128', 'text' : '128 Mb'}, {'id': '8', 'text': '8 Mb'},
]) {'id': '16', 'text': '16 Mb'},
{'id': '32', 'text': '32 Mb'},
{'id': '64', 'text': '64 Mb'},
{'id': '128', 'text': '128 Mb'},
])
def __init__(self, environment, values=None): def __init__(self, environment, values=None):
super(NXTransport, self).__init__(environment, values) super(NXTransport, self).__init__(environment, values)
if values != None: if values is not None:
self._useEmptyCreds = gui.strToBool(values['useEmptyCreds']) self._useEmptyCreds = gui.strToBool(values['useEmptyCreds'])
self._fixedName = values['fixedName'] self._fixedName = values['fixedName']
self._fixedPassword = values['fixedPassword'] self._fixedPassword = values['fixedPassword']
@ -128,12 +131,17 @@ class NXTransport(Transport):
self._useEmptyCreds = gui.strToBool(data[1]) self._useEmptyCreds = gui.strToBool(data[1])
self._fixedName, self._fixedPassword, self._listenPort, self._connection, self._session, self._cacheDisk, self._cacheMem = data[2:] self._fixedName, self._fixedPassword, self._listenPort, self._connection, self._session, self._cacheDisk, self._cacheMem = data[2:]
def valuesDict(self): def valuesDict(self):
return { 'useEmptyCreds' : gui.boolToStr(self._useEmptyCreds), 'fixedName' : self._fixedName, return {
'fixedPassword' : self._fixedPassword, 'listenPort': self._listenPort, 'useEmptyCreds': gui.boolToStr(self._useEmptyCreds),
'connection' : self._connection, 'session' : self._session, 'cacheDisk' : self._cacheDisk, 'fixedName': self._fixedName,
'cacheMem' : self._cacheMem } 'fixedPassword': self._fixedPassword,
'listenPort': self._listenPort,
'connection': self._connection,
'session': self._session,
'cacheDisk': self._cacheDisk,
'cacheMem': self._cacheMem
}
def isAvailableFor(self, ip): def isAvailableFor(self, ip):
''' '''
@ -144,14 +152,14 @@ class NXTransport(Transport):
ready = self.cache().get(ip) ready = self.cache().get(ip)
if ready is None: if ready is None:
# Check again for readyness # Check again for readyness
if connection.testServer(ip, self._listenPort) == True: if connection.testServer(ip, self._listenPort) is True:
self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT) self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT)
return True return True
else: else:
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT) self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y' return ready == 'Y'
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password): def renderForHtml(self, userService, transport, ip, os, user, password):
prefs = user.prefs('nx') prefs = user.prefs('nx')
@ -170,15 +178,20 @@ class NXTransport(Transport):
width, height = CommonPrefs.getWidthHeight(prefs) width, height = CommonPrefs.getWidthHeight(prefs)
# Extra data # Extra data
extra = { 'width': width, 'height' : height, extra = {
'port' : self._listenPort, 'connection' : self._connection, 'width': width,
'session' : self._session, 'cacheDisk': self._cacheDisk, 'height': height,
'cacheMem' : self._cacheMem } 'port': self._listenPort,
'connection': self._connection,
'session': self._session,
'cacheDisk': self._cacheDisk,
'cacheMem': self._cacheMem
}
# Fix username/password acording to os manager # Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password) username, password = userService.processUserPassword(username, password)
return generateHtmlForNX(self, idUserService, idTransport, ip, os, username, password, extra) return generateHtmlForNX(self, userService.uuid, transport.uuid, ip, os, username, password, extra)
def getHtmlComponent(self, theId, os, componentId): def getHtmlComponent(self, theId, os, componentId):
# We use helper to keep this clean # We use helper to keep this clean

View File

@ -1,221 +0,0 @@
# -*- 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.
'''
Created on Jul 29, 2011
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from django.utils.translation import ugettext_noop as _
from uds.core.managers.UserPrefsManager import CommonPrefs
from uds.core.ui.UserInterface import gui
from uds.core.transports.BaseTransport import Transport
from uds.core.transports import protocols
from uds.core.util.Cache import Cache
from uds.core.util import connection
from web import generateHtmlForNX, getHtmlComponent
import logging
import random
import string
import time
logger = logging.getLogger(__name__)
READY_CACHE_TIMEOUT = 30
class TSNXTransport(Transport):
'''
Provides access via NX to service. using tunnel
'''
typeName = _('NX Transport (tunneled)')
typeType = 'TSNXTransport'
typeDescription = _('NX Transport for tunneled connection')
iconFile = 'nx.png'
needsJava = True # If this transport needs java for rendering
supportedOss = ['Windows', 'Macintosh', 'Linux']
protocol = protocols.NX
tunnelServer = gui.TextField(label=_('Tunnel server'), order=1, tooltip=_('IP or Hostname of tunnel server send to client device ("public" ip) and port. (use HOST:PORT format)'))
tunnelCheckServer = gui.TextField(label=_('Tunnel host check'), order=2, tooltip=_('If not empty, this server will be used to check if service is running before assigning it to user. (use HOST:PORT format)'))
useEmptyCreds = gui.CheckBoxField(label=_('Empty creds'), order=3, tooltip=_('If checked, the credentials used to connect will be emtpy'))
fixedName = gui.TextField(label=_('Username'), order=4, tooltip=_('If not empty, this username will be always used as credential'))
fixedPassword = gui.PasswordField(label=_('Password'), order=5, tooltip=_('If not empty, this password will be always used as credential'))
listenPort = gui.NumericField(label=_('Listen port'), length=5, order=6, tooltip=_('Listening port of NX (ssh) at client machine'), defvalue='22')
connection = gui.ChoiceField(label=_('Connection'),
order=7,
tooltip=_('Connection speed for this transport (quality)'),
values=[
{'id': 'modem', 'text': 'modem'},
{'id': 'isdn', 'text': 'isdn'},
{'id': 'adsl', 'text': 'adsl'},
{'id': 'wan', 'text': 'wan'},
{'id': 'lan', 'text': 'lan'},
]
)
session = gui.ChoiceField(label=_('Session'), order=8, tooltip=_('Desktop session'), values=[
{'id' : 'gnome', 'text' : 'gnome'},
{'id' : 'kde', 'text' : 'kde'},
{'id' : 'cde', 'text' : 'cde'},
])
cacheDisk = gui.ChoiceField(label=_('Disk Cache'), order=9, tooltip=_('Cache size en Mb stored at disk'), values=[
{'id' : '0', 'text' : '0 Mb'},
{'id' : '32', 'text' : '32 Mb'},
{'id' : '64', 'text' : '64 Mb'},
{'id' : '128', 'text' : '128 Mb'},
{'id' : '256', 'text' : '256 Mb'},
{'id' : '512', 'text' : '512 Mb'},
])
cacheMem = gui.ChoiceField(label=_('Memory Cache'), order=10, tooltip=_('Cache size en Mb keept at memory'), values=[
{'id' : '4', 'text' : '4 Mb'},
{'id' : '8', 'text' : '8 Mb'},
{'id' : '16', 'text' : '16 Mb'},
{'id' : '32', 'text' : '32 Mb'},
{'id' : '64', 'text' : '64 Mb'},
{'id' : '128', 'text' : '128 Mb'},
])
def __init__(self, environment, values=None):
super(TSNXTransport, self).__init__(environment, values)
if values != None:
if values['tunnelServer'].count(':') != 1:
raise Transport.ValidationException(_('Must use HOST:PORT in Tunnel Server Field'))
self._tunnelServer = values['tunnelServer']
self._tunnelCheckServer = values['tunnelCheckServer']
self._useEmptyCreds = gui.strToBool(values['useEmptyCreds'])
self._fixedName = values['fixedName']
self._fixedPassword = values['fixedPassword']
self._listenPort = values['listenPort']
self._connection = values['connection']
self._session = values['session']
self._cacheDisk = values['cacheDisk']
self._cacheMem = values['cacheMem']
else:
self._tunnelServer = ''
self._tunnelCheckServer = ''
self._useEmptyCreds = False
self._fixedName = ''
self._fixedPassword = ''
self._listenPort = ''
self._connection = ''
self._session = ''
self._cacheDisk = ''
self._cacheMem = ''
def marshal(self):
'''
Serializes the transport data so we can store it in database
'''
return str.join('\t', ['v1', gui.boolToStr(self._useEmptyCreds), self._fixedName, self._fixedPassword, self._listenPort,
self._connection, self._session, self._cacheDisk, self._cacheMem, self._tunnelServer, self._tunnelCheckServer])
def unmarshal(self, string):
data = string.split('\t')
if data[0] == 'v1':
self._useEmptyCreds = gui.strToBool(data[1])
self._fixedName, self._fixedPassword, self._listenPort, self._connection, self._session, self._cacheDisk, self._cacheMem, self._tunnelServer, self._tunnelCheckServer = data[2:]
def valuesDict(self):
return {
'useEmptyCreds': gui.boolToStr(self._useEmptyCreds),
'fixedName': self._fixedName,
'fixedPassword': self._fixedPassword,
'listenPort': self._listenPort,
'connection': self._connection,
'session': self._session,
'cacheDisk': self._cacheDisk,
'cacheMem': self._cacheMem,
'tunnelServer': self._tunnelServer,
'tunnelCheckServer': self._tunnelCheckServer
}
def isAvailableFor(self, ip):
'''
Checks if the transport is available for the requested destination ip
Override this in yours transports
'''
logger.debug('Checking availability for {0}'.format(ip))
ready = self.cache().get(ip)
if ready is None:
# Check again for readyness
if connection.testServer(ip, self._listenPort) == True:
self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT)
return True
else:
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y'
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password):
prefs = user.prefs('nx')
username = user.getUsernameForAuth()
proc = username.split('@')
username = proc[0]
if self._fixedName is not '':
username = self._fixedName
if self._fixedPassword is not '':
password = self._fixedPassword
if self._useEmptyCreds is True:
username, password = '', ''
width, height = CommonPrefs.getWidthHeight(prefs)
cache = Cache('pam')
tunuser = ''.join(random.choice(string.letters + string.digits) for _ in range(12)) + ("%f" % time.time()).split('.')[1]
tunpass = ''.join(random.choice(string.letters + string.digits) for _ in range(12))
cache.put(tunuser, tunpass, 60 * 10) # Credential valid for ten minutes, and for 1 use only
sshHost, sshPort = self._tunnelServer.split(':')
logger.debug('Username generated: {0}, password: {1}'.format(tunuser, tunpass))
tun = "{0} {1} {2} {3} {4} {5} {6}".format(tunuser, tunpass, sshHost, sshPort, ip, self._listenPort, '9')
# Extra data
extra = {
'width': width,
'height': height,
'connection': self._connection,
'session': self._session,
'cacheDisk': self._cacheDisk,
'cacheMem': self._cacheMem,
'tun': tun
}
# Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password)
return generateHtmlForNX(self, idUserService, idTransport, ip, os, username, password, extra)
def getHtmlComponent(self, theId, os, componentId):
# We use helper to keep this clean
return getHtmlComponent(self.__module__, componentId)

View File

@ -37,7 +37,7 @@ from uds.core.ui.UserInterface import gui
from uds.core.transports.BaseTransport import Transport from uds.core.transports.BaseTransport import Transport
from uds.core.transports import protocols from uds.core.transports import protocols
from uds.core.util import connection from uds.core.util import connection
from web import generateHtmlForRdp, getHtmlComponent from .web import generateHtmlForRdp, getHtmlComponent
import logging import logging
@ -69,72 +69,8 @@ class RDPTransport(Transport):
allowSerials = gui.CheckBoxField(label=_('Allow Serials'), order=9, tooltip=_('If checked, this transport will allow the use of user serial ports')) allowSerials = gui.CheckBoxField(label=_('Allow Serials'), order=9, tooltip=_('If checked, this transport will allow the use of user serial ports'))
wallpaper = gui.CheckBoxField(label=_('Show wallpaper'), order=10, tooltip=_('If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)')) wallpaper = gui.CheckBoxField(label=_('Show wallpaper'), order=10, tooltip=_('If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)'))
def __init__(self, environment, values=None): def initialize(self, values):
super(RDPTransport, self).__init__(environment, values) return
self._useEmptyCreds = False
self._fixedName = ''
self._fixedPassword = ''
self._fixedDomain = ''
self._allowSmartcards = False
self._allowPrinters = False
self._allowDrives = False
self._allowSerials = False
self._wallPaper = False
self._withoutDomain = False
if values != None:
try:
self._useEmptyCreds = gui.strToBool(values['useEmptyCreds'])
self._fixedName = values['fixedName']
self._fixedPassword = values['fixedPassword']
self._fixedDomain = values['fixedDomain']
self._allowSmartcards = gui.strToBool(values['allowSmartcards'])
self._allowPrinters = gui.strToBool(values['allowPrinters'])
self._allowDrives = gui.strToBool(values['allowDrives'])
self._allowSerials = gui.strToBool(values['allowSerials'])
self._wallPaper = gui.strToBool(values['wallpaper'])
self._withoutDomain = gui.strToBool(values['withoutDomain'])
except:
logger.exception('Some value was missing on RTP Transport')
def marshal(self):
'''
Serializes the transport data so we can store it in database
'''
return str.join('\t', [ 'v3', gui.boolToStr(self._useEmptyCreds), gui.boolToStr(self._allowSmartcards), gui.boolToStr(self._allowPrinters),
gui.boolToStr(self._allowDrives), gui.boolToStr(self._allowSerials), gui.boolToStr(self._wallPaper),
self._fixedName, self._fixedPassword, self._fixedDomain, gui.boolToStr(self._withoutDomain) ])
def unmarshal(self, str_):
data = str_.split('\t')
if data[0] in ('v1', 'v2', 'v3'):
self._useEmptyCreds = gui.strToBool(data[1])
self._allowSmartcards = gui.strToBool(data[2])
self._allowPrinters = gui.strToBool(data[3])
self._allowDrives = gui.strToBool(data[4])
self._allowSerials = gui.strToBool(data[5])
if data[0] == 'v1':
self._wallPaper = False
i = 0
if data[0] in ('v2', 'v3'):
self._wallPaper = gui.strToBool(data[6])
i = 1
self._fixedName = data[6 + i]
self._fixedPassword = data[7 + i]
self._fixedDomain = data[8 + i]
if data[0] == 'v3':
self._withoutDomain = gui.strToBool(data[9 + i])
def valuesDict(self):
return { 'allowSmartcards' : gui.boolToStr(self._allowSmartcards), 'allowPrinters' : gui.boolToStr(self._allowPrinters),
'allowDrives': gui.boolToStr(self._allowDrives), 'allowSerials': gui.boolToStr(self._allowSerials),
'fixedName' : self._fixedName, 'fixedPassword' : self._fixedPassword, 'fixedDomain' : self._fixedDomain,
'useEmptyCreds' : gui.boolToStr(self._useEmptyCreds), 'wallpaper': self._wallPaper, 'withoutDomain': self._withoutDomain }
def isAvailableFor(self, ip): def isAvailableFor(self, ip):
''' '''
@ -144,7 +80,7 @@ class RDPTransport(Transport):
logger.debug('Checking availability for {0}'.format(ip)) logger.debug('Checking availability for {0}'.format(ip))
ready = self.cache().get(ip) ready = self.cache().get(ip)
if ready is None: if ready is None:
# Check again for readyness # Check again for ready
if connection.testServer(ip, '3389') == True: if connection.testServer(ip, '3389') == True:
self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT) self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT)
return True return True
@ -153,37 +89,10 @@ class RDPTransport(Transport):
return ready == 'Y' return ready == 'Y'
def getConnectionInfo(self, service, user, password): def getConnectionInfo(self, service, user, password):
from uds.core.transports import protocols
username = user.getUsernameForAuth() username = user.getUsernameForAuth()
proc = username.split('@') if self.fixedName.value is not '':
if len(proc) > 1: username = self.fixedName.value
domain = proc[1]
else:
domain = ''
username = proc[0]
if self._fixedName is not '':
username = self._fixedName
if self._fixedPassword is not '':
password = self._fixedPassword
if self._fixedDomain is not '':
domain = self._fixedDomain;
if self._useEmptyCreds is True:
username, password, domain = '', '', ''
username, password = service.processUserPassword(username, password)
return {'protocol': protocols.RDP, 'username': username, 'password': password, 'domain': domain}
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password):
# We use helper to keep this clean
username = user.getUsernameForAuth()
prefs = user.prefs('rdp')
if self._fixedName is not '':
username = self._fixedName
proc = username.split('@') proc = username.split('@')
if len(proc) > 1: if len(proc) > 1:
@ -192,34 +101,51 @@ class RDPTransport(Transport):
domain = '' domain = ''
username = proc[0] username = proc[0]
if self._fixedPassword is not '': if self.fixedPassword.value is not '':
password = self._fixedPassword password = self.fixedPassword.value
if self._fixedDomain is not '': if self.fixedDomain.value is not '':
domain = self._fixedDomain; domain = self.fixedDomain.value
if self._useEmptyCreds is True: if self.useEmptyCreds.isTrue():
username, password, domain = '', '', '' username, password, domain = '', '', ''
if self._withoutDomain is True: if self.withoutDomain.isTrue():
domain = '' domain = ''
if '.' in domain: # Dotter domain form if '.' in domain: # Dotter domain form
username = username + '@' + domain username = username + '@' + domain
domain = '' domain = ''
# Fix username/password acording to os manager
username, password = service.processUserPassword(username, password)
return {'protocol': self.protocol, 'username': username, 'password': password, 'domain': domain}
def renderForHtml(self, userService, transport, ip, os, user, password):
# We use helper to keep this clean
prefs = user.prefs('rdp')
ci = self.getConnectionInfo(userService, user, password)
username, password, domain = ci['username'], ci['password'], ci['domain']
width, height = CommonPrefs.getWidthHeight(prefs) width, height = CommonPrefs.getWidthHeight(prefs)
depth = CommonPrefs.getDepth(prefs) depth = CommonPrefs.getDepth(prefs)
# Extra data # Extra data
extra = { 'width': width, 'height' : height, 'depth' : depth, extra = {
'printers' : self._allowPrinters, 'smartcards' : self._allowSmartcards, 'width': width,
'drives' : self._allowDrives, 'serials' : self._allowSerials, 'compression':True, 'height': height,
'wallpaper': self._wallPaper } 'depth': depth,
'printers': self.allowPrinters.isTrue(),
'smartcards': self.allowSmartcards.isTrue(),
'drives': self.allowDrives.isTrue(),
'serials': self.allowSerials.isTrue(),
'compression': True,
'wallpaper': self.wallpaper.isTrue()
}
# Fix username/password acording to os manager return generateHtmlForRdp(self, userService.uuid, transport.uuid, os, ip, '3389', username, password, domain, extra)
username, password = userService.processUserPassword(username, password)
return generateHtmlForRdp(self, idUserService, idTransport, os, ip, '3389', username, password, domain, extra)
def getHtmlComponent(self, id, os, componentId): def getHtmlComponent(self, id, os, componentId):
logger.debug('Component: ID={}'.format(id))
# We use helper to keep this clean # We use helper to keep this clean
return getHtmlComponent(self.__module__, componentId) return getHtmlComponent(self.__module__, componentId)

View File

@ -76,86 +76,10 @@ class TSRDPTransport(Transport):
allowSerials = gui.CheckBoxField(label=_('Allow Serials'), order=11, tooltip=_('If checked, this transport will allow the use of user serial ports')) allowSerials = gui.CheckBoxField(label=_('Allow Serials'), order=11, tooltip=_('If checked, this transport will allow the use of user serial ports'))
wallpaper = gui.CheckBoxField(label=_('Show wallpaper'), order=12, tooltip=_('If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)')) wallpaper = gui.CheckBoxField(label=_('Show wallpaper'), order=12, tooltip=_('If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)'))
def __init__(self, environment, values=None): def initialize(self, values):
super(TSRDPTransport, self).__init__(environment, values)
if values is not None: if values is not None:
if values['tunnelServer'].count(':') != 1: if values['tunnelServer'].count(':') != 1:
raise Transport.ValidationException(_('Must use HOST:PORT in Tunnel Server Field')) raise Transport.ValidationException(_('Must use HOST:PORT in Tunnel Server Field'))
self._tunnelServer = values['tunnelServer']
self._tunnelCheckServer = values['tunnelCheckServer']
self._useEmptyCreds = gui.strToBool(values['useEmptyCreds'])
self._fixedName = values['fixedName']
self._fixedPassword = values['fixedPassword']
self._fixedDomain = values['fixedDomain']
self._allowSmartcards = gui.strToBool(values['allowSmartcards'])
self._allowPrinters = gui.strToBool(values['allowPrinters'])
self._allowDrives = gui.strToBool(values['allowDrives'])
self._allowSerials = gui.strToBool(values['allowSerials'])
self._wallPaper = gui.strToBool(values['wallpaper'])
self._withoutDomain = gui.strToBool(values['withoutDomain'])
else:
self._tunnelServer = ''
self._tunnelCheckServer = ''
self._useEmptyCreds = False
self._fixedName = ''
self._fixedPassword = ''
self._fixedDomain = ''
self._allowSmartcards = False
self._allowPrinters = False
self._allowDrives = False
self._allowSerials = False
self._wallPaper = False
self._withoutDomain = False
def marshal(self):
'''
Serializes the transport data so we can store it in database
'''
return str.join('\t', [ 'v3', gui.boolToStr(self._useEmptyCreds), gui.boolToStr(self._allowSmartcards), gui.boolToStr(self._allowPrinters),
gui.boolToStr(self._allowDrives), gui.boolToStr(self._allowSerials), gui.boolToStr(self._wallPaper),
self._fixedName, self._fixedPassword, self._fixedDomain, self._tunnelServer, self._tunnelCheckServer,
gui.boolToStr(self._withoutDomain) ])
def unmarshal(self, str_):
data = str_.split('\t')
if data[0] in ('v1', 'v2', 'v3'):
self._useEmptyCreds = gui.strToBool(data[1])
self._allowSmartcards = gui.strToBool(data[2])
self._allowPrinters = gui.strToBool(data[3])
self._allowDrives = gui.strToBool(data[4])
self._allowSerials = gui.strToBool(data[5])
if data[0] == 'v1':
self._wallPaper = False
i = 0
if data[0] in ('v2', 'v3'):
self._wallPaper = gui.strToBool(data[6])
i = 1
self._fixedName = data[6 + i]
self._fixedPassword = data[7 + i]
self._fixedDomain = data[8 + i]
self._tunnelServer = data[9 + i]
self._tunnelCheckServer = data[10 + i]
if data[0] == 'v3':
self._withoutDomain = gui.strToBool(data[11 + i])
def valuesDict(self):
return {
'allowSmartcards': gui.boolToStr(self._allowSmartcards),
'allowPrinters': gui.boolToStr(self._allowPrinters),
'allowDrives': gui.boolToStr(self._allowDrives),
'allowSerials': gui.boolToStr(self._allowSerials),
'fixedName': self._fixedName,
'fixedPassword': self._fixedPassword,
'fixedDomain': self._fixedDomain,
'useEmptyCreds': gui.boolToStr(self._useEmptyCreds),
'tunnelServer': self._tunnelServer,
'tunnelCheckServer': self._tunnelCheckServer,
'wallpaper': self._wallPaper,
'withoutDomain': gui.boolToStr(self._withoutDomain)
}
def isAvailableFor(self, ip): def isAvailableFor(self, ip):
''' '''
@ -173,13 +97,13 @@ class TSRDPTransport(Transport):
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT) self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y' return ready == 'Y'
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password): def renderForHtml(self, userService, transport, ip, os, user, password):
# We use helper to keep this clean # We use helper to keep this clean
username = user.getUsernameForAuth() username = user.getUsernameForAuth()
prefs = user.prefs('rdp') prefs = user.prefs('rdp')
if self._fixedName is not '': if self.fixedName.value is not '':
username = self._fixedName username = self.fixedName.value
proc = username.split('@') proc = username.split('@')
if len(proc) > 1: if len(proc) > 1:
@ -187,29 +111,29 @@ class TSRDPTransport(Transport):
else: else:
domain = '' domain = ''
username = proc[0] username = proc[0]
if self._fixedPassword is not '': if self.fixedPassword.value is not '':
password = self._fixedPassword password = self.fixedPassword.value
if self._fixedDomain is not '': if self.fixedDomain.value is not '':
domain = self._fixedDomain; domain = self.fixedDomain.value
if self._useEmptyCreds is True: if self.useEmptyCreds.isTrue():
username, password, domain = '', '', '' username, password, domain = '', '', ''
if '.' in domain: # Dotter domain form if '.' in domain: # Dotter domain form
username = username + '@' + domain username = username + '@' + domain
domain = '' domain = ''
if self._withoutDomain is True: if self.withoutDomain.isTrue():
domain = '' domain = ''
width, height = CommonPrefs.getWidthHeight(prefs) width, height = CommonPrefs.getWidthHeight(prefs)
depth = CommonPrefs.getDepth(prefs) depth = CommonPrefs.getDepth(prefs)
cache = Cache('pam') cache = Cache('pam')
tunuser = ''.join(random.choice(string.letters + string.digits) for i in range(12)) + ("%f" % time.time()).split('.')[1] tunuser = ''.join(random.choice(string.letters + string.digits) for _i in range(12)) + ("%f" % time.time()).split('.')[1]
tunpass = ''.join(random.choice(string.letters + string.digits) for i in range(12)) tunpass = ''.join(random.choice(string.letters + string.digits) for _i in range(12))
cache.put(tunuser, tunpass, 60 * 10) # Credential valid for ten minutes, and for 1 use only cache.put(tunuser, tunpass, 60 * 10) # Credential valid for ten minutes, and for 1 use only
sshHost, sshPort = self._tunnelServer.split(':') sshHost, sshPort = self.tunnelServer.value.split(':')
logger.debug('Username generated: {0}, password: {1}'.format(tunuser, tunpass)) logger.debug('Username generated: {0}, password: {1}'.format(tunuser, tunpass))
tun = "{0} {1} {2} {3} {4} {5} {6}".format(tunuser, tunpass, sshHost, sshPort, ip, '3389', '9') tun = "{0} {1} {2} {3} {4} {5} {6}".format(tunuser, tunpass, sshHost, sshPort, ip, '3389', '9')
@ -218,21 +142,21 @@ class TSRDPTransport(Transport):
# Extra data # Extra data
extra = { extra = {
'width': width, 'width': width,
'height' : height, 'height': height,
'depth': depth, 'depth': depth,
'printers': self._allowPrinters, 'printers': self.allowPrinters.isTrue(),
'smartcards': self._allowSmartcards, 'smartcards': self.allowSmartcards.isTrue(),
'drives': self._allowDrives, 'drives': self.allowDrives.isTrue(),
'serials': self._allowSerials, 'serials': self.allowSerials.isTrue(),
'tun': tun, 'tun': tun,
'compression': True, 'compression': True,
'wallpaper': self._wallPaper 'wallpaper': self.wallpaper.isTrue()
} }
# Fix username/password acording to os manager # Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password) username, password = userService.processUserPassword(username, password)
return generateHtmlForRdp(self, idUserService, idTransport, os, ip, '-1', username, password, domain, extra) return generateHtmlForRdp(self, userService.uuid, transport.uuid, os, ip, '-1', username, password, domain, extra)
def getHtmlComponent(self, id, os, componentId): def getHtmlComponent(self, id, os, componentId):
# We use helper to keep this clean # We use helper to keep this clean

View File

@ -34,7 +34,9 @@
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from uds.core.util import OsDetector from uds.core.util import OsDetector
import logging, os, sys import logging
import os
import sys
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -37,11 +37,15 @@ from django.utils.translation import ugettext_noop as _
from uds.core.managers.UserPrefsManager import CommonPrefs from uds.core.managers.UserPrefsManager import CommonPrefs
from uds.core.ui.UserInterface import gui from uds.core.ui.UserInterface import gui
from uds.core.transports.BaseTransport import Transport from uds.core.transports.BaseTransport import Transport
from uds.core.transports import protocols
from uds.core.util.Cache import Cache from uds.core.util.Cache import Cache
from uds.core.util import connection from uds.core.util import connection
from web import generateHtmlForNX, getHtmlComponent from web import generateHtmlForNX, getHtmlComponent
import logging, random, string, time import logging
import random
import string
import time
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -59,6 +63,7 @@ class TSNXTransport(Transport):
iconFile = 'nx.png' iconFile = 'nx.png'
needsJava = True # If this transport needs java for rendering needsJava = True # If this transport needs java for rendering
supportedOss = ['Windows', 'Macintosh', 'Linux'] supportedOss = ['Windows', 'Macintosh', 'Linux']
protocol = protocols.NX
tunnelServer = gui.TextField(label=_('Tunnel server'), order=1, tooltip=_('IP or Hostname of tunnel server send to client device ("public" ip) and port. (use HOST:PORT format)')) tunnelServer = gui.TextField(label=_('Tunnel server'), order=1, tooltip=_('IP or Hostname of tunnel server send to client device ("public" ip) and port. (use HOST:PORT format)'))
tunnelCheckServer = gui.TextField(label=_('Tunnel host check'), order=2, tooltip=_('If not empty, this server will be used to check if service is running before assigning it to user. (use HOST:PORT format)')) tunnelCheckServer = gui.TextField(label=_('Tunnel host check'), order=2, tooltip=_('If not empty, this server will be used to check if service is running before assigning it to user. (use HOST:PORT format)'))
@ -67,35 +72,38 @@ class TSNXTransport(Transport):
fixedName = gui.TextField(label=_('Username'), order=4, tooltip=_('If not empty, this username will be always used as credential')) fixedName = gui.TextField(label=_('Username'), order=4, tooltip=_('If not empty, this username will be always used as credential'))
fixedPassword = gui.PasswordField(label=_('Password'), order=5, tooltip=_('If not empty, this password will be always used as credential')) fixedPassword = gui.PasswordField(label=_('Password'), order=5, tooltip=_('If not empty, this password will be always used as credential'))
listenPort = gui.NumericField(label=_('Listen port'), length=5, order=6, tooltip=_('Listening port of NX (ssh) at client machine'), defvalue='22') listenPort = gui.NumericField(label=_('Listen port'), length=5, order=6, tooltip=_('Listening port of NX (ssh) at client machine'), defvalue='22')
connection = gui.ChoiceField(label=_('Connection'), order=7, tooltip=_('Connection speed for this transport (quality)'), values=[ connection = gui.ChoiceField(label=_('Connection'), order=7, tooltip=_('Connection speed for this transport (quality)'),
{'id' : 'modem', 'text' : 'modem'}, values=[
{'id' : 'isdn', 'text' : 'isdn'}, {'id': 'modem', 'text': 'modem'},
{'id' : 'adsl', 'text' : 'adsl'}, {'id': 'isdn', 'text': 'isdn'},
{'id' : 'wan', 'text' : 'wan'}, {'id': 'adsl', 'text': 'adsl'},
{'id' : 'lan', 'text' : 'lan'}, {'id': 'wan', 'text': 'wan'},
]) {'id': 'lan', 'text': 'lan'},
session = gui.ChoiceField(label=_('Session'), order=8, tooltip=_('Desktop session'), values=[ ])
{'id' : 'gnome', 'text' : 'gnome'}, session = gui.ChoiceField(label=_('Session'), order=8, tooltip=_('Desktop session'),
{'id' : 'kde', 'text' : 'kde'}, values=[
{'id' : 'cde', 'text' : 'cde'}, {'id': 'gnome', 'text': 'gnome'},
]) {'id': 'kde', 'text': 'kde'},
cacheDisk = gui.ChoiceField(label=_('Disk Cache'), order=9, tooltip=_('Cache size en Mb stored at disk'), values=[ {'id': 'cde', 'text': 'cde'},
{'id' : '0', 'text' : '0 Mb'}, ])
{'id' : '32', 'text' : '32 Mb'}, cacheDisk = gui.ChoiceField(label=_('Disk Cache'), order=9, tooltip=_('Cache size en Mb stored at disk'),
{'id' : '64', 'text' : '64 Mb'}, values=[
{'id' : '128', 'text' : '128 Mb'}, {'id': '0', 'text': '0 Mb'},
{'id' : '256', 'text' : '256 Mb'}, {'id': '32', 'text': '32 Mb'},
{'id' : '512', 'text' : '512 Mb'}, {'id': '64', 'text': '64 Mb'},
]) {'id': '128', 'text': '128 Mb'},
cacheMem = gui.ChoiceField(label=_('Memory Cache'), order=10, tooltip=_('Cache size en Mb keept at memory'), values=[ {'id': '256', 'text': '256 Mb'},
{'id' : '4', 'text' : '4 Mb'}, {'id': '512', 'text': '512 Mb'},
{'id' : '8', 'text' : '8 Mb'}, ])
{'id' : '16', 'text' : '16 Mb'}, cacheMem = gui.ChoiceField(label=_('Memory Cache'), order=10, tooltip=_('Cache size en Mb keept at memory'),
{'id' : '32', 'text' : '32 Mb'}, values=[
{'id' : '64', 'text' : '64 Mb'}, {'id': '4', 'text': '4 Mb'},
{'id' : '128', 'text' : '128 Mb'}, {'id': '8', 'text': '8 Mb'},
]) {'id': '16', 'text': '16 Mb'},
{'id': '32', 'text': '32 Mb'},
{'id': '64', 'text': '64 Mb'},
{'id': '128', 'text': '128 Mb'},
])
def __init__(self, environment, values=None): def __init__(self, environment, values=None):
super(TSNXTransport, self).__init__(environment, values) super(TSNXTransport, self).__init__(environment, values)
@ -137,13 +145,19 @@ class TSNXTransport(Transport):
self._useEmptyCreds = gui.strToBool(data[1]) self._useEmptyCreds = gui.strToBool(data[1])
self._fixedName, self._fixedPassword, self._listenPort, self._connection, self._session, self._cacheDisk, self._cacheMem, self._tunnelServer, self._tunnelCheckServer = data[2:] self._fixedName, self._fixedPassword, self._listenPort, self._connection, self._session, self._cacheDisk, self._cacheMem, self._tunnelServer, self._tunnelCheckServer = data[2:]
def valuesDict(self): def valuesDict(self):
return { 'useEmptyCreds' : gui.boolToStr(self._useEmptyCreds), 'fixedName' : self._fixedName, return {
'fixedPassword' : self._fixedPassword, 'listenPort': self._listenPort, 'useEmptyCreds': gui.boolToStr(self._useEmptyCreds),
'connection' : self._connection, 'session' : self._session, 'cacheDisk' : self._cacheDisk, 'fixedName': self._fixedName,
'cacheMem' : self._cacheMem, 'tunnelServer' : self._tunnelServer, 'fixedPassword': self._fixedPassword,
'tunnelCheckServer' : self._tunnelCheckServer } 'listenPort': self._listenPort,
'connection': self._connection,
'session': self._session,
'cacheDisk': self._cacheDisk,
'cacheMem': self._cacheMem,
'tunnelServer': self._tunnelServer,
'tunnelCheckServer': self._tunnelCheckServer
}
def isAvailableFor(self, ip): def isAvailableFor(self, ip):
''' '''
@ -154,14 +168,14 @@ class TSNXTransport(Transport):
ready = self.cache().get(ip) ready = self.cache().get(ip)
if ready is None: if ready is None:
# Check again for readyness # Check again for readyness
if connection.testServer(ip, self._listenPort) == True: if connection.testServer(ip, self._listenPort) is True:
self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT) self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT)
return True return True
else: else:
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT) self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y' return ready == 'Y'
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password): def renderForHtml(self, userService, transport, ip, os, user, password):
prefs = user.prefs('nx') prefs = user.prefs('nx')
@ -178,9 +192,8 @@ class TSNXTransport(Transport):
width, height = CommonPrefs.getWidthHeight(prefs) width, height = CommonPrefs.getWidthHeight(prefs)
cache = Cache('pam') cache = Cache('pam')
tunuser = ''.join(random.choice(string.letters + string.digits) for _i in range(12)) + ("%f" % time.time()).split('.')[1]
tunuser = ''.join(random.choice(string.letters + string.digits) for i in range(12)) + ("%f" % time.time()).split('.')[1] tunpass = ''.join(random.choice(string.letters + string.digits) for _i in range(12))
tunpass = ''.join(random.choice(string.letters + string.digits) for i in range(12))
cache.put(tunuser, tunpass, 60 * 10) # Credential valid for ten minutes, and for 1 use only cache.put(tunuser, tunpass, 60 * 10) # Credential valid for ten minutes, and for 1 use only
sshHost, sshPort = self._tunnelServer.split(':') sshHost, sshPort = self._tunnelServer.split(':')
@ -189,15 +202,20 @@ class TSNXTransport(Transport):
tun = "{0} {1} {2} {3} {4} {5} {6}".format(tunuser, tunpass, sshHost, sshPort, ip, self._listenPort, '9') tun = "{0} {1} {2} {3} {4} {5} {6}".format(tunuser, tunpass, sshHost, sshPort, ip, self._listenPort, '9')
# Extra data # Extra data
extra = { 'width': width, 'height' : height, extra = {
'connection' : self._connection, 'width': width,
'session' : self._session, 'cacheDisk': self._cacheDisk, 'height': height,
'cacheMem' : self._cacheMem, 'tun' : tun } 'connection': self._connection,
'session': self._session,
'cacheDisk': self._cacheDisk,
'cacheMem': self._cacheMem,
'tun': tun
}
# Fix username/password acording to os manager # Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password) username, password = userService.processUserPassword(username, password)
return generateHtmlForNX(self, idUserService, idTransport, os, username, password, extra) return generateHtmlForNX(self, userService.uuid, transport.uuid, os, username, password, extra)
def getHtmlComponent(self, theId, os, componentId): def getHtmlComponent(self, theId, os, componentId):
# We use helper to keep this clean # We use helper to keep this clean

View File

@ -55,11 +55,16 @@ def __init__():
# Dinamycally import children of this package. The __init__.py files must import classes # Dinamycally import children of this package. The __init__.py files must import classes
pkgpath = os.path.dirname(sys.modules[__name__].__file__) pkgpath = os.path.dirname(sys.modules[__name__].__file__)
for _, name, _ in pkgutil.iter_modules([pkgpath]): for _, name, _ in pkgutil.iter_modules([pkgpath]):
__import__(name, globals(), locals(), [], -1) __import__(name, globals(), locals(), [])
p = transports.Transport p = transports.Transport
# This is marked as error in IDE, but it's not (__subclasses__) # This is marked as error in IDE, but it's not (__subclasses__)
for cls in p.__subclasses__(): for cls in p.__subclasses__():
transports.factory().insert(cls) clsSubCls = cls.__subclasses__()
if len(clsSubCls) == 0:
transports.factory().insert(cls)
else:
for l2 in clsSubCls:
transports.factory().insert(l2)
__init__() __init__()

View File

@ -277,7 +277,7 @@ def service(request, idService, idTransport):
itrans = trans.getInstance() itrans = trans.getInstance()
if itrans.isAvailableFor(ip): if itrans.isAvailableFor(ip):
log.doLog(ads, log.INFO, "User service ready, rendering transport", log.WEB) log.doLog(ads, log.INFO, "User service ready, rendering transport", log.WEB)
transport = itrans.renderForHtml(ads, ads.uuid, trans.uuid, ip, request.session['OS'], request.user, webPassword(request)) transport = itrans.renderForHtml(ads, trans, ip, request.session['OS'], request.user, webPassword(request))
return render_to_response(theme.template('show_transport.html'), {'transport': transport, 'nolang': True}, context_instance=RequestContext(request)) return render_to_response(theme.template('show_transport.html'), {'transport': transport, 'nolang': True}, context_instance=RequestContext(request))
else: else:
log.doLog(ads, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT) log.doLog(ads, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT)