aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2014-11-03 12:47:16 +0100
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2014-11-03 12:47:47 +0100
commit831b1082ab352fd7e2696b8cee070ac03f79baf5 (patch)
tree61b47db6636929332b947e78a95e2f9689bdcf9e
parentecb6bd24f4fc69b4b4332630f07ef428c4f101e7 (diff)
downloadremote-logon-service-831b1082ab352fd7e2696b8cee070ac03f79baf5.tar.gz
remote-logon-service-831b1082ab352fd7e2696b8cee070ac03f79baf5.tar.bz2
remote-logon-service-831b1082ab352fd7e2696b8cee070ac03f79baf5.zip
Apply 03_x2go+rls.patch. Provide support for X2Go remote logins.
-rw-r--r--debian/changelog1
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/com.canonical.RemoteLogin.xml12
-rw-r--r--src/defines.h3
-rw-r--r--src/main.c1
-rw-r--r--src/server.c6
-rw-r--r--src/x2go-server.c227
-rw-r--r--src/x2go-server.h59
-rwxr-xr-xtests/slmock15
10 files changed, 322 insertions, 5 deletions
diff --git a/debian/changelog b/debian/changelog
index 4dadca3..d813719 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,7 @@ remote-login-service-x2go (1.0.0.1-0x2go1) UNRELEASED; urgency=medium
GLib versions.
- Apply 02_server-name.patch. Provide support for non-Canonical
UCCS servers.
+ - Apply 03_x2go+rls.patch. Provide support for X2Go remote logins.
* Add SERVER_NAME env var support.
* Add X2Go support to RLS.
* Provide via ppa:x2go/ppa and ppa:x2go/stable on Launchpad.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ed4237c..12b4fa6 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -3,5 +3,6 @@ src/server.c
src/remote-login.c
src/rdp-server.c
src/citrix-server.c
+src/x2go-server.c
src/main.c
src/uccs-server.c
diff --git a/src/Makefile.am b/src/Makefile.am
index a402870..b5f5d5b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,6 +36,8 @@ libservers_la_SOURCES = \
citrix-server.h \
rdp-server.c \
rdp-server.h \
+ x2go-server.c \
+ x2go-server.h \
uccs-server.c \
uccs-server.h \
defines.h \
diff --git a/src/com.canonical.RemoteLogin.xml b/src/com.canonical.RemoteLogin.xml
index 0fec355..f0d8cb1 100644
--- a/src/com.canonical.RemoteLogin.xml
+++ b/src/com.canonical.RemoteLogin.xml
@@ -2,19 +2,21 @@
<node name="/">
<interface name="com.canonical.RemoteLogin">
<!-- SERVER LIST DOCS - it's in a few places :-)
- s: server type: "ica", "freerdp", "uccs"
+ s: server type: "ica", "freerdp", "x2go", "uccs"
s: server name
s: server uri
b: last used server
a(sbva{sv}): properties for the server
- s: type: "username", "password", "domain", "email"
+ s: type: "username", "password", "domain", "email", "sessiontype"
b: required
v: default value
- a{sv}: properties for the value, currently only used for domains
- that have a list of possible domains
+ a{sv}: properties for the value
+ for value 'domain': a list of possible domains (ica, freerdp)
"domains": a(s)
- and domains that are read only
+ for value 'domain': a list of domains that are read only
"read-only": b
+ for value 'sessiontype': TODO -> a subset of session profile parameters...
+ "nothing-yet": s
a(si): applications pinned for the server
s: ID of the application (desktop file)
i: position the application is pinned in
diff --git a/src/defines.h b/src/defines.h
index e815ca5..e205d2c 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -34,6 +34,7 @@
#define CONFIG_SERVER_TYPE "Type"
#define CONFIG_SERVER_TYPE_RDP "RDP"
#define CONFIG_SERVER_TYPE_ICA "ICA"
+#define CONFIG_SERVER_TYPE_X2GO "X2GO"
#define CONFIG_SERVER_TYPE_UCCS "UCCS"
#define JSON_PROTOCOL "Protocol"
@@ -43,5 +44,7 @@
#define JSON_PASSWORD "Password"
#define JSON_DOMAIN_REQ "DomainRequired"
#define JSON_DOMAIN "WindowsDomain"
+#define JSON_SESSIONTYPE "SessionType"
+#define JSON_SESSIONTYPE_REQ "SessionTypeRequired"
#endif /* __DEFINES_H__ */
diff --git a/src/main.c b/src/main.c
index c4801ba..74e09e0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -33,6 +33,7 @@
#include "rdp-server.h"
#include "citrix-server.h"
#include "uccs-server.h"
+#include "x2go-server.h"
#include "crypt.h"
gint server_list_to_array (GVariantBuilder * builder, GList * items);
diff --git a/src/server.c b/src/server.c
index 2f36898..551aa99 100644
--- a/src/server.c
+++ b/src/server.c
@@ -25,6 +25,7 @@
#include "citrix-server.h"
#include "rdp-server.h"
#include "uccs-server.h"
+#include "x2go-server.h"
static void server_class_init (ServerClass *klass);
static void server_init (Server *self);
@@ -162,6 +163,9 @@ server_new_from_json (JsonObject * object)
else if (g_strcmp0(proto, "freerdp") == 0 || g_strcmp0(proto, "rdp") == 0 || g_strcmp0(proto, "RDP") == 0 || g_strcmp0(proto, "FreeRDP") == 0) {
newserver = rdp_server_new_from_json(object);
}
+ else if (g_strcmp0(proto, "x2go") == 0 || g_strcmp0(proto, "X2go") == 0 || g_strcmp0(proto, "X2Go") == 0 || g_strcmp0(proto, "X2GO") == 0 || g_strcmp0(proto, "x2GO") == 0 || g_strcmp0(proto, "x2gO") == 0) {
+ newserver = x2go_server_new_from_json(object);
+ }
return newserver;
}
@@ -184,6 +188,8 @@ server_get_variant (Server * server)
g_variant_builder_add_value(&tuple, g_variant_new_string("freerdp"));
} else if (IS_UCCS_SERVER(server)) {
g_variant_builder_add_value(&tuple, g_variant_new_string("uccs"));
+ } else if (IS_X2GO_SERVER(server)) {
+ g_variant_builder_add_value(&tuple, g_variant_new_string("x2go"));
} else {
g_assert_not_reached();
}
diff --git a/src/x2go-server.c b/src/x2go-server.c
new file mode 100644
index 0000000..fb0935e
--- /dev/null
+++ b/src/x2go-server.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright © 2012 Canonical Ltd.
+ * Copyright © 2013 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ted Gould <ted@canonical.com>
+ * Modified for X2Go: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/mman.h>
+
+#include <glib/gi18n.h>
+
+#include <string.h>
+
+#include "x2go-server.h"
+#include "defines.h"
+
+static void x2go_server_class_init (X2GoServerClass *klass);
+static void x2go_server_init (X2GoServer *self);
+static void x2go_server_dispose (GObject *object);
+static void x2go_server_finalize (GObject *object);
+static GVariant * get_properties (Server * server);
+
+G_DEFINE_TYPE (X2GoServer, x2go_server, SERVER_TYPE);
+
+static void
+x2go_server_class_init (X2GoServerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = x2go_server_dispose;
+ object_class->finalize = x2go_server_finalize;
+
+ ServerClass * server_class = SERVER_CLASS(klass);
+
+ server_class->get_properties = get_properties;
+
+ return;
+}
+
+static void
+x2go_server_init (X2GoServer *self)
+{
+ self->username = NULL;
+ self->password = NULL;
+ self->sessiontype = NULL;
+ self->sessiontype_required = FALSE;
+
+ return;
+}
+
+static void
+x2go_server_dispose (GObject *object)
+{
+
+ G_OBJECT_CLASS (x2go_server_parent_class)->dispose (object);
+ return;
+}
+
+/* Unlocks the memory before freeing */
+static void
+password_clear (gpointer data)
+{
+ char * pass = (char *)data;
+ munlock(pass, strlen(pass));
+ g_free(pass);
+ return;
+}
+
+static void
+x2go_server_finalize (GObject *object)
+{
+ X2GoServer * server = X2GO_SERVER(object);
+
+ g_clear_pointer(&server->username, g_free);
+ g_clear_pointer(&server->password, password_clear);
+ g_clear_pointer(&server->sessiontype, g_free);
+
+ G_OBJECT_CLASS (x2go_server_parent_class)->finalize (object);
+ return;
+}
+
+static GVariant *
+get_properties (Server * server)
+{
+ X2GoServer * rserver = X2GO_SERVER(server);
+
+ GVariantBuilder propbuilder;
+ g_variant_builder_init(&propbuilder, G_VARIANT_TYPE_ARRAY);
+
+ GVariantBuilder namebuilder;
+ g_variant_builder_init(&namebuilder, G_VARIANT_TYPE_TUPLE);
+ g_variant_builder_add_value(&namebuilder, g_variant_new_string("username"));
+ g_variant_builder_add_value(&namebuilder, g_variant_new_boolean(TRUE));
+ if (rserver->username == NULL) {
+ g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string("")));
+ } else {
+ g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(rserver->username)));
+ }
+ g_variant_builder_add_value(&namebuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
+ g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&namebuilder));
+
+ GVariantBuilder passbuilder;
+ g_variant_builder_init(&passbuilder, G_VARIANT_TYPE_TUPLE);
+ g_variant_builder_add_value(&passbuilder, g_variant_new_string("password"));
+ g_variant_builder_add_value(&passbuilder, g_variant_new_boolean(TRUE));
+ if (rserver->password == NULL) {
+ g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string("")));
+ } else {
+ g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(rserver->password)));
+ }
+ g_variant_builder_add_value(&passbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
+ g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&passbuilder));
+
+ GVariantBuilder sessiontypebuilder;
+ g_variant_builder_init(&sessiontypebuilder, G_VARIANT_TYPE_TUPLE);
+ g_variant_builder_add_value(&sessiontypebuilder, g_variant_new_string("x2gosession"));
+ g_variant_builder_add_value(&sessiontypebuilder, g_variant_new_boolean(rserver->sessiontype_required));
+ if (rserver->sessiontype == NULL) {
+ g_variant_builder_add_value(&sessiontypebuilder, g_variant_new_variant(g_variant_new_string("")));
+ } else {
+ g_variant_builder_add_value(&sessiontypebuilder, g_variant_new_variant(g_variant_new_string(rserver->sessiontype)));
+ }
+ g_variant_builder_add_value(&sessiontypebuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
+ g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&sessiontypebuilder));
+
+ return g_variant_builder_end(&propbuilder);
+}
+
+Server *
+x2go_server_new_from_keyfile (GKeyFile * keyfile, const gchar * groupname)
+{
+ g_return_val_if_fail(keyfile != NULL, NULL); /* NOTE: No way to check if that's really a keyfile :-( */
+ g_return_val_if_fail(groupname != NULL, NULL);
+
+ if (!g_key_file_has_group(keyfile, groupname)) {
+ g_warning("Server specified but group '%s' was not found", groupname);
+ return NULL;
+ }
+
+ X2GoServer * server = g_object_new(X2GO_SERVER_TYPE, NULL);
+
+ if (g_key_file_has_key(keyfile, groupname, CONFIG_SERVER_NAME, NULL)) {
+ gchar * keyname = g_key_file_get_string(keyfile, groupname, CONFIG_SERVER_NAME, NULL);
+ server->parent.name = g_strdup(_(keyname));
+ g_free(keyname);
+ }
+
+ if (g_key_file_has_key(keyfile, groupname, CONFIG_SERVER_URI, NULL)) {
+ server->parent.uri = g_key_file_get_string(keyfile, groupname, CONFIG_SERVER_URI, NULL);
+ }
+
+ return SERVER(server);
+}
+
+/* Build the X2Go server from information in the JSON object */
+Server *
+x2go_server_new_from_json (JsonObject * object)
+{
+ X2GoServer * server = g_object_new(X2GO_SERVER_TYPE, NULL);
+
+ if (json_object_has_member(object, JSON_SERVER_NAME)) {
+ JsonNode * node = json_object_get_member(object, JSON_SERVER_NAME);
+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
+ const gchar * name = json_node_get_string(node);
+ server->parent.name = g_strdup(name);
+ }
+ }
+
+ if (json_object_has_member(object, JSON_URI)) {
+ JsonNode * node = json_object_get_member(object, JSON_URI);
+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
+ const gchar * uri = json_node_get_string(node);
+ server->parent.uri = g_strdup(uri);
+ }
+ }
+
+ if (json_object_has_member(object, JSON_USERNAME)) {
+ JsonNode * node = json_object_get_member(object, JSON_USERNAME);
+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
+ const gchar * username = json_node_get_string(node);
+ server->username = g_strdup(username);
+ }
+ }
+
+ if (json_object_has_member(object, JSON_PASSWORD)) {
+ JsonNode * node = json_object_get_member(object, JSON_PASSWORD);
+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
+ const gchar * password = json_node_get_string(node);
+ server->password = g_strdup(password);
+ mlock(server->password, strlen(server->password));
+ }
+ }
+
+ if (json_object_has_member(object, JSON_SESSIONTYPE)) {
+ JsonNode * node = json_object_get_member(object, JSON_SESSIONTYPE);
+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
+ const gchar * sessiontype = json_node_get_string(node);
+ server->sessiontype = g_strdup(sessiontype);
+ }
+ }
+
+ if (json_object_has_member(object, JSON_SESSIONTYPE_REQ)) {
+ JsonNode * node = json_object_get_member(object, JSON_SESSIONTYPE_REQ);
+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_BOOLEAN) {
+ server->sessiontype_required = json_node_get_boolean(node);
+ }
+ }
+
+ return SERVER(server);
+}
diff --git a/src/x2go-server.h b/src/x2go-server.h
new file mode 100644
index 0000000..b492a2c
--- /dev/null
+++ b/src/x2go-server.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2012 Canonical Ltd.
+ * Copyright © 2013 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ted Gould <ted@canonical.com>
+ * Modified for X2Go: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+ */
+
+#ifndef __X2GO_SERVER_H__
+#define __X2GO_SERVER_H__
+
+#include <glib-object.h>
+#include <json-glib/json-glib.h>
+#include "server.h"
+
+G_BEGIN_DECLS
+
+#define X2GO_SERVER_TYPE (x2go_server_get_type ())
+#define X2GO_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), X2GO_SERVER_TYPE, X2GoServer))
+#define X2GO_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), X2GO_SERVER_TYPE, X2GoServerClass))
+#define IS_X2GO_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), X2GO_SERVER_TYPE))
+#define IS_X2GO_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), X2GO_SERVER_TYPE))
+#define X2GO_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), X2GO_SERVER_TYPE, X2GoServerClass))
+
+typedef struct _X2GoServer X2GoServer;
+typedef struct _X2GoServerClass X2GoServerClass;
+
+struct _X2GoServerClass {
+ ServerClass parent_class;
+};
+
+struct _X2GoServer {
+ Server parent;
+
+ gchar * username;
+ gchar * password;
+ gchar * sessiontype;
+ gboolean sessiontype_required;
+};
+
+GType x2go_server_get_type (void);
+Server * x2go_server_new_from_keyfile (GKeyFile * keyfile, const gchar * name);
+Server * x2go_server_new_from_json (JsonObject * object);
+
+G_END_DECLS
+
+#endif
diff --git a/tests/slmock b/tests/slmock
index 59c5174..b3b5019 100755
--- a/tests/slmock
+++ b/tests/slmock
@@ -78,6 +78,20 @@ def freerdp(email):
ms.set_default(ts1.Name)
print(ms.toJson())
+def x2go(email):
+ ms = ManagementServer("http://x2go.intern", "X2GoSessionBroker")
+ ts1 = TerminalServer("10.0.2.11", "X2Go Server 1", "x2go", False,
+ "foo")
+ ts2 = TerminalServer("10.0.2.12", "X2Go Server 2", "x2go", False,
+ "bar")
+ ts3 = TerminalServer("10.0.2.13", "X2Go Server 3", "x2go", False,
+ "foobar")
+ ms.add_terminal_server(ts1)
+ ms.add_terminal_server(ts2)
+ ms.add_terminal_server(ts3)
+ ms.set_default(ts1.Name)
+ print(ms.toJson())
+
def print_error(text):
print("{ \"Error\": \"%s\" }" % text)
@@ -201,6 +215,7 @@ emailaddrs = {"b" : big, #lots of domains/servers
"d" : defaults, #for easy testing of default ts
"e" : error,
"f" : freerdp,
+ "x" : x2go,
"g" : garbage,
"m" : missing_fields, #json missing some fields
"r" : random_string,