1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-01-22 22:03:54 +03:00

Refactoring Transports

This commit is contained in:
Adolfo Gómez García 2024-01-12 01:34:28 +01:00
parent e4d2d2a843
commit f1c1cbae06
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
9 changed files with 308 additions and 237 deletions

View File

@ -83,6 +83,7 @@ def tunnel_field() -> ui.gui.ChoiceField:
required=True, required=True,
choices=functools.partial(_server_group_values, [types.servers.ServerType.TUNNEL]), choices=functools.partial(_server_group_values, [types.servers.ServerType.TUNNEL]),
tab=types.ui.Tab.TUNNEL, tab=types.ui.Tab.TUNNEL,
stored_field_name='tunnel',
) )
@ -93,7 +94,7 @@ def get_tunnel_from_field(fld: ui.gui.ChoiceField) -> models.ServerGroup:
# Server group field # Server group field
def server_group_field( def server_group_field(
type: typing.Optional[list[types.servers.ServerType]] = None, valid_types: typing.Optional[list[types.servers.ServerType]] = None,
subtype: typing.Optional[str] = None, subtype: typing.Optional[str] = None,
tab: typing.Optional[types.ui.Tab] = None, tab: typing.Optional[types.ui.Tab] = None,
) -> ui.gui.ChoiceField: ) -> ui.gui.ChoiceField:
@ -106,14 +107,15 @@ def server_group_field(
Returns: Returns:
A ChoiceField with the server group selection A ChoiceField with the server group selection
""" """
type = type or [types.servers.ServerType.UNMANAGED] valid_types = valid_types or [types.servers.ServerType.UNMANAGED]
return ui.gui.ChoiceField( return ui.gui.ChoiceField(
label=_('Server group'), label=_('Server group'),
order=2, order=2,
tooltip=_('Server group to use'), tooltip=_('Server group to use'),
required=True, required=True,
choices=functools.partial(_server_group_values, type, subtype), # So it gets evaluated at runtime choices=functools.partial(_server_group_values, valid_types, subtype), # So it gets evaluated at runtime
tab=tab, tab=tab,
stored_field_name='serverGroup',
) )
@ -127,7 +129,7 @@ def get_server_group_from_field(fld: ui.gui.ChoiceField) -> models.ServerGroup:
# Ticket validity time field (for http related tunnels) # Ticket validity time field (for http related tunnels)
def tunnel_ricket_validity_field() -> ui.gui.NumericField: def tunnel_ticket_validity_field() -> ui.gui.NumericField:
return ui.gui.NumericField( return ui.gui.NumericField(
length=3, length=3,
label=_('Ticket Validity'), label=_('Ticket Validity'),
@ -139,11 +141,12 @@ def tunnel_ricket_validity_field() -> ui.gui.NumericField:
required=True, required=True,
min_value=60, min_value=60,
tab=types.ui.Tab.ADVANCED, tab=types.ui.Tab.ADVANCED,
stored_field_name='ticketValidity',
) )
# Tunnel wait time (for uds client related tunnels) # Tunnel wait time (for uds client related tunnels)
def tunnel_runnel_wait(order: int = 2) -> ui.gui.NumericField: def tunnel_wait_time(order: int = 2) -> ui.gui.NumericField:
return ui.gui.NumericField( return ui.gui.NumericField(
length=3, length=3,
label=_('Tunnel wait time'), label=_('Tunnel wait time'),
@ -154,6 +157,7 @@ def tunnel_runnel_wait(order: int = 2) -> ui.gui.NumericField:
tooltip=_('Maximum time, in seconds, to wait before disable new connections on client tunnel listener'), tooltip=_('Maximum time, in seconds, to wait before disable new connections on client tunnel listener'),
required=True, required=True,
tab=types.ui.Tab.TUNNEL, tab=types.ui.Tab.TUNNEL,
stored_field_name='tunnelWait',
) )

View File

@ -52,6 +52,7 @@ logger = logging.getLogger(__name__)
READY_CACHE_TIMEOUT = 30 READY_CACHE_TIMEOUT = 30
class HTML5RDPTransport(transports.Transport): class HTML5RDPTransport(transports.Transport):
""" """
Provides access via RDP to service. Provides access via RDP to service.
@ -70,46 +71,52 @@ class HTML5RDPTransport(transports.Transport):
tunnel = fields.tunnel_field() tunnel = fields.tunnel_field()
useGlyptodonTunnel = ui.gui.CheckBoxField( use_glyptodon = ui.gui.CheckBoxField(
label=_('Use Glyptodon Enterprise tunnel'), label=_('Use Glyptodon Enterprise tunnel'),
order=2, order=2,
tooltip=_( tooltip=_(
'If checked, UDS will use Glyptodon Enterprise Tunnel for HTML tunneling instead of UDS Tunnel' 'If checked, UDS will use Glyptodon Enterprise Tunnel for HTML tunneling instead of UDS Tunnel'
), ),
tab=types.ui.Tab.TUNNEL, tab=types.ui.Tab.TUNNEL,
stored_field_name='useGlyptodonTunnel',
) )
useEmptyCreds = ui.gui.CheckBoxField( force_empty_creds = ui.gui.CheckBoxField(
label=_('Empty creds'), label=_('Empty creds'),
order=3, order=3,
tooltip=_('If checked, the credentials used to connect will be emtpy'), tooltip=_('If checked, the credentials used to connect will be emtpy'),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='useEmptyCreds',
) )
fixedName = ui.gui.TextField( forced_username = ui.gui.TextField(
label=_('Username'), label=_('Username'),
order=4, order=4,
tooltip=_('If not empty, this username will be always used as credential'), tooltip=_('If not empty, this username will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedName',
) )
fixedPassword = ui.gui.PasswordField( forced_password = ui.gui.PasswordField(
label=_('Password'), label=_('Password'),
order=5, order=5,
tooltip=_('If not empty, this password will be always used as credential'), tooltip=_('If not empty, this password will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedPassword',
) )
withoutDomain = ui.gui.CheckBoxField( force_no_domain = ui.gui.CheckBoxField(
label=_('Without Domain'), label=_('Without Domain'),
order=6, order=6,
tooltip=_( tooltip=_(
'If checked, the domain part will always be emptied (to connecto to xrdp for example is needed)' 'If checked, the domain part will always be emptied (to connecto to xrdp for example is needed)'
), ),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='withoutDomain',
) )
fixedDomain = ui.gui.TextField( forced_domain = ui.gui.TextField(
label=_('Domain'), label=_('Domain'),
order=7, order=7,
tooltip=_('If not empty, this domain will be always used as credential (used as DOMAIN\\user)'), tooltip=_('If not empty, this domain will be always used as credential (used as DOMAIN\\user)'),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedDomain',
) )
wallpaper = ui.gui.CheckBoxField( wallpaper = ui.gui.CheckBoxField(
label=_('Show wallpaper'), label=_('Show wallpaper'),
@ -118,43 +125,49 @@ class HTML5RDPTransport(transports.Transport):
'If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)' 'If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)'
), ),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='wallpaper',
) )
desktopComp = ui.gui.CheckBoxField( allow_destop_composition = ui.gui.CheckBoxField(
label=_('Allow Desk.Comp.'), label=_('Allow Desk.Comp.'),
order=19, order=19,
tooltip=_('If checked, desktop composition will be allowed'), tooltip=_('If checked, desktop composition will be allowed'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='desktopComp',
) )
smooth = ui.gui.CheckBoxField( smooth = ui.gui.CheckBoxField(
label=_('Font Smoothing'), label=_('Font Smoothing'),
order=20, order=20,
tooltip=_('If checked, fonts smoothing will be allowed (windows clients only)'), tooltip=_('If checked, fonts smoothing will be allowed (windows clients only)'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='smooth',
) )
enableAudio = ui.gui.CheckBoxField( enable_audio = ui.gui.CheckBoxField(
label=_('Enable Audio'), label=_('Enable Audio'),
order=21, order=21,
tooltip=_('If checked, the audio will be redirected to remote session (if client browser supports it)'), tooltip=_('If checked, the audio will be redirected to remote session (if client browser supports it)'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
default=True, default=True,
stored_field_name='enableAudio',
) )
enableAudioInput = ui.gui.CheckBoxField( enable_microphone = ui.gui.CheckBoxField(
label=_('Enable Microphone'), label=_('Enable Microphone'),
order=22, order=22,
tooltip=_( tooltip=_(
'If checked, the microphone will be redirected to remote session (if client browser supports it)' 'If checked, the microphone will be redirected to remote session (if client browser supports it)'
), ),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='enableAudioInput',
) )
enablePrinting = ui.gui.CheckBoxField( enable_printing = ui.gui.CheckBoxField(
label=_('Enable Printing'), label=_('Enable Printing'),
order=23, order=23,
tooltip=_( tooltip=_(
'If checked, the printing will be redirected to remote session (if client browser supports it)' 'If checked, the printing will be redirected to remote session (if client browser supports it)'
), ),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='enablePrinting',
) )
enableFileSharing = ui.gui.ChoiceField( enable_file_sharing = ui.gui.ChoiceField(
label=_('File Sharing'), label=_('File Sharing'),
order=24, order=24,
tooltip=_('File upload/download redirection policy'), tooltip=_('File upload/download redirection policy'),
@ -166,8 +179,9 @@ class HTML5RDPTransport(transports.Transport):
{'id': 'true', 'text': _('Enable file sharing')}, {'id': 'true', 'text': _('Enable file sharing')},
], ],
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='enableFileSharing',
) )
enableClipboard = ui.gui.ChoiceField( enable_clipboard = ui.gui.ChoiceField(
label=_('Clipboard'), label=_('Clipboard'),
order=25, order=25,
tooltip=_('Clipboard redirection policy'), tooltip=_('Clipboard redirection policy'),
@ -179,9 +193,10 @@ class HTML5RDPTransport(transports.Transport):
{'id': 'enabled', 'text': _('Enable clipboard')}, {'id': 'enabled', 'text': _('Enable clipboard')},
], ],
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='enableClipboard',
) )
serverLayout = ui.gui.ChoiceField( server_layout = ui.gui.ChoiceField(
order=26, order=26,
label=_('Layout'), label=_('Layout'),
tooltip=_('Keyboard Layout of server'), tooltip=_('Keyboard Layout of server'),
@ -209,11 +224,12 @@ class HTML5RDPTransport(transports.Transport):
], ],
default='-', default='-',
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='serverLayout',
) )
ticketValidity = fields.tunnel_ricket_validity_field() ticket_validity = fields.tunnel_ticket_validity_field()
forceNewWindow = ui.gui.ChoiceField( force_new_window = ui.gui.ChoiceField(
order=91, order=91,
label=_('Force new HTML Window'), label=_('Force new HTML Window'),
tooltip=_('Select windows behavior for new connections on HTML5'), tooltip=_('Select windows behavior for new connections on HTML5'),
@ -231,7 +247,9 @@ class HTML5RDPTransport(transports.Transport):
], ],
default='true', default='true',
tab=types.ui.Tab.ADVANCED, tab=types.ui.Tab.ADVANCED,
stored_field_name='forceNewWindow',
) )
security = ui.gui.ChoiceField( security = ui.gui.ChoiceField(
order=92, order=92,
label=_('Security'), label=_('Security'),
@ -259,9 +277,10 @@ class HTML5RDPTransport(transports.Transport):
], ],
default='any', default='any',
tab=types.ui.Tab.ADVANCED, tab=types.ui.Tab.ADVANCED,
stored_field_name='security',
) )
rdpPort = ui.gui.NumericField( rdp_port = ui.gui.NumericField(
order=93, order=93,
length=5, # That is, max allowed value is 65535 length=5, # That is, max allowed value is 65535
label=_('RDP Port'), label=_('RDP Port'),
@ -269,9 +288,10 @@ class HTML5RDPTransport(transports.Transport):
required=True, #: Numeric fields have always a value, so this not really needed required=True, #: Numeric fields have always a value, so this not really needed
default=3389, default=3389,
tab=types.ui.Tab.ADVANCED, tab=types.ui.Tab.ADVANCED,
stored_field_name='rdpPort',
) )
customGEPath = ui.gui.TextField( custom_glyptodon_path = ui.gui.TextField(
label=_('Glyptodon Enterprise context path'), label=_('Glyptodon Enterprise context path'),
order=94, order=94,
tooltip=_( tooltip=_(
@ -281,6 +301,7 @@ class HTML5RDPTransport(transports.Transport):
length=128, length=128,
required=False, required=False,
tab=types.ui.Tab.ADVANCED, tab=types.ui.Tab.ADVANCED,
stored_field_name='customGEPath',
) )
def initialize(self, values: 'Module.ValuesType'): def initialize(self, values: 'Module.ValuesType'):
@ -303,7 +324,7 @@ class HTML5RDPTransport(transports.Transport):
ready = self.cache.get(ip) ready = self.cache.get(ip)
if not ready: if not ready:
# Check again for readyness # Check again for readyness
if self.test_connectivity(userService, ip, self.rdpPort.num()) is True: if self.test_connectivity(userService, ip, self.rdp_port.num()) is True:
self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT) self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT)
return True return True
self.cache.put(ip, 'N', READY_CACHE_TIMEOUT) self.cache.put(ip, 'N', READY_CACHE_TIMEOUT)
@ -328,11 +349,11 @@ class HTML5RDPTransport(transports.Transport):
username = cdata[1] or username username = cdata[1] or username
password = cdata[2] or password password = cdata[2] or password
if self.fixedPassword.value: if self.forced_password.value:
password = self.fixedPassword.value password = self.forced_password.value
if self.fixedName.value: if self.forced_username.value:
username = self.fixedName.value username = self.forced_username.value
proc = username.split('@') proc = username.split('@')
if len(proc) > 1: if len(proc) > 1:
@ -342,16 +363,16 @@ class HTML5RDPTransport(transports.Transport):
username = proc[0] username = proc[0]
azureAd = False azureAd = False
if self.fixedDomain.value != '': if self.forced_domain.value != '':
if self.fixedDomain.value.lower() == 'azuread': if self.forced_domain.value.lower() == 'azuread':
azureAd = True azureAd = True
else: else:
domain = self.fixedDomain.value domain = self.forced_domain.value
if self.useEmptyCreds.as_bool(): if self.force_empty_creds.as_bool():
username, password, domain = '', '', '' username, password, domain = '', '', ''
if self.withoutDomain.as_bool(): if self.force_no_domain.as_bool():
domain = '' domain = ''
if '.' in domain: # FQDN domain form if '.' in domain: # FQDN domain form
@ -400,18 +421,18 @@ class HTML5RDPTransport(transports.Transport):
params = { params = {
'protocol': 'rdp', 'protocol': 'rdp',
'hostname': ip, 'hostname': ip,
'port': self.rdpPort.num(), 'port': self.rdp_port.num(),
'username': username, 'username': username,
'password': passwordCrypted, 'password': passwordCrypted,
'resize-method': 'display-update', 'resize-method': 'display-update',
'ignore-cert': 'true', 'ignore-cert': 'true',
'security': self.security.value, 'security': self.security.value,
'enable-drive': as_txt(self.enableFileSharing.value in ('true', 'down', 'up')), 'enable-drive': as_txt(self.enable_file_sharing.value in ('true', 'down', 'up')),
'disable-upload': as_txt(self.enableFileSharing.value not in ('true', 'up')), 'disable-upload': as_txt(self.enable_file_sharing.value not in ('true', 'up')),
'drive-path': f'/share/{user.uuid}', 'drive-path': f'/share/{user.uuid}',
'drive-name': 'UDSfs', 'drive-name': 'UDSfs',
'disable-copy': as_txt(self.enableClipboard.value in ('dis-copy', 'disabled')), 'disable-copy': as_txt(self.enable_clipboard.value in ('dis-copy', 'disabled')),
'disable-paste': as_txt(self.enableClipboard.value in ('dis-paste', 'disabled')), 'disable-paste': as_txt(self.enable_clipboard.value in ('dis-paste', 'disabled')),
'create-drive-path': 'true', 'create-drive-path': 'true',
'ticket-info': { 'ticket-info': {
'userService': userService.uuid, 'userService': userService.uuid,
@ -446,22 +467,22 @@ class HTML5RDPTransport(transports.Transport):
if domain: if domain:
params['domain'] = domain params['domain'] = domain
if self.serverLayout.value != '-': if self.server_layout.value != '-':
params['server-layout'] = self.serverLayout.value params['server-layout'] = self.server_layout.value
if not self.enableAudio.as_bool(): if not self.enable_audio.as_bool():
params['disable-audio'] = 'true' params['disable-audio'] = 'true'
elif self.enableAudioInput.as_bool(): elif self.enable_microphone.as_bool():
params['enable-audio-input'] = 'true' params['enable-audio-input'] = 'true'
if self.enablePrinting.as_bool(): if self.enable_printing.as_bool():
params['enable-printing'] = 'true' params['enable-printing'] = 'true'
params['printer-name'] = 'UDS-Printer' params['printer-name'] = 'UDS-Printer'
if self.wallpaper.as_bool(): if self.wallpaper.as_bool():
params['enable-wallpaper'] = 'true' params['enable-wallpaper'] = 'true'
if self.desktopComp.as_bool(): if self.allow_destop_composition.as_bool():
params['enable-desktop-composition'] = 'true' params['enable-desktop-composition'] = 'true'
if self.smooth.as_bool(): if self.smooth.as_bool():
@ -469,14 +490,14 @@ class HTML5RDPTransport(transports.Transport):
logger.debug('RDP Params: %s', params) logger.debug('RDP Params: %s', params)
ticket = models.TicketStore.create(params, validity=self.ticketValidity.num()) ticket = models.TicketStore.create(params, validity=self.ticket_validity.num())
onw = f'&o_n_w={transport.uuid}' onw = f'&o_n_w={transport.uuid}'
if self.forceNewWindow.value == consts.TRUE_STR: if self.force_new_window.value == consts.TRUE_STR:
onw = f'&o_n_w={userService.deployed_service.uuid}' onw = f'&o_n_w={userService.deployed_service.uuid}'
elif self.forceNewWindow.value == 'overwrite': elif self.force_new_window.value == 'overwrite':
onw = '&o_s_w=yes' onw = '&o_s_w=yes'
path = self.customGEPath.value if self.useGlyptodonTunnel.as_bool() else '/guacamole' path = self.custom_glyptodon_path.value if self.use_glyptodon.as_bool() else '/guacamole'
# Remove trailing / # Remove trailing /
path = path.rstrip('/') path = path.rstrip('/')

View File

@ -72,13 +72,14 @@ class HTML5SSHTransport(transports.Transport):
tunnel = fields.tunnel_field() tunnel = fields.tunnel_field()
useGlyptodonTunnel = HTML5RDPTransport.useGlyptodonTunnel useGlyptodonTunnel = HTML5RDPTransport.use_glyptodon
username = gui.TextField( username = gui.TextField(
label=_('Username'), label=_('Username'),
order=20, order=20,
tooltip=_('Username for SSH connection authentication.'), tooltip=_('Username for SSH connection authentication.'),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='username'
) )
# password = gui.PasswordField( # password = gui.PasswordField(
@ -105,22 +106,24 @@ class HTML5SSHTransport(transports.Transport):
# tab=types.ui.Tab.CREDENTIALS, # tab=types.ui.Tab.CREDENTIALS,
# ) # )
sshCommand = gui.TextField( ssh_command = gui.TextField(
label=_('SSH Command'), label=_('SSH Command'),
order=30, order=30,
tooltip=_( tooltip=_(
'Command to execute on the remote server. If not provided, an interactive shell will be executed.' 'Command to execute on the remote server. If not provided, an interactive shell will be executed.'
), ),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='sshCommand'
) )
enableFileSharing = HTML5RDPTransport.enableFileSharing enable_file_sharing = HTML5RDPTransport.enable_file_sharing
fileSharingRoot = gui.TextField( filesharing_root = gui.TextField(
label=_('File Sharing Root'), label=_('File Sharing Root'),
order=32, order=32,
tooltip=_('Root path for file sharing. If not provided, root directory will be used.'), tooltip=_('Root path for file sharing. If not provided, root directory will be used.'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='fileSharingRoot'
) )
sshPort = gui.NumericField( ssh_port = gui.NumericField(
length=40, length=40,
label=_('SSH Server port'), label=_('SSH Server port'),
default=22, default=22,
@ -128,14 +131,16 @@ class HTML5SSHTransport(transports.Transport):
tooltip=_('Port of the SSH server.'), tooltip=_('Port of the SSH server.'),
required=True, required=True,
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='sshPort'
) )
sshHostKey = gui.TextField( ssh_host_key = gui.TextField(
label=_('SSH Host Key'), label=_('SSH Host Key'),
order=34, order=34,
tooltip=_('Host key of the SSH server. If not provided, no verification of host identity is done.'), tooltip=_('Host key of the SSH server. If not provided, no verification of host identity is done.'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='sshHostKey'
) )
serverKeepAlive = gui.NumericField( server_keep_alive = gui.NumericField(
length=3, length=3,
label=_('Server Keep Alive'), label=_('Server Keep Alive'),
default=30, default=30,
@ -146,12 +151,13 @@ class HTML5SSHTransport(transports.Transport):
required=True, required=True,
min_value=0, min_value=0,
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='serverKeepAlive'
) )
ticketValidity = fields.tunnel_ricket_validity_field() ticket_validity = fields.tunnel_ticket_validity_field()
forceNewWindow = HTML5RDPTransport.forceNewWindow force_new_window = HTML5RDPTransport.force_new_window
customGEPath = HTML5RDPTransport.customGEPath custom_glyptodon_path = HTML5RDPTransport.custom_glyptodon_path
def initialize(self, values: 'Module.ValuesType'): def initialize(self, values: 'Module.ValuesType'):
if not values: if not values:
@ -166,7 +172,7 @@ class HTML5SSHTransport(transports.Transport):
ready = self.cache.get(ip) ready = self.cache.get(ip)
if not ready: if not ready:
# Check again for readyness # Check again for readyness
if self.test_connectivity(userService, ip, self.sshPort.value) is True: if self.test_connectivity(userService, ip, self.ssh_port.value) is True:
self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT) self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT)
return True return True
self.cache.put(ip, 'N', READY_CACHE_TIMEOUT) self.cache.put(ip, 'N', READY_CACHE_TIMEOUT)
@ -186,12 +192,12 @@ class HTML5SSHTransport(transports.Transport):
params = { params = {
'protocol': 'ssh', 'protocol': 'ssh',
'hostname': ip, 'hostname': ip,
'port': str(self.sshPort.num()), 'port': str(self.ssh_port.num()),
} }
# Optional numeric keep alive. If less than 2, it is not sent # Optional numeric keep alive. If less than 2, it is not sent
if self.serverKeepAlive.num() >= 2: if self.server_keep_alive.num() >= 2:
params['server-alive-interval'] = str(self.serverKeepAlive.num()) params['server-alive-interval'] = str(self.server_keep_alive.num())
# Add optional parameters (strings only) # Add optional parameters (strings only)
for i in ( for i in (
@ -199,38 +205,38 @@ class HTML5SSHTransport(transports.Transport):
# ('password', self.password), # ('password', self.password),
# ('private-key', self.sshPrivateKey), # ('private-key', self.sshPrivateKey),
# ('passphrase', self.sshPassphrase), # ('passphrase', self.sshPassphrase),
('command', self.sshCommand), ('command', self.ssh_command),
('host-key', self.sshHostKey), ('host-key', self.ssh_host_key),
): ):
if i[1].value.strip(): if i[1].value.strip():
params[i[0]] = i[1].value.strip() params[i[0]] = i[1].value.strip()
# Filesharing using guacamole sftp # Filesharing using guacamole sftp
if self.enableFileSharing.value != 'false': if self.enable_file_sharing.value != 'false':
params['enable-sftp'] = 'true' params['enable-sftp'] = 'true'
if self.fileSharingRoot.value.strip(): if self.filesharing_root.value.strip():
params['sftp-root-directory'] = self.fileSharingRoot.value.strip() params['sftp-root-directory'] = self.filesharing_root.value.strip()
if self.enableFileSharing.value not in ('down', 'true'): if self.enable_file_sharing.value not in ('down', 'true'):
params['sftp-disable-download'] = 'true' params['sftp-disable-download'] = 'true'
if self.enableFileSharing.value not in ('up', 'true'): if self.enable_file_sharing.value not in ('up', 'true'):
params['sftp-disable-upload'] = 'true' params['sftp-disable-upload'] = 'true'
logger.debug('SSH Params: %s', params) logger.debug('SSH Params: %s', params)
scrambler = CryptoManager().random_string(32) scrambler = CryptoManager().random_string(32)
ticket = models.TicketStore.create(params, validity=self.ticketValidity.num()) ticket = models.TicketStore.create(params, validity=self.ticket_validity.num())
onw = '' onw = ''
if self.forceNewWindow.value == 'true': if self.force_new_window.value == 'true':
onw = 'o_n_w={}' onw = 'o_n_w={}'
elif self.forceNewWindow.value == 'overwrite': elif self.force_new_window.value == 'overwrite':
onw = 'o_s_w=yes' onw = 'o_s_w=yes'
onw = onw.format(hash(transport.name)) onw = onw.format(hash(transport.name))
path = self.customGEPath.value if self.useGlyptodonTunnel.as_bool() else '/guacamole' path = self.custom_glyptodon_path.value if self.useGlyptodonTunnel.as_bool() else '/guacamole'
# Remove trailing / # Remove trailing /
path = path.rstrip('/') path = path.rstrip('/')

View File

@ -73,22 +73,24 @@ class HTML5VNCTransport(transports.Transport):
tunnel = fields.tunnel_field() tunnel = fields.tunnel_field()
useGlyptodonTunnel = HTML5RDPTransport.useGlyptodonTunnel use_glyptodon = HTML5RDPTransport.use_glyptodon
username = gui.TextField( username = gui.TextField(
label=_('Username'), label=_('Username'),
order=20, order=20,
tooltip=_('Username for VNC connection authentication.'), tooltip=_('Username for VNC connection authentication.'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='username'
) )
password = gui.PasswordField( password = gui.PasswordField(
label=_('Password'), label=_('Password'),
order=21, order=21,
tooltip=_('Password for VNC connection authentication'), tooltip=_('Password for VNC connection authentication'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='password'
) )
vncPort = gui.NumericField( vnc_port = gui.NumericField(
length=22, length=22,
label=_('VNC Server port'), label=_('VNC Server port'),
default=5900, default=5900,
@ -96,9 +98,10 @@ class HTML5VNCTransport(transports.Transport):
tooltip=_('Port of the VNC server.'), tooltip=_('Port of the VNC server.'),
required=True, required=True,
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='vncPort'
) )
colorDepth = gui.ChoiceField( color_depth = gui.ChoiceField(
order=26, order=26,
label=_('Color depth'), label=_('Color depth'),
tooltip=_('Color depth for VNC connection. Use this to control bandwidth.'), tooltip=_('Color depth for VNC connection. Use this to control bandwidth.'),
@ -112,30 +115,34 @@ class HTML5VNCTransport(transports.Transport):
], ],
default='-', default='-',
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='colorDepth'
) )
swapRedBlue = gui.CheckBoxField( swap_red_blue = gui.CheckBoxField(
label=_('Swap red/blue'), label=_('Swap red/blue'),
order=27, order=27,
tooltip=_('Use this if your colours seems incorrect (blue appears red, ..) to swap them.'), tooltip=_('Use this if your colours seems incorrect (blue appears red, ..) to swap them.'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='swapRedBlue'
) )
cursor = gui.CheckBoxField( cursor = gui.CheckBoxField(
label=_('Remote cursor'), label=_('Remote cursor'),
order=28, order=28,
tooltip=_('If set, force to show remote cursor'), tooltip=_('If set, force to show remote cursor'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='cursor'
) )
readOnly = gui.CheckBoxField( read_only = gui.CheckBoxField(
label=_('Read only'), label=_('Read only'),
order=29, order=29,
tooltip=_('If set, the connection will be read only'), tooltip=_('If set, the connection will be read only'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='readOnly'
) )
ticketValidity = fields.tunnel_ricket_validity_field() ticket_validity = fields.tunnel_ticket_validity_field()
forceNewWindow = HTML5RDPTransport.forceNewWindow force_new_window = HTML5RDPTransport.force_new_window
customGEPath = HTML5RDPTransport.customGEPath custom_glyptodon_path = HTML5RDPTransport.custom_glyptodon_path
def initialize(self, values: 'Module.ValuesType'): def initialize(self, values: 'Module.ValuesType'):
if not values: if not values:
@ -150,7 +157,7 @@ class HTML5VNCTransport(transports.Transport):
ready = self.cache.get(ip) ready = self.cache.get(ip)
if not ready: if not ready:
# Check again for readyness # Check again for readyness
if self.test_connectivity(userService, ip, self.vncPort.value) is True: if self.test_connectivity(userService, ip, self.vnc_port.value) is True:
self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT) self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT)
return True return True
self.cache.put(ip, 'N', READY_CACHE_TIMEOUT) self.cache.put(ip, 'N', READY_CACHE_TIMEOUT)
@ -170,7 +177,7 @@ class HTML5VNCTransport(transports.Transport):
params = { params = {
'protocol': 'vnc', 'protocol': 'vnc',
'hostname': ip, 'hostname': ip,
'port': str(self.vncPort.num()), 'port': str(self.vnc_port.num()),
} }
if self.username.value.strip(): if self.username.value.strip():
@ -179,31 +186,31 @@ class HTML5VNCTransport(transports.Transport):
if self.password.value.strip(): if self.password.value.strip():
params['password'] = self.password.value.strip() params['password'] = self.password.value.strip()
if self.colorDepth.value != '-': if self.color_depth.value != '-':
params['color-depth'] = self.colorDepth.value params['color-depth'] = self.color_depth.value
if self.swapRedBlue.as_bool(): if self.swap_red_blue.as_bool():
params['swap-red-blue'] = 'true' params['swap-red-blue'] = 'true'
if self.cursor.as_bool(): if self.cursor.as_bool():
params['cursor'] = 'remote' params['cursor'] = 'remote'
if self.readOnly.as_bool(): if self.read_only.as_bool():
params['read-only'] = 'true' params['read-only'] = 'true'
logger.debug('VNC Params: %s', params) logger.debug('VNC Params: %s', params)
scrambler = CryptoManager().random_string(32) scrambler = CryptoManager().random_string(32)
ticket = models.TicketStore.create(params, validity=self.ticketValidity.num()) ticket = models.TicketStore.create(params, validity=self.ticket_validity.num())
onw = '' onw = ''
if self.forceNewWindow.value == 'true': if self.force_new_window.value == 'true':
onw = 'o_n_w={}' onw = 'o_n_w={}'
elif self.forceNewWindow.value == 'overwrite': elif self.force_new_window.value == 'overwrite':
onw = 'o_s_w=yes' onw = 'o_s_w=yes'
onw = onw.format(hash(transport.name)) onw = onw.format(hash(transport.name))
path = self.customGEPath.value if self.useGlyptodonTunnel.as_bool() else '/guacamole' path = self.custom_glyptodon_path.value if self.use_glyptodon.as_bool() else '/guacamole'
# Remove trailing / # Remove trailing /
path = path.rstrip('/') path = path.rstrip('/')

View File

@ -64,41 +64,41 @@ class RDPTransport(BaseRDPTransport):
type_type = 'RDPTransport' type_type = 'RDPTransport'
type_description = _('RDP Protocol. Direct connection.') type_description = _('RDP Protocol. Direct connection.')
useEmptyCreds = BaseRDPTransport.useEmptyCreds force_empty_creds = BaseRDPTransport.force_empty_creds
fixedName = BaseRDPTransport.fixedName forced_username = BaseRDPTransport.forced_username
fixedPassword = BaseRDPTransport.fixedPassword forced_password = BaseRDPTransport.forced_password
withoutDomain = BaseRDPTransport.withoutDomain force_no_domain = BaseRDPTransport.force_no_domain
fixedDomain = BaseRDPTransport.fixedDomain forced_domain = BaseRDPTransport.forced_domain
allowSmartcards = BaseRDPTransport.allowSmartcards allow_smartcards = BaseRDPTransport.allow_smartcards
allowPrinters = BaseRDPTransport.allowPrinters allow_printers = BaseRDPTransport.allow_printers
allowDrives = BaseRDPTransport.allowDrives allow_drives = BaseRDPTransport.allow_drives
enforceDrives = BaseRDPTransport.enforceDrives enforce_drives = BaseRDPTransport.enforce_drives
allowSerials = BaseRDPTransport.allowSerials allow_serial_ports = BaseRDPTransport.allow_serial_ports
allowClipboard = BaseRDPTransport.allowClipboard allow_clipboard = BaseRDPTransport.allow_clipboard
allowAudio = BaseRDPTransport.allowAudio allow_audio = BaseRDPTransport.allow_audio
allowWebcam = BaseRDPTransport.allowWebcam allow_webcam = BaseRDPTransport.allow_webcam
usbRedirection = BaseRDPTransport.usbRedirection allow_usb_redirection = BaseRDPTransport.allow_usb_redirection
wallpaper = BaseRDPTransport.wallpaper wallpaper = BaseRDPTransport.wallpaper
multimon = BaseRDPTransport.multimon multimon = BaseRDPTransport.multimon
aero = BaseRDPTransport.aero aero = BaseRDPTransport.aero
smooth = BaseRDPTransport.smooth smooth = BaseRDPTransport.smooth
showConnectionBar = BaseRDPTransport.showConnectionBar show_connection_bar = BaseRDPTransport.show_connection_bar
credssp = BaseRDPTransport.credssp credssp = BaseRDPTransport.credssp
rdpPort = BaseRDPTransport.rdpPort rdp_port = BaseRDPTransport.rdp_port
screenSize = BaseRDPTransport.screenSize screen_size = BaseRDPTransport.screen_size
colorDepth = BaseRDPTransport.colorDepth color_depth = BaseRDPTransport.color_depth
alsa = BaseRDPTransport.alsa lnx_alsa = BaseRDPTransport.lnx_alsa
multimedia = BaseRDPTransport.multimedia lnx_multimedia = BaseRDPTransport.lnx_multimedia
printerString = BaseRDPTransport.printerString lnx_printer_string = BaseRDPTransport.lnx_printer_string
smartcardString = BaseRDPTransport.smartcardString lnx_smartcard_string = BaseRDPTransport.lnx_smartcard_string
allowMacMSRDC = BaseRDPTransport.allowMacMSRDC mac_allow_msrdc = BaseRDPTransport.mac_allow_msrdc
customParameters = BaseRDPTransport.customParameters lnx_custom_parameters = BaseRDPTransport.lnx_custom_parameters
customParametersMAC = BaseRDPTransport.customParametersMAC mac_custom_parameters = BaseRDPTransport.mac_custom_parameters
customParametersWindows = BaseRDPTransport.customParametersWindows wnd_custom_parameters = BaseRDPTransport.wnd_custom_parameters
optimizeTeams = BaseRDPTransport.optimizeTeams wnd_optimize_teams = BaseRDPTransport.wnd_optimize_teams
def get_transport_script( # pylint: disable=too-many-locals def get_transport_script( # pylint: disable=too-many-locals
self, self,
@ -119,57 +119,57 @@ class RDPTransport(BaseRDPTransport):
# width, height = CommonPrefs.getWidthHeight(prefs) # width, height = CommonPrefs.getWidthHeight(prefs)
# depth = CommonPrefs.getDepth(prefs) # depth = CommonPrefs.getDepth(prefs)
width, height = self.screenSize.value.split('x') width, height = self.screen_size.value.split('x')
depth = self.colorDepth.value depth = self.color_depth.value
r = RDPFile(width == '-1' or height == '-1', width, height, depth, target=os.os) r = RDPFile(width == '-1' or height == '-1', width, height, depth, target=os.os)
# r.enablecredsspsupport = ci.get('sso') == 'True' or self.credssp.as_bool() # r.enablecredsspsupport = ci.get('sso') == 'True' or self.credssp.as_bool()
r.enablecredsspsupport = self.credssp.as_bool() r.enablecredsspsupport = self.credssp.as_bool()
r.address = f'{ip}:{self.rdpPort.num()}' r.address = f'{ip}:{self.rdp_port.num()}'
r.username = ci.username r.username = ci.username
r.password = ci.password r.password = ci.password
r.domain = ci.domain r.domain = ci.domain
r.redirectPrinters = self.allowPrinters.as_bool() r.redirectPrinters = self.allow_printers.as_bool()
r.redirectSmartcards = self.allowSmartcards.as_bool() r.redirectSmartcards = self.allow_smartcards.as_bool()
r.redirectDrives = self.allowDrives.value r.redirectDrives = self.allow_drives.value
r.redirectSerials = self.allowSerials.as_bool() r.redirectSerials = self.allow_serial_ports.as_bool()
r.enableClipboard = self.allowClipboard.as_bool() r.enableClipboard = self.allow_clipboard.as_bool()
r.redirectAudio = self.allowAudio.as_bool() r.redirectAudio = self.allow_audio.as_bool()
r.redirectWebcam = self.allowWebcam.as_bool() r.redirectWebcam = self.allow_webcam.as_bool()
r.showWallpaper = self.wallpaper.as_bool() r.showWallpaper = self.wallpaper.as_bool()
r.multimon = self.multimon.as_bool() r.multimon = self.multimon.as_bool()
r.desktopComposition = self.aero.as_bool() r.desktopComposition = self.aero.as_bool()
r.smoothFonts = self.smooth.as_bool() r.smoothFonts = self.smooth.as_bool()
r.displayConnectionBar = self.showConnectionBar.as_bool() r.displayConnectionBar = self.show_connection_bar.as_bool()
r.enablecredsspsupport = self.credssp.as_bool() r.enablecredsspsupport = self.credssp.as_bool()
r.multimedia = self.multimedia.as_bool() r.multimedia = self.lnx_multimedia.as_bool()
r.alsa = self.alsa.as_bool() r.alsa = self.lnx_alsa.as_bool()
r.smartcardString = self.smartcardString.value r.smartcardString = self.lnx_smartcard_string.value
r.printerString = self.printerString.value r.printerString = self.lnx_printer_string.value
r.enforcedShares = self.enforceDrives.value r.enforcedShares = self.enforce_drives.value
r.redirectUSB = self.usbRedirection.value r.redirectUSB = self.allow_usb_redirection.value
r.optimizeTeams = self.optimizeTeams.as_bool() r.optimizeTeams = self.wnd_optimize_teams.as_bool()
sp: collections.abc.MutableMapping[str, typing.Any] = { sp: collections.abc.MutableMapping[str, typing.Any] = {
'password': ci.password, 'password': ci.password,
'this_server': request.build_absolute_uri('/'), 'this_server': request.build_absolute_uri('/'),
'ip': ip, 'ip': ip,
'port': self.rdpPort.value, # As string, because we need to use it in the template 'port': self.rdp_port.value, # As string, because we need to use it in the template
'address': r.address, 'address': r.address,
} }
if os.os == types.os.KnownOS.WINDOWS: if os.os == types.os.KnownOS.WINDOWS:
r.customParameters = self.customParametersWindows.value r.customParameters = self.wnd_custom_parameters.value
if ci.password: if ci.password:
r.password = '{password}' # nosec: password is not hardcoded r.password = '{password}' # nosec: password is not hardcoded
sp.update( sp.update(
{ {
'as_file': r.as_file, 'as_file': r.as_file,
'optimize_teams': self.optimizeTeams.as_bool(), 'optimize_teams': self.wnd_optimize_teams.as_bool(),
} }
) )
elif os.os == types.os.KnownOS.LINUX: elif os.os == types.os.KnownOS.LINUX:
r.customParameters = self.customParameters.value r.customParameters = self.lnx_custom_parameters.value
sp.update( sp.update(
{ {
'as_new_xfreerdp_params': r.as_new_xfreerdp_params, 'as_new_xfreerdp_params': r.as_new_xfreerdp_params,
@ -177,12 +177,12 @@ class RDPTransport(BaseRDPTransport):
} }
) )
elif os.os == types.os.KnownOS.MAC_OS: elif os.os == types.os.KnownOS.MAC_OS:
r.customParameters = self.customParametersMAC.value r.customParameters = self.mac_custom_parameters.value
sp.update( sp.update(
{ {
'as_new_xfreerdp_params': r.as_new_xfreerdp_params, 'as_new_xfreerdp_params': r.as_new_xfreerdp_params,
'as_rdp_url': r.as_rdp_url if self.allowMacMSRDC.as_bool() else '', 'as_rdp_url': r.as_rdp_url if self.mac_allow_msrdc.as_bool() else '',
'as_file': r.as_file if self.allowMacMSRDC.as_bool() else '', 'as_file': r.as_file if self.mac_allow_msrdc.as_bool() else '',
'address': r.address, 'address': r.address,
} }
) )

View File

@ -59,52 +59,59 @@ class BaseRDPTransport(transports.Transport):
icon_file = 'rdp.png' icon_file = 'rdp.png'
protocol = types.transports.Protocol.RDP protocol = types.transports.Protocol.RDP
useEmptyCreds = gui.CheckBoxField( force_empty_creds = gui.CheckBoxField(
label=_('Empty creds'), label=_('Empty creds'),
order=11, order=11,
tooltip=_('If checked, the credentials used to connect will be emtpy'), tooltip=_('If checked, the credentials used to connect will be emtpy'),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='useEmptyCreds',
) )
fixedName = gui.TextField( forced_username = gui.TextField(
label=_('Username'), label=_('Username'),
order=12, order=12,
tooltip=_('If not empty, this username will be always used as credential'), tooltip=_('If not empty, this username will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedName',
) )
fixedPassword = gui.PasswordField( forced_password = gui.PasswordField(
label=_('Password'), label=_('Password'),
order=13, order=13,
tooltip=_('If not empty, this password will be always used as credential'), tooltip=_('If not empty, this password will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedPassword',
) )
withoutDomain = gui.CheckBoxField( force_no_domain = gui.CheckBoxField(
label=_('Without Domain'), label=_('Without Domain'),
order=14, order=14,
tooltip=_( tooltip=_(
'If checked, the domain part will always be emptied (to connect to xrdp for example is needed)' 'If checked, the domain part will always be emptied (to connect to xrdp for example is needed)'
), ),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='withoutDomain',
) )
fixedDomain = gui.TextField( forced_domain = gui.TextField(
label=_('Domain'), label=_('Domain'),
order=15, order=15,
tooltip=_('If not empty, this domain will be always used as credential (used as DOMAIN\\user)'), tooltip=_('If not empty, this domain will be always used as credential (used as DOMAIN\\user)'),
tab=types.ui.Tab.CREDENTIALS, tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedDomain',
) )
allowSmartcards = gui.CheckBoxField( allow_smartcards = gui.CheckBoxField(
label=_('Allow Smartcards'), label=_('Allow Smartcards'),
order=20, order=20,
tooltip=_('If checked, this transport will allow the use of smartcards'), tooltip=_('If checked, this transport will allow the use of smartcards'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='allowSmartcards',
) )
allowPrinters = gui.CheckBoxField( allow_printers = gui.CheckBoxField(
label=_('Allow Printers'), label=_('Allow Printers'),
order=21, order=21,
tooltip=_('If checked, this transport will allow the use of user printers'), tooltip=_('If checked, this transport will allow the use of user printers'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='allowPrinters',
) )
allowDrives = gui.ChoiceField( allow_drives = gui.ChoiceField(
label=_('Local drives policy'), label=_('Local drives policy'),
order=22, order=22,
tooltip=_('Local drives redirection policy'), tooltip=_('Local drives redirection policy'),
@ -115,44 +122,50 @@ class BaseRDPTransport(transports.Transport):
{'id': 'true', 'text': 'Allow any drive'}, {'id': 'true', 'text': 'Allow any drive'},
], ],
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='allowDrives',
) )
enforceDrives = gui.TextField( enforce_drives = gui.TextField(
label=_('Force drives'), label=_('Force drives'),
order=23, order=23,
tooltip=_( tooltip=_(
'Use comma separated values, for example "C:,D:". If drives policy is disallowed, this will be ignored' 'Use comma separated values, for example "C:,D:". If drives policy is disallowed, this will be ignored'
), ),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='enforceDrives',
) )
allowSerials = gui.CheckBoxField( allow_serial_ports = gui.CheckBoxField(
label=_('Allow Serials'), label=_('Allow Serials'),
order=24, order=24,
tooltip=_('If checked, this transport will allow the use of user serial ports'), tooltip=_('If checked, this transport will allow the use of user serial ports'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='allowSerials',
) )
allowClipboard = gui.CheckBoxField( allow_clipboard = gui.CheckBoxField(
label=_('Enable clipboard'), label=_('Enable clipboard'),
order=25, order=25,
tooltip=_('If checked, copy-paste functions will be allowed'), tooltip=_('If checked, copy-paste functions will be allowed'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
default=True, default=True,
stored_field_name='allowClipboard',
) )
allowAudio = gui.CheckBoxField( allow_audio = gui.CheckBoxField(
label=_('Enable sound'), label=_('Enable sound'),
order=26, order=26,
tooltip=_('If checked, sound will be redirected.'), tooltip=_('If checked, sound will be redirected.'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
default=True, default=True,
stored_field_name='allowAudio',
) )
allowWebcam = gui.CheckBoxField( allow_webcam = gui.CheckBoxField(
label=_('Enable webcam'), label=_('Enable webcam'),
order=27, order=27,
tooltip=_('If checked, webcam will be redirected (ONLY Windows).'), tooltip=_('If checked, webcam will be redirected (ONLY Windows).'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
default=False, default=False,
stored_field_name='allowWebcam',
) )
usbRedirection = gui.ChoiceField( allow_usb_redirection = gui.ChoiceField(
label=_('USB redirection'), label=_('USB redirection'),
order=28, order=28,
tooltip=_('USB redirection policy'), tooltip=_('USB redirection policy'),
@ -167,6 +180,7 @@ class BaseRDPTransport(transports.Transport):
{'id': '{745a17a0-74d3-11d0-b6fe-00a0c90f57da}', 'text': 'HIDs'}, {'id': '{745a17a0-74d3-11d0-b6fe-00a0c90f57da}', 'text': 'HIDs'},
], ],
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
stored_field_name='usbRedirection',
) )
credssp = gui.CheckBoxField( credssp = gui.CheckBoxField(
@ -175,8 +189,9 @@ class BaseRDPTransport(transports.Transport):
tooltip=_('If checked, will enable Credentials Provider Support)'), tooltip=_('If checked, will enable Credentials Provider Support)'),
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
default=True, default=True,
stored_field_name='credssp',
) )
rdpPort = gui.NumericField( rdp_port = gui.NumericField(
order=30, order=30,
length=5, # That is, max allowed value is 65535 length=5, # That is, max allowed value is 65535
label=_('RDP Port'), label=_('RDP Port'),
@ -184,9 +199,10 @@ class BaseRDPTransport(transports.Transport):
tab=types.ui.Tab.PARAMETERS, tab=types.ui.Tab.PARAMETERS,
required=True, #: Numeric fields have always a value, so this not really needed required=True, #: Numeric fields have always a value, so this not really needed
default=3389, default=3389,
stored_field_name='rdpPort',
) )
screenSize = gui.ChoiceField( screen_size = gui.ChoiceField(
label=_('Screen Size'), label=_('Screen Size'),
order=31, order=31,
tooltip=_('Screen size for this transport'), tooltip=_('Screen size for this transport'),
@ -208,9 +224,10 @@ class BaseRDPTransport(transports.Transport):
{'id': '-1x-1', 'text': 'Full screen'}, {'id': '-1x-1', 'text': 'Full screen'},
], ],
tab=types.ui.Tab.DISPLAY, tab=types.ui.Tab.DISPLAY,
stored_field_name='screenSize',
) )
colorDepth = gui.ChoiceField( color_depth = gui.ChoiceField(
label=_('Color depth'), label=_('Color depth'),
order=32, order=32,
tooltip=_('Color depth for this connection'), tooltip=_('Color depth for this connection'),
@ -222,6 +239,7 @@ class BaseRDPTransport(transports.Transport):
{'id': '32', 'text': '32'}, {'id': '32', 'text': '32'},
], ],
tab=types.ui.Tab.DISPLAY, tab=types.ui.Tab.DISPLAY,
stored_field_name='colorDepth',
) )
wallpaper = gui.CheckBoxField( wallpaper = gui.CheckBoxField(
@ -231,6 +249,7 @@ class BaseRDPTransport(transports.Transport):
'If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)' 'If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)'
), ),
tab=types.ui.Tab.DISPLAY, tab=types.ui.Tab.DISPLAY,
stored_field_name='wallpaper',
) )
multimon = gui.CheckBoxField( multimon = gui.CheckBoxField(
label=_('Multiple monitors'), label=_('Multiple monitors'),
@ -239,12 +258,14 @@ class BaseRDPTransport(transports.Transport):
'If checked, all client monitors will be used for displaying (only works on windows clients)' 'If checked, all client monitors will be used for displaying (only works on windows clients)'
), ),
tab=types.ui.Tab.DISPLAY, tab=types.ui.Tab.DISPLAY,
stored_field_name='multimon',
) )
aero = gui.CheckBoxField( aero = gui.CheckBoxField(
label=_('Allow Desk.Comp.'), label=_('Allow Desk.Comp.'),
order=35, order=35,
tooltip=_('If checked, desktop composition will be allowed'), tooltip=_('If checked, desktop composition will be allowed'),
tab=types.ui.Tab.DISPLAY, tab=types.ui.Tab.DISPLAY,
stored_field_name='aero',
) )
smooth = gui.CheckBoxField( smooth = gui.CheckBoxField(
label=_('Font Smoothing'), label=_('Font Smoothing'),
@ -252,42 +273,48 @@ class BaseRDPTransport(transports.Transport):
order=36, order=36,
tooltip=_('If checked, fonts smoothing will be allowed'), tooltip=_('If checked, fonts smoothing will be allowed'),
tab=types.ui.Tab.DISPLAY, tab=types.ui.Tab.DISPLAY,
stored_field_name='smooth',
) )
showConnectionBar = gui.CheckBoxField( show_connection_bar = gui.CheckBoxField(
label=_('Connection Bar'), label=_('Connection Bar'),
order=37, order=37,
tooltip=_('If checked, connection bar will be shown (only on Windows clients)'), tooltip=_('If checked, connection bar will be shown (only on Windows clients)'),
tab=types.ui.Tab.DISPLAY, tab=types.ui.Tab.DISPLAY,
default=True, default=True,
stored_field_name='showConnectionBar',
) )
multimedia = gui.CheckBoxField( lnx_multimedia = gui.CheckBoxField(
label=_('Multimedia sync'), label=_('Multimedia sync'),
order=40, order=40,
tooltip=_('If checked. Linux client will use multimedia parameter for xfreerdp'), tooltip=_('If checked. Linux client will use multimedia parameter for xfreerdp'),
tab='Linux Client', tab='Linux Client',
stored_field_name='multimedia',
) )
alsa = gui.CheckBoxField( lnx_alsa = gui.CheckBoxField(
label=_('Use Alsa'), label=_('Use Alsa'),
order=41, order=41,
tooltip=_('If checked, Linux client will try to use ALSA, otherwise Pulse will be used'), tooltip=_('If checked, Linux client will try to use ALSA, otherwise Pulse will be used'),
tab='Linux Client', tab='Linux Client',
stored_field_name='alsa',
) )
printerString = gui.TextField( lnx_printer_string = gui.TextField(
label=_('Printer string'), label=_('Printer string'),
order=43, order=43,
tooltip=_('If printer is checked, the printer string used with xfreerdp client'), tooltip=_('If printer is checked, the printer string used with xfreerdp client'),
tab='Linux Client', tab='Linux Client',
length=256, length=256,
stored_field_name='printerString',
) )
smartcardString = gui.TextField( lnx_smartcard_string = gui.TextField(
label=_('Smartcard string'), label=_('Smartcard string'),
order=44, order=44,
tooltip=_('If smartcard is checked, the smartcard string used with xfreerdp client'), tooltip=_('If smartcard is checked, the smartcard string used with xfreerdp client'),
tab='Linux Client', tab='Linux Client',
length=256, length=256,
stored_field_name='smartcardString',
) )
customParameters = gui.TextField( lnx_custom_parameters = gui.TextField(
label=_('Custom parameters'), label=_('Custom parameters'),
order=45, order=45,
tooltip=_( tooltip=_(
@ -295,17 +322,19 @@ class BaseRDPTransport(transports.Transport):
), ),
tab='Linux Client', tab='Linux Client',
length=256, length=256,
stored_field_name='customParameters',
) )
allowMacMSRDC = gui.CheckBoxField( mac_allow_msrdc = gui.CheckBoxField(
label=_('Allow Microsoft Rdp Client'), label=_('Allow Microsoft Rdp Client'),
order=50, order=50,
tooltip=_('If checked, allows use of Microsoft Remote Desktop Client. PASSWORD WILL BE PROMPTED!'), tooltip=_('If checked, allows use of Microsoft Remote Desktop Client. PASSWORD WILL BE PROMPTED!'),
tab='Mac OS X', tab='Mac OS X',
default=False, default=False,
stored_field_name='allowMacMSRDC',
) )
customParametersMAC = gui.TextField( mac_custom_parameters = gui.TextField(
label=_('Custom parameters'), label=_('Custom parameters'),
order=51, order=51,
tooltip=_( tooltip=_(
@ -313,22 +342,25 @@ class BaseRDPTransport(transports.Transport):
), ),
tab='Mac OS X', tab='Mac OS X',
length=256, length=256,
stored_field_name='customParametersMAC',
) )
customParametersWindows = gui.TextField( wnd_custom_parameters = gui.TextField(
label=_('Custom parameters'), label=_('Custom parameters'),
order=45, order=45,
tooltip=_('If not empty, extra parameters to include for Windows Client'), tooltip=_('If not empty, extra parameters to include for Windows Client'),
length=4096, length=4096,
lines=10, lines=10,
tab='Windows Client', tab='Windows Client',
stored_field_name='customParametersWindows',
) )
optimizeTeams = gui.CheckBoxField( wnd_optimize_teams = gui.CheckBoxField(
label=_('Optimize Teams'), label=_('Optimize Teams'),
order=46, order=46,
tooltip=_('If checked, Teams will be optimized (only works on Windows clients)'), tooltip=_('If checked, Teams will be optimized (only works on Windows clients)'),
tab='Windows Client', tab='Windows Client',
stored_field_name='optimizeTeams',
) )
def is_ip_allowed(self, userService: 'models.UserService', ip: str) -> bool: def is_ip_allowed(self, userService: 'models.UserService', ip: str) -> bool:
@ -340,7 +372,7 @@ class BaseRDPTransport(transports.Transport):
ready = self.cache.get(ip) ready = self.cache.get(ip)
if ready is None: if ready is None:
# Check again for ready # Check again for ready
if self.test_connectivity(userService, ip, self.rdpPort.num()) is True: if self.test_connectivity(userService, ip, self.rdp_port.num()) is True:
self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT) self.cache.put(ip, 'Y', READY_CACHE_TIMEOUT)
return True return True
self.cache.put(ip, 'N', READY_CACHE_TIMEOUT) self.cache.put(ip, 'N', READY_CACHE_TIMEOUT)
@ -360,8 +392,8 @@ class BaseRDPTransport(transports.Transport):
) -> types.connections.ConnectionData: ) -> types.connections.ConnectionData:
username: str = altUsername or user.get_username_for_auth() username: str = altUsername or user.get_username_for_auth()
if self.fixedName.value: if self.forced_username.value:
username = self.fixedName.value username = self.forced_username.value
proc = username.split('@') proc = username.split('@')
domain: str = '' domain: str = ''
@ -369,19 +401,19 @@ class BaseRDPTransport(transports.Transport):
domain = proc[1] domain = proc[1]
username = proc[0] username = proc[0]
if self.fixedPassword.value: if self.forced_password.value:
password = self.fixedPassword.value password = self.forced_password.value
azureAd = False azureAd = False
if self.fixedDomain.value != '': if self.forced_domain.value != '':
if self.fixedDomain.value.lower() == 'azuread': if self.forced_domain.value.lower() == 'azuread':
azureAd = True azureAd = True
else: else:
domain = self.fixedDomain.value domain = self.forced_domain.value
if self.useEmptyCreds.as_bool(): if self.force_empty_creds.as_bool():
username, password, domain = '', '', '' username, password, domain = '', '', ''
if self.withoutDomain.as_bool(): if self.force_no_domain.as_bool():
domain = '' domain = ''
if domain: # If has domain if domain: # If has domain
@ -403,7 +435,7 @@ class BaseRDPTransport(transports.Transport):
if azureAd: if azureAd:
username = 'AzureAD\\' + username username = 'AzureAD\\' + username
if self.optimizeTeams.as_bool(): if self.wnd_optimize_teams.as_bool():
password = '' # nosec password = '' # nosec
return types.connections.ConnectionData( return types.connections.ConnectionData(

View File

@ -70,50 +70,51 @@ class TRDPTransport(BaseRDPTransport):
tunnel = fields.tunnel_field() tunnel = fields.tunnel_field()
tunnelWait = fields.tunnel_runnel_wait() tunnel_wait = fields.tunnel_wait_time()
verifyCertificate = gui.CheckBoxField( verify_certificate = gui.CheckBoxField(
label=_('Force SSL certificate verification'), label=_('Force SSL certificate verification'),
order=23, order=23,
tooltip=_('If enabled, the certificate of tunnel server will be verified (recommended).'), tooltip=_('If enabled, the certificate of tunnel server will be verified (recommended).'),
default=False, default=False,
tab=types.ui.Tab.TUNNEL, tab=types.ui.Tab.TUNNEL,
stored_field_name='tunnelVerifyCert',
) )
useEmptyCreds = BaseRDPTransport.useEmptyCreds force_empty_creds = BaseRDPTransport.force_empty_creds
fixedName = BaseRDPTransport.fixedName forced_username = BaseRDPTransport.forced_username
fixedPassword = BaseRDPTransport.fixedPassword forced_password = BaseRDPTransport.forced_password
withoutDomain = BaseRDPTransport.withoutDomain force_no_domain = BaseRDPTransport.force_no_domain
fixedDomain = BaseRDPTransport.fixedDomain forced_domain = BaseRDPTransport.forced_domain
allowSmartcards = BaseRDPTransport.allowSmartcards allow_smartcards = BaseRDPTransport.allow_smartcards
allowPrinters = BaseRDPTransport.allowPrinters allow_printers = BaseRDPTransport.allow_printers
allowDrives = BaseRDPTransport.allowDrives allow_drives = BaseRDPTransport.allow_drives
enforceDrives = BaseRDPTransport.enforceDrives enforce_drives = BaseRDPTransport.enforce_drives
allowSerials = BaseRDPTransport.allowSerials allow_serial_ports = BaseRDPTransport.allow_serial_ports
allowClipboard = BaseRDPTransport.allowClipboard allow_clipboard = BaseRDPTransport.allow_clipboard
allowAudio = BaseRDPTransport.allowAudio allow_audio = BaseRDPTransport.allow_audio
allowWebcam = BaseRDPTransport.allowWebcam allow_webcam = BaseRDPTransport.allow_webcam
usbRedirection = BaseRDPTransport.usbRedirection allow_usb_redirection = BaseRDPTransport.allow_usb_redirection
wallpaper = BaseRDPTransport.wallpaper wallpaper = BaseRDPTransport.wallpaper
multimon = BaseRDPTransport.multimon multimon = BaseRDPTransport.multimon
aero = BaseRDPTransport.aero aero = BaseRDPTransport.aero
smooth = BaseRDPTransport.smooth smooth = BaseRDPTransport.smooth
showConnectionBar = BaseRDPTransport.showConnectionBar show_connection_bar = BaseRDPTransport.show_connection_bar
credssp = BaseRDPTransport.credssp credssp = BaseRDPTransport.credssp
rdpPort = BaseRDPTransport.rdpPort rdp_port = BaseRDPTransport.rdp_port
screenSize = BaseRDPTransport.screenSize screen_size = BaseRDPTransport.screen_size
colorDepth = BaseRDPTransport.colorDepth color_depth = BaseRDPTransport.color_depth
alsa = BaseRDPTransport.alsa lnx_alsa = BaseRDPTransport.lnx_alsa
multimedia = BaseRDPTransport.multimedia lnx_multimedia = BaseRDPTransport.lnx_multimedia
printerString = BaseRDPTransport.printerString lnx_printer_string = BaseRDPTransport.lnx_printer_string
smartcardString = BaseRDPTransport.smartcardString lnx_smartcard_string = BaseRDPTransport.lnx_smartcard_string
allowMacMSRDC = BaseRDPTransport.allowMacMSRDC mac_allow_msrdc = BaseRDPTransport.mac_allow_msrdc
customParameters = BaseRDPTransport.customParameters lnx_custom_parameters = BaseRDPTransport.lnx_custom_parameters
customParametersMAC = BaseRDPTransport.customParametersMAC mac_custom_parameters = BaseRDPTransport.mac_custom_parameters
customParametersWindows = BaseRDPTransport.customParametersWindows wnd_custom_parameters = BaseRDPTransport.wnd_custom_parameters
# optimizeTeams = BaseRDPTransport.optimizeTeams # optimizeTeams = BaseRDPTransport.optimizeTeams
def initialize(self, values: 'Module.ValuesType'): def initialize(self, values: 'Module.ValuesType'):
@ -139,13 +140,13 @@ class TRDPTransport(BaseRDPTransport):
# width, height = CommonPrefs.getWidthHeight(prefs) # width, height = CommonPrefs.getWidthHeight(prefs)
# depth = CommonPrefs.getDepth(prefs) # depth = CommonPrefs.getDepth(prefs)
width, height = self.screenSize.value.split('x') width, height = self.screen_size.value.split('x')
depth = self.colorDepth.value depth = self.color_depth.value
ticket = TicketStore.create_for_tunnel( ticket = TicketStore.create_for_tunnel(
userService=userService, userService=userService,
port=self.rdpPort.num(), port=self.rdp_port.num(),
validity=self.tunnelWait.num() + 60, # Ticket overtime validity=self.tunnel_wait.num() + 60, # Ticket overtime
) )
tunnelFields = fields.get_tunnel_from_field(self.tunnel) tunnelFields = fields.get_tunnel_from_field(self.tunnel)
@ -159,61 +160,61 @@ class TRDPTransport(BaseRDPTransport):
r.password = ci.password r.password = ci.password
r.domain = ci.domain r.domain = ci.domain
r.redirectPrinters = self.allowPrinters.as_bool() r.redirectPrinters = self.allow_printers.as_bool()
r.redirectSmartcards = self.allowSmartcards.as_bool() r.redirectSmartcards = self.allow_smartcards.as_bool()
r.redirectDrives = self.allowDrives.value r.redirectDrives = self.allow_drives.value
r.redirectSerials = self.allowSerials.as_bool() r.redirectSerials = self.allow_serial_ports.as_bool()
r.enableClipboard = self.allowClipboard.as_bool() r.enableClipboard = self.allow_clipboard.as_bool()
r.redirectAudio = self.allowAudio.as_bool() r.redirectAudio = self.allow_audio.as_bool()
r.redirectWebcam = self.allowWebcam.as_bool() r.redirectWebcam = self.allow_webcam.as_bool()
r.showWallpaper = self.wallpaper.as_bool() r.showWallpaper = self.wallpaper.as_bool()
r.multimon = self.multimon.as_bool() r.multimon = self.multimon.as_bool()
r.desktopComposition = self.aero.as_bool() r.desktopComposition = self.aero.as_bool()
r.smoothFonts = self.smooth.as_bool() r.smoothFonts = self.smooth.as_bool()
r.displayConnectionBar = self.showConnectionBar.as_bool() r.displayConnectionBar = self.show_connection_bar.as_bool()
r.enablecredsspsupport = self.credssp.as_bool() r.enablecredsspsupport = self.credssp.as_bool()
r.multimedia = self.multimedia.as_bool() r.multimedia = self.lnx_multimedia.as_bool()
r.alsa = self.alsa.as_bool() r.alsa = self.lnx_alsa.as_bool()
r.smartcardString = self.smartcardString.value r.smartcardString = self.lnx_smartcard_string.value
r.printerString = self.printerString.value r.printerString = self.lnx_printer_string.value
r.enforcedShares = self.enforceDrives.value r.enforcedShares = self.enforce_drives.value
r.redirectUSB = self.usbRedirection.value r.redirectUSB = self.allow_usb_redirection.value
r.optimizeTeams = self.optimizeTeams.as_bool() r.optimizeTeams = self.wnd_optimize_teams.as_bool()
sp: collections.abc.MutableMapping[str, typing.Any] = { sp: collections.abc.MutableMapping[str, typing.Any] = {
'tunHost': tunHost, 'tunHost': tunHost,
'tunPort': tunPort, 'tunPort': tunPort,
'tunWait': self.tunnelWait.num(), 'tunWait': self.tunnel_wait.num(),
'tunChk': self.verifyCertificate.as_bool(), 'tunChk': self.verify_certificate.as_bool(),
'ticket': ticket, 'ticket': ticket,
'password': ci.password, 'password': ci.password,
'this_server': request.build_absolute_uri('/'), 'this_server': request.build_absolute_uri('/'),
} }
if os.os == types.os.KnownOS.WINDOWS: if os.os == types.os.KnownOS.WINDOWS:
r.customParameters = self.customParametersWindows.value r.customParameters = self.wnd_custom_parameters.value
if ci.password: if ci.password:
r.password = '{password}' # nosec: password is not hardcoded r.password = '{password}' # nosec: password is not hardcoded
sp.update( sp.update(
{ {
'as_file': r.as_file, 'as_file': r.as_file,
'optimize_teams': self.optimizeTeams.as_bool(), 'optimize_teams': self.wnd_optimize_teams.as_bool(),
} }
) )
elif os.os == types.os.KnownOS.LINUX: elif os.os == types.os.KnownOS.LINUX:
r.customParameters = self.customParameters.value r.customParameters = self.lnx_custom_parameters.value
sp.update( sp.update(
{ {
'as_new_xfreerdp_params': r.as_new_xfreerdp_params, 'as_new_xfreerdp_params': r.as_new_xfreerdp_params,
} }
) )
elif os.os == types.os.KnownOS.MAC_OS: elif os.os == types.os.KnownOS.MAC_OS:
r.customParameters = self.customParametersMAC.value r.customParameters = self.mac_custom_parameters.value
sp.update( sp.update(
{ {
'as_new_xfreerdp_params': r.as_new_xfreerdp_params, 'as_new_xfreerdp_params': r.as_new_xfreerdp_params,
'as_file': r.as_file if self.allowMacMSRDC.as_bool() else '', 'as_file': r.as_file if self.mac_allow_msrdc.as_bool() else '',
'as_rdp_url': r.as_rdp_url if self.allowMacMSRDC.as_bool() else '', 'as_rdp_url': r.as_rdp_url if self.mac_allow_msrdc.as_bool() else '',
} }
) )
else: else:

View File

@ -66,7 +66,7 @@ class TSPICETransport(BaseSpiceTransport):
group = types.transports.Grouping.TUNNELED group = types.transports.Grouping.TUNNELED
tunnel = fields.tunnel_field() tunnel = fields.tunnel_field()
tunnelWait = fields.tunnel_runnel_wait() tunnelWait = fields.tunnel_wait_time()
verifyCertificate = gui.CheckBoxField( verifyCertificate = gui.CheckBoxField(
label=_('Force SSL certificate verification'), label=_('Force SSL certificate verification'),

View File

@ -68,7 +68,7 @@ class TX2GOTransport(BaseX2GOTransport):
group = types.transports.Grouping.TUNNELED group = types.transports.Grouping.TUNNELED
tunnel = fields.tunnel_field() tunnel = fields.tunnel_field()
tunnelWait = fields.tunnel_runnel_wait() tunnelWait = fields.tunnel_wait_time()
verifyCertificate = gui.CheckBoxField( verifyCertificate = gui.CheckBoxField(
label=_('Force SSL certificate verification'), label=_('Force SSL certificate verification'),