* Added support to existing transports to notify ip/hostname of client connected to service

* Added support to administration interface to show this data
This commit is contained in:
Adolfo Gómez 2012-12-14 11:43:20 +00:00
parent 6667544c39
commit ff609a39e8
16 changed files with 67 additions and 29 deletions

View File

@ -160,6 +160,7 @@ encoding//src/uds/transports/RDP/web.py=utf-8
encoding//src/uds/transports/RGS-enterprise/RGSTransport.py=utf-8
encoding//src/uds/transports/RGS-enterprise/TRGSTransport.py=utf-8
encoding//src/uds/transports/RGS-enterprise/__init__.py=utf-8
encoding//src/uds/transports/RGS-enterprise/web.py=utf-8
encoding//src/uds/transports/RGS/RGSTransport.py=utf-8
encoding//src/uds/transports/RGS/TRGSTransport.py=utf-8
encoding//src/uds/transports/RGS/__init__.py=utf-8

View File

@ -134,11 +134,12 @@ class Transport(Module):
'''
return {'protocol': protocols.NONE, 'username': '', 'password': '', 'domain': ''}
def renderForHtml(self, userService, id, ip, os, user, password):
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, 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 id: id of the transport
@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 idTransport: id of the transport (scrambled)
@param ip: ip of the destination
@param user: user (dbUser) logged in
@param pass: password used in authentication

View File

@ -30,7 +30,6 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from uds.models import UserService, State
import logging
logger = logging.getLogger(__name__)
@ -55,11 +54,11 @@ __nameLevels = {
# Reverse dict of names
__valueLevels = dict((v,k) for k, v in __nameLevels.iteritems())
def logLevelFromStr(str):
def logLevelFromStr(str_):
'''
Gets the numeric log level from an string.
'''
return __nameLevels.get(str, OTHER)
return __nameLevels.get(str_.upper(), OTHER)
def logStrFromLevel(level):
return __valueLevels.get(level, 'OTHER')

View File

@ -148,7 +148,7 @@ class NXTransport(Transport):
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y'
def renderForHtml(self, userService, theId, ip, os, user, password):
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password):
prefs = user.prefs('nx')
@ -175,7 +175,7 @@ class NXTransport(Transport):
# Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password)
return generateHtmlForNX(self, theId, ip, username, password, extra)
return generateHtmlForNX(self, idUserService, idTransport, ip, username, password, extra)
def getHtmlComponent(self, theId, os, componentId):
# We use helper to keep this clean

View File

@ -53,8 +53,8 @@ def simpleScrambler(data):
def generateHtmlForNX(transport, id, ip, user, password, extra):
applet = reverse('uds.web.views.transcomp', kwargs = { 'idTransport' : id, 'componentId' : '1' })
def generateHtmlForNX(transport, idUserService, idTransport, ip, user, password, extra):
applet = reverse('uds.web.views.transcomp', kwargs = { 'idTransport' : idTransport, 'componentId' : '1' })
# Gets the codebase, simply remove last char from applet
codebase = applet[:-1]
# We generate the "data" parameter
@ -68,9 +68,10 @@ def generateHtmlForNX(transport, id, ip, user, password, extra):
'cacheDisk:' + extra['cacheDisk'],
'cacheMem:' + extra['cacheMem'],
'width:' + str(extra['width']),
'height:' + str(extra['height'])
'height:' + str(extra['height']),
'is:' + idUserService
]))
res = '<div id="applet"><applet code="NxTransportApplet.class" codebase="%s" archive="%s" width="140" height="22"><param name="data" value="%s"/></applet></div>' % (codebase, '1', data )
res = '<div idTransport="applet"><applet code="NxTransportApplet.class" codebase="%s" archive="%s" width="140" height="22"><param name="data" value="%s"/></applet></div>' % (codebase, '1', data )
res += '<div><p>' + _('In order to use this transport, you need to install first Nomachine Nx Client version 3.5.x') + '</p>'
res += '<p>' + _('you can obtain it for your platform from') + '<a href="http://www.nomachine.com/download.php">' + _('nochamine web site') + '</a></p></div>'
return res

View File

@ -130,7 +130,7 @@ class RDPTransport(Transport):
return {'protocol': protocols.RDP, 'username': username, 'password': password, 'domain': domain}
def renderForHtml(self, userService, id, ip, os, user, password):
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password):
# We use helper to keep this clean
username = user.getUsernameForAuth()
prefs = user.prefs('rdp')
@ -161,7 +161,7 @@ class RDPTransport(Transport):
# Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password)
return generateHtmlForRdp(self, id, os, ip, '3389', username, password, domain, extra)
return generateHtmlForRdp(self, idUserService, idTransport, os, ip, '3389', username, password, domain, extra)
def getHtmlComponent(self, id, os, componentId):
# We use helper to keep this clean

View File

@ -116,7 +116,7 @@ class TSRDPTransport(Transport):
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y'
def renderForHtml(self, userService, id, ip, os, user, password):
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password):
# We use helper to keep this clean
username = user.getUsernameForAuth()
prefs = user.prefs('rdp')
@ -159,7 +159,7 @@ class TSRDPTransport(Transport):
# Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password)
return generateHtmlForRdp(self, id, os, ip, '-1', username, password, domain, extra)
return generateHtmlForRdp(self, idUserService, idTransport, os, ip, '-1', username, password, domain, extra)
def getHtmlComponent(self, id, os, componentId):
# We use helper to keep this clean

View File

@ -52,9 +52,9 @@ def scramble(data):
def generateHtmlForRdp(transport, id, os, ip, port, user, password, domain, extra):
def generateHtmlForRdp(transport, idUserService, idTransport, os, ip, port, user, password, domain, extra):
isMac = os['OS'] == OsDetector.Macintosh
applet = reverse('uds.web.views.transcomp', kwargs = { 'idTransport' : id, 'componentId' : '1' })
applet = reverse('uds.web.views.transcomp', kwargs = { 'idTransport' : idTransport, 'componentId' : '1' })
logger.debug('Applet: {0}'.format(applet))
# Gets the codebase, simply remove last char from applet
codebase = applet[:-1]
@ -72,13 +72,14 @@ def generateHtmlForRdp(transport, id, os, ip, port, user, password, domain, extr
'w:' + str(extra['width']),
'h:' + str(extra['height']),
'c:' + str(extra['depth']),
'cr:' + (extra['compression'] and '1' or '0')
'cr:' + (extra['compression'] and '1' or '0'),
'is:' + idUserService
]
if extra.has_key('tun'):
data.append('tun:' + extra['tun'])
data = scramble('\t'.join(data))
res = '<div id="applet"><applet code="RdpApplet.class" codebase="%s" archive="%s" width="200" height="22"><param name="data" value="%s"/></applet></div>' % (codebase, '1', data )
res = '<div idTransport="applet"><applet code="RdpApplet.class" codebase="%s" archive="%s" width="200" height="22"><param name="data" value="%s"/></applet></div>' % (codebase, '1', data )
if isMac is True:
res += ('<div><p>' + _('In order to use this service, you should first install CoRD.') + '</p>'
'<p>' + _('You can obtain it from') + ' <a href="http://cord.sourceforge.net/">' + _('CoRD Website') + '</a></p>'

View File

@ -158,7 +158,7 @@ class TSNXTransport(Transport):
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y'
def renderForHtml(self, userService, theId, ip, os, user, password):
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password):
prefs = user.prefs('nx')
@ -194,7 +194,7 @@ class TSNXTransport(Transport):
# Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password)
return generateHtmlForNX(self, theId, username, password, extra)
return generateHtmlForNX(self, idUserService, idTransport, username, password, extra)
def getHtmlComponent(self, theId, os, componentId):
# We use helper to keep this clean

View File

@ -52,8 +52,8 @@ def simpleScrambler(data):
def generateHtmlForNX(transport, id, user, password, extra):
applet = reverse('uds.web.views.transcomp', kwargs = { 'idTransport' : id, 'componentId' : '1' })
def generateHtmlForNX(transport, idUserService, idTransport, user, password, extra):
applet = reverse('uds.web.views.transcomp', kwargs = { 'idTransport' : idTransport, 'componentId' : '1' })
# Gets the codebase, simply remove last char from applet
codebase = applet[:-1]
# We generate the "data" parameter
@ -67,10 +67,11 @@ def generateHtmlForNX(transport, id, user, password, extra):
'cacheMem:' + extra['cacheMem'],
'width:' + str(extra['width']),
'height:' + str(extra['height']),
'tun:' + extra['tun']
'tun:' + extra['tun'],
'is:' + idUserService
]
data = simpleScrambler( '\t'.join(data))
res = '<div id="applet"><applet code="NxTunTransportApplet.class" codebase="%s" archive="%s" width="165" height="22"><param name="data" value="%s"/></applet></div>' % (codebase, '1', data )
res = '<div idTransport="applet"><applet code="NxTunTransportApplet.class" codebase="%s" archive="%s" width="165" height="22"><param name="data" value="%s"/></applet></div>' % (codebase, '1', data )
res += '<div><p>In order to use this transport, you need to install first nomachine nx client version 3.5.x</p>'
res += '<p>you can obtain it for your platform from <a href="http://www.nomachine.com/download.php">nochamine web site </a></p></div>'
return res

View File

@ -45,6 +45,8 @@ urlpatterns = patterns('uds',
(r'^error/(?P<idError>.+)$', 'web.views.error'),
# Transport component url
(r'^transcomp/(?P<idTransport>.+)/(?P<componentId>.+)$', 'web.views.transcomp'),
# Service notification url
(r'^sernotify/(?P<idUserService>.+)/(?P<notification>.+)$', 'web.views.sernotify'),
# Authenticators custom html
(r'^customAuth/(?P<idAuth>.*)$', 'web.views.customAuth'),
# Preferences

View File

@ -222,7 +222,7 @@ def service(request, idService, idTransport):
if ip is not None:
itrans = trans.getInstance()
if itrans.isAvailableFor(ip):
transport = itrans.renderForHtml(ads, scrambleId(request, trans.id), ip, request.session['OS'], request.user, webPassword(request))
transport = itrans.renderForHtml(ads, scrambleId(request, ads.id), scrambleId(request, trans.id), ip, request.session['OS'], request.user, webPassword(request))
return render_to_response('uds/show_transport.html', {'transport' : transport, 'nolang' : True }, context_instance=RequestContext(request))
else:
logger.debug('Transport is not ready for user service {0}'.format(ads))
@ -247,6 +247,32 @@ def transcomp(request, idTransport, componentId):
return response
except Exception, e:
return errors.exceptionView(request, e)
@webLoginRequired
@transformId
def sernotify(request, idUserService, notification):
try:
if notification == 'hostname':
hostname = request.GET.get('hostname', None)
ip = request.GET.get('ip', None)
if ip is not None and hostname is not None:
us = UserService.objects.get(pk=idUserService)
us.setConnectionSource(ip, hostname)
else:
return HttpResponse('Invalid request!', 'text/plain')
elif notification == "log":
message = request.GET.get('message', None)
level = request.GET.get('level', None)
if message is not None and level is not None:
from uds.core.util import log
us = UserService.objects.get(pk=idUserService)
us.doLog(level, message, log.TRANSPORT)
else:
return HttpResponse('Invalid request!', 'text/plain')
except Exception as e:
logger.exception("Exception")
return errors.errorView(request, e)
return HttpResponse('ok', mimetype='text/plain')
@transformId

View File

@ -45,7 +45,7 @@ logger = logging.getLogger(__name__)
ADMIN_AUTH = '#'
CLIENT_VERSION_REQUIRED = '1.0.8'
CLIENT_VERSION_REQUIRED = '1.1.0'
class Credentials(object):
'''

View File

@ -41,8 +41,13 @@ import logging
logger = logging.getLogger(__name__)
def dictFromCachedDeployedService(cs):
if cs.publication is not None:
revision = str(cs.publication.revision)
else:
revision = ''
res = { 'idParent' : str(cs.deployed_service_id), 'id' : str(cs.id), 'uniqueId' : cs.unique_id, 'friendlyName' : cs.friendly_name, 'state' : cs.state, 'osState': cs.os_state, 'stateDate' : cs.state_date,
'creationDate' : cs.creation_date, 'cacheLevel' : str(cs.cache_level), 'revision' : str(cs.publication.revision) }
'creationDate' : cs.creation_date, 'cacheLevel' : str(cs.cache_level), 'revision' : revision }
return res
def dictFromAssignedDeployedService(ads):
@ -52,7 +57,8 @@ def dictFromAssignedDeployedService(ads):
revision = ''
res = { 'idParent' : str(ads.deployed_service_id), 'id' : str(ads.id), 'uniqueId' : ads.unique_id, 'friendlyName' : ads.friendly_name, 'state' : ads.state, 'osState': ads.os_state, 'stateDate' : ads.state_date,
'creationDate' : ads.creation_date, 'revision' : revision, 'user': ads.user.manager.name + "-" + ads.user.name, 'inUse': ads.in_use, 'inUseDate': ads.in_use_date }
'creationDate' : ads.creation_date, 'revision' : revision, 'user': ads.user.manager.name + "-" + ads.user.name, 'inUse': ads.in_use, 'inUseDate': ads.in_use_date,
'sourceHost' : ads.src_hostname, 'sourceIp': ads.src_ip }
return res
@needs_credentials