Skip to content

Commit

Permalink
GUACAMOLE-261: Implement Spice protocol support.
Browse files Browse the repository at this point in the history
  • Loading branch information
necouchman committed Sep 20, 2022
1 parent b20afa2 commit c6263a2
Show file tree
Hide file tree
Showing 67 changed files with 9,876 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ DIST_SUBDIRS = \
src/pulse \
src/protocols/kubernetes \
src/protocols/rdp \
src/protocols/spice \
src/protocols/ssh \
src/protocols/telnet \
src/protocols/vnc
Expand Down Expand Up @@ -65,6 +66,10 @@ if ENABLE_RDP
SUBDIRS += src/protocols/rdp
endif

if ENABLE_SPICE
SUBDIRS += src/protocols/spice
endif

if ENABLE_SSH
SUBDIRS += src/protocols/ssh
endif
Expand Down
24 changes: 24 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,27 @@ then

fi

#
# spice-glib
#

have_spice_glib=disabled
AC_ARG_WITH([spice],
[AS_HELP_STRING([--with-spice],
[support SPICE @<:@default=check@:>@])],
[],
[with_spice=check])

if test "x$with_spice" != "xno"
then
have_spice_glib=yes
PKG_CHECK_MODULES([GLIB2], [glib-2.0],, [have_spice_glib=no])
PKG_CHECK_MODULES([SPICE], [spice-client-glib-2.0],, [have_spice_glib=no])
fi

AM_CONDITIONAL([ENABLE_SPICE], [test "x${have_spice_glib}" = "xyes"])
AC_SUBST(SPICE_LIBS)


#
# FreeRDP 2 (libfreerdp2, libfreerdp-client2, and libwinpr2)
Expand Down Expand Up @@ -1188,6 +1209,7 @@ AC_CONFIG_FILES([Makefile
src/protocols/kubernetes/tests/Makefile
src/protocols/rdp/Makefile
src/protocols/rdp/tests/Makefile
src/protocols/spice/Makefile
src/protocols/ssh/Makefile
src/protocols/telnet/Makefile
src/protocols/vnc/Makefile])
Expand All @@ -1199,6 +1221,7 @@ AC_OUTPUT

AM_COND_IF([ENABLE_KUBERNETES], [build_kubernetes=yes], [build_kubernetes=no])
AM_COND_IF([ENABLE_RDP], [build_rdp=yes], [build_rdp=no])
AM_COND_IF([ENABLE_SPICE], [build_spice=yes], [build_spice=no])
AM_COND_IF([ENABLE_SSH], [build_ssh=yes], [build_ssh=no])
AM_COND_IF([ENABLE_TELNET], [build_telnet=yes], [build_telnet=no])
AM_COND_IF([ENABLE_VNC], [build_vnc=yes], [build_vnc=no])
Expand Down Expand Up @@ -1260,6 +1283,7 @@ $PACKAGE_NAME version $PACKAGE_VERSION

Kubernetes .... ${build_kubernetes}
RDP ........... ${build_rdp}
SPICE ......... ${build_spice}
SSH ........... ${build_ssh}
Telnet ........ ${build_telnet}
VNC ........... ${build_vnc}
Expand Down
139 changes: 139 additions & 0 deletions src/protocols/spice/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# NOTE: Parts of this file (Makefile.am) are automatically transcluded verbatim
# into Makefile.in. Though the build system (GNU Autotools) automatically adds
# its own license boilerplate to the generated Makefile.in, that boilerplate
# does not apply to the transcluded portions of Makefile.am which are licensed
# to you by the ASF under the Apache License, Version 2.0, as described above.
#

AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4

lib_LTLIBRARIES = libguac-client-spice.la

nodist_libguac_client_spice_la_SOURCES = \
_generated_keymaps.c

libguac_client_spice_la_SOURCES = \
argv.c \
auth.c \
channels/audio.c \
channels/clipboard.c \
channels/cursor.c \
channels/display.c \
channels/file.c \
channels/file-download.c \
channels/file-ls.c \
channels/file-upload.c \
client.c \
decompose.c \
input.c \
keyboard.c \
keymap.c \
log.c \
settings.c \
spice.c \
user.c

noinst_HEADERS = \
argv.h \
auth.h \
channels/audio.h \
channels/clipboard.h \
channels/cursor.h \
channels/display.h \
channels/file.h \
channels/file-download.h \
channels/file-ls.h \
channels/file-upload.h \
client.h \
decompose.h \
input.h \
keyboard.h \
keymap.h \
log.h \
settings.h \
spice.h \
user.h

libguac_client_spice_la_CFLAGS = \
-Werror -Wall -pedantic -Iinclude \
@COMMON_INCLUDE@ \
@COMMON_SSH_INCLUDE@ \
@LIBGUAC_INCLUDE@ \
@GLIB2_CFLAGS@ \
@SPICE_CFLAGS@

libguac_client_spice_la_LDFLAGS = \
-version-info 0:0:0 \
@CAIRO_LIBS@ \
@GLIB2_LIBS@ \
@SPICE_LIBS@

libguac_client_spice_la_LIBADD = \
@COMMON_LTLIB@ \
@LIBGUAC_LTLIB@

# Optional SFTP support
if ENABLE_COMMON_SSH
libguac_client_spice_la_SOURCES += sftp.c
noinst_HEADERS += sftp.h
libguac_client_spice_la_LIBADD += @COMMON_SSH_LTLIB@
endif

#
# Autogenerated keymaps and channel wrapper functions
#

CLEANFILES = \
_generated_keymaps.c

BUILT_SOURCES = \
_generated_keymaps.c

spice_keymaps = \
$(srcdir)/keymaps/base.keymap \
$(srcdir)/keymaps/failsafe.keymap \
$(srcdir)/keymaps/de_de_qwertz.keymap \
$(srcdir)/keymaps/de_ch_qwertz.keymap \
$(srcdir)/keymaps/en_gb_qwerty.keymap \
$(srcdir)/keymaps/en_us_qwerty.keymap \
$(srcdir)/keymaps/es_es_qwerty.keymap \
$(srcdir)/keymaps/es_latam_qwerty.keymap \
$(srcdir)/keymaps/fr_be_azerty.keymap \
$(srcdir)/keymaps/fr_ca_qwerty.keymap \
$(srcdir)/keymaps/fr_ch_qwertz.keymap \
$(srcdir)/keymaps/fr_fr_azerty.keymap \
$(srcdir)/keymaps/hu_hu_qwertz.keymap \
$(srcdir)/keymaps/it_it_qwerty.keymap \
$(srcdir)/keymaps/ja_jp_qwerty.keymap \
$(srcdir)/keymaps/no_no_qwerty.keymap \
$(srcdir)/keymaps/pl_pl_qwerty.keymap \
$(srcdir)/keymaps/pt_br_qwerty.keymap \
$(srcdir)/keymaps/sv_se_qwerty.keymap \
$(srcdir)/keymaps/da_dk_qwerty.keymap \
$(srcdir)/keymaps/tr_tr_qwerty.keymap

_generated_keymaps.c: $(spice_keymaps) $(srcdir)/keymaps/generate.pl
$(AM_V_GEN) $(srcdir)/keymaps/generate.pl $(spice_keymaps)

EXTRA_DIST = \
$(spice_keymaps) \
keymaps/generate.pl
53 changes: 53 additions & 0 deletions src/protocols/spice/argv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#include "config.h"
#include "argv.h"
#include "spice.h"

#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/user.h>

#include <pthread.h>
#include <stdlib.h>
#include <string.h>

int guac_spice_argv_callback(guac_user* user, const char* mimetype,
const char* name, const char* value, void* data) {

guac_client* client = user->client;
guac_spice_client* spice_client = (guac_spice_client*) client->data;
guac_spice_settings* settings = spice_client->settings;

/* Update username */
if (strcmp(name, GUAC_SPICE_ARGV_USERNAME) == 0) {
free(settings->username);
settings->username = strdup(value);
}

/* Update password */
else if (strcmp(name, GUAC_SPICE_ARGV_PASSWORD) == 0) {
free(settings->password);
settings->password = strdup(value);
}

return 0;

}
47 changes: 47 additions & 0 deletions src/protocols/spice/argv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#ifndef GUAC_SPICE_ARGV_H
#define GUAC_SPICE_ARGV_H

#include "config.h"

#include <guacamole/argv.h>
#include <guacamole/user.h>

/**
* Handles a received argument value from a Guacamole "argv" instruction,
* updating the given connection parameter.
*/
guac_argv_callback guac_spice_argv_callback;

/**
* The name of the parameter Guacamole will use to specify/update the username
* for the Spice connection.
*/
#define GUAC_SPICE_ARGV_USERNAME "username"

/**
* The name of the parameter Guacamole will use to specify/update the password
* for the Spice connection.
*/
#define GUAC_SPICE_ARGV_PASSWORD "password"

#endif /* GUAC_SPICE_ARGV_H */

71 changes: 71 additions & 0 deletions src/protocols/spice/auth.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#include "config.h"

#include "argv.h"
#include "auth.h"
#include "spice.h"

#include <guacamole/argv.h>
#include <guacamole/client.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/string.h>

#include <glib-unix.h>
#include <pthread.h>
#include <string.h>

gboolean guac_spice_get_credentials(guac_client* client) {

guac_spice_client* spice_client = ((guac_spice_client*) client->data);
guac_spice_settings* settings = spice_client->settings;

char* params[3] = {NULL};
int i = 0;

/* Check if username is not provided. */
if (settings->username == NULL) {
guac_argv_register(GUAC_SPICE_ARGV_USERNAME, guac_spice_argv_callback, NULL, 0);
params[i] = GUAC_SPICE_ARGV_USERNAME;
i++;
}

/* Check if password is not provided. */
if (settings->password == NULL) {
guac_argv_register(GUAC_SPICE_ARGV_PASSWORD, guac_spice_argv_callback, NULL, 0);
params[i] = GUAC_SPICE_ARGV_PASSWORD;
i++;
}

params[i] = NULL;

/* If we have empty parameters, request them and await response. */
if (i > 0) {
guac_client_owner_send_required(client, (const char**) params);
guac_argv_await((const char**) params);
return true;
}

guac_client_log(client, GUAC_LOG_DEBUG,
"Unable to retrieve any credentials from the user.");
return false;

}
Loading

0 comments on commit c6263a2

Please sign in to comment.