From 787f67c5c953512b78f10d3e2fca9fde0175d4fa Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Thu, 20 Jul 2023 02:52:09 +0200 Subject: src/: add rda_protocol.{c,h} for generic remote protocol support. --- src/rda_protocol.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/rda_protocol.h | 58 +++++++++++++++ 2 files changed, 261 insertions(+) create mode 100644 src/rda_protocol.c create mode 100644 src/rda_protocol.h diff --git a/src/rda_protocol.c b/src/rda_protocol.c new file mode 100644 index 0000000..91a0f2c --- /dev/null +++ b/src/rda_protocol.c @@ -0,0 +1,203 @@ +/* -*- Mode: C; c-set-style: linux indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* rda_protocol.c - Generic protocol support for remote sessions + + Copyright (C) 2023 Mihai Moldovan + All rights reserved. + + The RDA Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The RDA Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include +#include +#include + +static guint supported_protos[RDA_PROTOCOL_MAX] = { }; +static gboolean supported_protos_init = FALSE; + +rda_protocol_t +rda_protocol = RDA_PROTOCOL_MAX; + +guint +rda_get_protocol(void) +{ + if (RDA_PROTOCOL_MAX == rda_protocol) + { + rda_init(); + } + + return rda_protocol; +} + +static const gchar* +rda_protocol_name_nx(void) +{ + return _("NX"); +} + +static const gchar* +rda_protocol_name_kdrive(void) +{ + return _("KDrive"); +} + +static const gchar* +rda_protocol_name_rdp(void) +{ + return _("RDP"); +} + +static const gchar* +rda_protocol_name_vnc(void) +{ + return _("VNC"); +} + +gchar* +rda_get_protocol_name (void) +{ + if (RDA_PROTOCOL_MAX == rda_protocol) + rda_init(); + + gchar* rda_protocol_name; + + switch(rda_protocol) { + + case RDA_PROTOCOL_NONE: + rda_protocol_name = g_strdup(_("local")); + break; + + case RDA_PROTOCOL_NX: + rda_protocol_name = g_strdup(rda_protocol_name_nx()); + break; + + case RDA_PROTOCOL_KDRIVE: + rda_protocol_name = g_strdup(rda_protocol_name_kdrive()); + break; + + case RDA_PROTOCOL_RDP: + rda_protocol_name = g_strdup(rda_protocol_name_rdp()); + break; + + case RDA_PROTOCOL_VNC: + rda_protocol_name = g_strdup(rda_protocol_name_vnc()); + break; + + case RDA_PROTOCOL_UNKNOWN: + rda_protocol_name = g_strdup(_("unknown")); + + default: + rda_protocol_name = g_strdup(""); + + } + + /* + * Moving g_strdup() down here might sound tempting, but don't do + * that. + * + * Even though, at the time of writing this comment, all functions + * used in here actually return a string literal (and as such, a + * "const gchar*"), this may not be true forever and it's too easy + * to leak memory by copying an already heap-allocated string. + */ + return rda_protocol_name; +} + +static void +init_supported_protos(void) +{ + if (!(supported_protos_init)) + { + /* Initialize the list. */ +#define merge_arr(name) \ + do \ + { \ + for (gsize i = 0; i < rda_supported_protocols_ ## name ## _len; ++i) \ + { \ + supported_protos[rda_supported_protocols_ ## name [i]] = TRUE; \ + } \ + } \ + while (0) + +#ifdef WITH_REMOTE_AWARENESS_X2GO + merge_arr(x2go); +#endif + +#ifdef WITH_REMOTE_AWARENESS_OGON + merge_arr(ogon); +#endif + +#undef merge_arr + supported_protos_init = TRUE; + } +} + +GList* +rda_supported_protocols(void) +{ + GList *proto_list = NULL; + + init_supported_protos(); + + for (gsize i = 0; i < RDA_PROTOCOL_MAX; ++i) + { + if (supported_protos[i]) + { + proto_list = g_list_append (proto_list, GUINT_TO_POINTER(i)); + } + } + + return proto_list; +} + +GList* +rda_supported_protocols_by_name(void) +{ + GList *proto_list_by_name = NULL; + + init_supported_protos(); + + for (gsize i = 0; i < RDA_PROTOCOL_MAX; ++i) + { + if (supported_protos[i]) + { + switch (i) + { + case RDA_PROTOCOL_NX: + proto_list_by_name = g_list_append (proto_list_by_name, g_strdup(rda_protocol_name_nx())); + break; + + case RDA_PROTOCOL_KDRIVE: + proto_list_by_name = g_list_append (proto_list_by_name, g_strdup(rda_protocol_name_kdrive())); + break; + + case RDA_PROTOCOL_RDP: + proto_list_by_name = g_list_append (proto_list_by_name, g_strdup(rda_protocol_name_rdp())); + break; + + case RDA_PROTOCOL_VNC: + proto_list_by_name = g_list_append (proto_list_by_name, g_strdup(rda_protocol_name_vnc())); + break; + } + } + } + + return proto_list_by_name; +} diff --git a/src/rda_protocol.h b/src/rda_protocol.h new file mode 100644 index 0000000..982b916 --- /dev/null +++ b/src/rda_protocol.h @@ -0,0 +1,58 @@ +/* -*- Mode: C; c-set-style: linux indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* rda_protocol.h - Generic protocol support for remote sessions + + Copyright (C) 2023 Mihai Moldovan + All rights reserved. + + The RDA Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The RDA Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef RDA_PROTOCOL_H +#define RDA_PROTOCOL_H + +#include + +G_BEGIN_DECLS + +typedef enum { + RDA_PROTOCOL_UNKNOWN = 0, + RDA_PROTOCOL_NONE, + RDA_PROTOCOL_VNC, + RDA_PROTOCOL_RDP, + RDA_PROTOCOL_NX, + RDA_PROTOCOL_KDRIVE, + RDA_PROTOCOL_MAX, +} rda_protocol_t; + +extern rda_protocol_t +rda_protocol; + +guint +rda_get_protocol(void); + +gchar* +rda_get_protocol_name(void); + +GList* +rda_supported_protocols(void); + +GList* +rda_supported_protocols_by_name(void); + +G_END_DECLS + +#endif /* RDA_PROTOCOL_H */ -- cgit v1.2.3 From eb3af447a30bbcdf4e71c6c5be9f45fdd178cfd7 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Fri, 21 Jul 2023 02:28:05 +0200 Subject: src/: add rda_util.{c,h} for miscellaneous utilities. --- src/rda_util.c | 27 +++++++++++++++++++++++++++ src/rda_util.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/rda_util.c create mode 100644 src/rda_util.h diff --git a/src/rda_util.c b/src/rda_util.c new file mode 100644 index 0000000..6ffa54f --- /dev/null +++ b/src/rda_util.c @@ -0,0 +1,27 @@ +/* -*- Mode: C; c-set-style: linux indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* rda_util.c - Miscellaneous helpers + + Copyright (C) 2023 Mihai Moldovan + All rights reserved. + + The RDA Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The RDA Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include diff --git a/src/rda_util.h b/src/rda_util.h new file mode 100644 index 0000000..bfa0edb --- /dev/null +++ b/src/rda_util.h @@ -0,0 +1,35 @@ +/* -*- Mode: C; c-set-style: linux indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* rda_util.h - Miscellaneous helpers + + Copyright (C) 2023 Mihai Moldovan + All rights reserved. + + The RDA Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The RDA Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef RDA_UTIL_H +#define RDA_UTIL_H + +#include + +G_BEGIN_DECLS + +#define static_arr_size(arr) (sizeof(arr) / sizeof(*arr)) + +G_END_DECLS + +#endif /* RDA_UTIL_H */ -- cgit v1.2.3 From fa330e8b9844e838fa8a8e1d01ab9d72d61e6bce Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Thu, 20 Jul 2023 02:53:47 +0200 Subject: src/rda_ogon.{c,h}: add generic remote protocol support. Ogon only supports RDP, so expose only that. --- src/rda_ogon.c | 9 +++++++++ src/rda_ogon.h | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/src/rda_ogon.c b/src/rda_ogon.c index 95f4f11..e4dc7d2 100644 --- a/src/rda_ogon.c +++ b/src/rda_ogon.c @@ -25,9 +25,17 @@ #include #include +#include +#include +#include #ifdef WITH_REMOTE_AWARENESS_OGON +const rda_protocol_t +rda_supported_protocols_ogon[] = { RDA_PROTOCOL_RDP }; +const gsize +rda_supported_protocols_ogon_len = static_arr_size(rda_supported_protocols_ogon); + gboolean rda_session_is_ogon (void) { @@ -37,6 +45,7 @@ rda_session_is_ogon (void) if (g_getenv("OGON_SID")) { remote_technology = REMOTE_TECHNOLOGY_OGON; + rda_protocol = RDA_PROTOCOL_RDP; return TRUE; } diff --git a/src/rda_ogon.h b/src/rda_ogon.h index 744d459..4959563 100644 --- a/src/rda_ogon.h +++ b/src/rda_ogon.h @@ -27,9 +27,15 @@ #include #include +#include #ifdef WITH_REMOTE_AWARENESS_OGON +extern const rda_protocol_t +rda_supported_protocols_ogon[]; +extern const gsize +rda_supported_protocols_ogon_len; + gboolean rda_session_is_ogon (void); -- cgit v1.2.3 From 685e6c3f471c226b43464212238731c7a86dbe99 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Thu, 20 Jul 2023 02:54:58 +0200 Subject: src/rda_x2go.{c,h}: add generic protocol support. X2Go supports both NX and KDrive sessions, so parse the session ID (X2GO_SESSION) to find out what protocol the session uses. --- src/rda_x2go.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/rda_x2go.h | 6 ++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/rda_x2go.c b/src/rda_x2go.c index 7b8cb6c..76f7652 100644 --- a/src/rda_x2go.c +++ b/src/rda_x2go.c @@ -25,18 +25,102 @@ #include #include +#include +#include #ifdef WITH_REMOTE_AWARENESS_X2GO +const rda_protocol_t +rda_supported_protocols_x2go[] = { RDA_PROTOCOL_NX, RDA_PROTOCOL_KDRIVE }; +const gsize +rda_supported_protocols_x2go_len = static_arr_size(rda_supported_protocols_x2go); + +static gboolean +rda_x2go_session_is_kdrive (const gchar *session_id) +{ + gboolean ret = FALSE; + const gchar *ptr = session_id; + + /* Sanity check. */ + if (!(ptr)) + { + return (ret); + } + + /* Skip user name. */ + while ((ptr) && (*(ptr)) && ('-' != (*(ptr)))) + { + ++ptr; + } + + if ((!(ptr)) || (!(*(ptr++)))) + { + return (ret); + } + + /* Skip port. */ + while ((ptr) && (*(ptr)) && ('-' != (*(ptr)))) + { + ++ptr; + } + + if ((!(ptr)) || (!(*(ptr++)))) + { + return (ret); + } + + /* Skip date. */ + while ((ptr) && (*(ptr)) && ('_' != (*(ptr)))) + { + ++ptr; + } + + if ((!(ptr)) || (!(*(ptr++)))) + { + return (ret); + } + + /* Don't supply a null pointer to strncmp() by accident. */ + if (!(ptr)) + { + return (ret); + } + + /* Check for "st". */ + if (!(strncmp("st", ptr, 2))) + { + ptr += 2; + + /* + * Next character must be 'K' for KDrive sessions. + * Note that this might change in future versions. + */ + if ((ptr) && ('K' == (*(ptr)))) + { + ret = TRUE; + } + } + + return (ret); +} + gboolean rda_session_is_x2go (void) { if (remote_technology == REMOTE_TECHNOLOGY_X2GO) return TRUE; - if (g_getenv("X2GO_SESSION")) + const gchar *session_id = g_getenv("X2GO_SESSION"); + if (session_id) { remote_technology = REMOTE_TECHNOLOGY_X2GO; + rda_protocol = RDA_PROTOCOL_NX; + + if (rda_x2go_session_is_kdrive(session_id)) + { + rda_protocol = RDA_PROTOCOL_KDRIVE; + } + return TRUE; } diff --git a/src/rda_x2go.h b/src/rda_x2go.h index 5759e79..fc9c986 100644 --- a/src/rda_x2go.h +++ b/src/rda_x2go.h @@ -27,9 +27,15 @@ #include #include +#include #ifdef WITH_REMOTE_AWARENESS_X2GO +extern const rda_protocol_t +rda_supported_protocols_x2go[]; +extern const gsize +rda_supported_protocols_x2go_len; + gboolean rda_session_is_x2go (void); -- cgit v1.2.3 From 589976911c4153200409a803f0b24cb5f818e38a Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Thu, 20 Jul 2023 02:56:44 +0200 Subject: src/rda.c: add generic protocol support. We're setting the protocol to RDA_PROTOCOL_NONE for local sessions here. All the other detection is done in the remote technology's code. --- src/rda.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rda.c b/src/rda.c index 26fd3ac..f71a4aa 100644 --- a/src/rda.c +++ b/src/rda.c @@ -27,6 +27,7 @@ #include #include #include +#include guint remote_technology = REMOTE_TECHNOLOGY_UNCHECKED; @@ -46,6 +47,7 @@ rda_session_is_local(void) if (g_getenv("XDG_SEAT")) { remote_technology = REMOTE_TECHNOLOGY_NONE; + rda_protocol = RDA_PROTOCOL_NONE; return TRUE; } @@ -57,7 +59,7 @@ rda_session_is_remote (void) { if (rda_session_is_local()) - remote_technology = REMOTE_TECHNOLOGY_NONE; + return FALSE; #ifdef WITH_REMOTE_AWARENESS_X2GO else if (rda_session_is_x2go()) return TRUE; -- cgit v1.2.3 From 8b5773c3396c7a358bf8b504025458d029fe17a6 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Fri, 21 Jul 2023 02:29:49 +0200 Subject: src/Makefile.am: compile the source and install header file for utilities. --- src/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index 88e8ffa..4bb5819 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,6 +21,7 @@ librdaincludedir = $(includedir)/rda librdainclude_HEADERS = \ rda_supported_technologies.h \ rda_ogon.h \ + rda_util.h \ rda_x2go.h \ rda.h \ $(NULL) @@ -29,6 +30,7 @@ librda_la_SOURCES = \ rda.c \ rda_x2go.c \ rda_ogon.c \ + rda_util.c \ $(NULL) librda_la_CFLAGS = \ -- cgit v1.2.3 From 89dffdf1babe0f401d1675e6837c06e1a0053509 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Thu, 20 Jul 2023 02:57:44 +0200 Subject: src/Makefile.am: compile the source and install header files for the new generic protocol support. --- src/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index 4bb5819..55e477b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,6 +21,7 @@ librdaincludedir = $(includedir)/rda librdainclude_HEADERS = \ rda_supported_technologies.h \ rda_ogon.h \ + rda_protocol.h \ rda_util.h \ rda_x2go.h \ rda.h \ @@ -30,6 +31,7 @@ librda_la_SOURCES = \ rda.c \ rda_x2go.c \ rda_ogon.c \ + rda_protocol.c \ rda_util.c \ $(NULL) -- cgit v1.2.3 From 46f800ed209cc199c4f567b1cfc27bf03f252bd2 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Fri, 21 Jul 2023 02:31:40 +0200 Subject: po/POTFILES.in: add src/rda_util.c. --- po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 26e7f40..3991b48 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,4 +1,5 @@ src/rda.c src/rda_x2go.c src/rda_ogon.c +src/rda_util.c util/rdacheck.c -- cgit v1.2.3 From f75ef6c322512f52fc3a7f98ff26622126497bb5 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Thu, 20 Jul 2023 03:00:05 +0200 Subject: po/POTFILES.in: add src/rda_protocol.c. --- po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 3991b48..9065279 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,5 +1,6 @@ src/rda.c src/rda_x2go.c src/rda_ogon.c +src/rda_protocol.c src/rda_util.c util/rdacheck.c -- cgit v1.2.3 From b34934f2afe790d88eac36e026352b81da2cfac3 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Thu, 20 Jul 2023 03:05:23 +0200 Subject: util/rdacheck.c: add generic protocol support. --- util/rdacheck.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/util/rdacheck.c b/util/rdacheck.c index 44a91ff..44bad77 100644 --- a/util/rdacheck.c +++ b/util/rdacheck.c @@ -26,12 +26,14 @@ Copyright 2019, Mike Gabriel #include #include +#include int main (int __attribute__((unused)) argc, char __attribute__((unused)) **argv) { rda_init(); g_message(_("Currently used remote technology: %s"), rda_get_remote_technology_name()); + g_message(_("Currently used protocol: %s"), rda_get_protocol_name()); g_message(_("RDA supports the following remote technologies:")); @@ -39,4 +41,13 @@ main (int __attribute__((unused)) argc, char __attribute__((unused)) **argv) gchar* item = tech->data; g_message(" * %s", item); } + + g_message(_("RDA supports the following protocols:")); + + GList *proto = NULL; + for(proto = rda_supported_protocols_by_name(); proto; proto = proto->next) { + gchar* item = proto->data; + g_message(" * %s", item); + } + g_list_free_full(g_steal_pointer(&proto), free); } -- cgit v1.2.3