[X2Go-Commits] [libx2goclient] 04/08: src/x2goclient-network-ssh.c: implement FQDN/alias socket parsing.
git-admin at x2go.org
git-admin at x2go.org
Sat Aug 3 12:36:33 CEST 2019
This is an automated email from the git hooks/post-receive script.
x2go pushed a commit to branch master
in repository libx2goclient.
commit 309c0119a6fbb539401f37f2221d0c2406aef96a
Author: Mihai Moldovan <ionic at ionic.de>
Date: Wed Jul 31 21:28:08 2019 +0200
src/x2goclient-network-ssh.c: implement FQDN/alias socket parsing.
---
src/x2goclient-network-ssh.c | 123 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 122 insertions(+), 1 deletion(-)
diff --git a/src/x2goclient-network-ssh.c b/src/x2goclient-network-ssh.c
index 3bb1285..768b974 100644
--- a/src/x2goclient-network-ssh.c
+++ b/src/x2goclient-network-ssh.c
@@ -55,7 +55,8 @@
enum {
X2GOCLIENT_NETWORK_SSH_ERROR_PORT_CONV = 0,
X2GOCLIENT_NETWORK_SSH_ERROR_IPV6_CONV,
- X2GOCLIENT_NETWORK_SSH_ERROR_IPV4_CONV
+ X2GOCLIENT_NETWORK_SSH_ERROR_IPV4_CONV,
+ X2GOCLIENT_NETWORK_SSH_ERROR_ALIAS_CONV
};
@@ -77,6 +78,19 @@ static void x2goclient_network_options_ssh_init (X2GoClientNetworkOptionsSSH *se
}
+/*
+ * Custom sockaddr structure used to represent socket endpoints based on a FQDN
+ * or ssh_config-specific host alias.
+ */
+typedef struct sockaddr_ho {
+ sa_family_t sho_family;
+ in_port_t sho_port;
+ char sho_addr[256];
+} sockaddr_ho;
+
+#define AF_HOST 33
+
+
struct _X2GoClientNetworkSSH {
X2GoClientNetwork parent_class;
};
@@ -168,6 +182,18 @@ static guint16 x2goclient_network_ssh_parse_sockspec_port (const GString *portsp
return (ret);
}
+static GString* x2goclient_network_ssh_sanitize_sockspec (const GString *sockspec) {
+ GString *ret = NULL;
+
+ gchar *sanitize_sockspec = g_strdup (sockspec->str);
+ g_strstrip (sanitize_sockspec);
+ ret = g_string_new (g_strstrip (sanitize_sockspec));
+ g_free (sanitize_sockspec);
+ sanitize_sockspec = NULL;
+
+ return (ret);
+}
+
static GSocketAddress* x2goclient_network_ssh_parse_sockspec_ip (const GString *sockspec, const gboolean want_v6, GError **err) {
GSocketAddress *ret = NULL;
@@ -340,6 +366,85 @@ static GSocketAddress* x2goclient_network_ssh_parse_sockspec_ip (const GString *
return (ret);
}
+static GSocketAddress* x2goclient_network_ssh_parse_sockspec_alias (const GString *sockspec, GError **err) {
+ GSocketAddress *ret = NULL;
+
+ g_return_val_if_fail (err == NULL || *err == NULL, ret);
+
+ /* We're free to sanitize the string now. */
+ GString *work_sockspec = x2goclient_network_ssh_sanitize_sockspec (sockspec);
+
+ gchar *tmp_start = work_sockspec->str,
+ *tmp_end = NULL;
+ GString *address = NULL;
+ guint16 port = 0;
+
+ /*
+ * For FQDN or alias addresses (like for IPv4 addresses), we'll accept any
+ * input of the form address:port.
+ */
+ tmp_end = g_strstr_len (tmp_start, -1, ":");
+
+ if (tmp_end) {
+ --tmp_end;
+
+ address = g_string_new_len (tmp_start, tmp_end - tmp_start);
+ }
+ else {
+ address = g_string_new_len (tmp_start, work_sockspec->len);
+ }
+
+ /*
+ * Check validity.
+ *
+ * FIXME: for now only the size, but maybe we should do extra checks on the
+ * name.
+ */
+ const gsize max_len = (sizeof (((struct sockaddr_ho*)(NULL))->sho_addr) - 1);
+ if (max_len < address->len) {
+ g_set_error (err, X2GOCLIENT_NETWORK_SSH_ERROR, X2GOCLIENT_NETWORK_SSH_ERROR_ALIAS_CONV, "Unable to parse FQDN or alias pseudo-address: name too long, expected at most %" G_GSIZE_FORMAT " bytes, got %" G_GSIZE_FORMAT " bytes.", max_len, address->len);
+ }
+
+ if (!err) {
+ if (tmp_end) {
+ /*
+ * No encapsulation whatsoever, so the colon must be at the next
+ * position.
+ */
+ GString *portspec = g_string_new (tmp_end + 1);
+
+ GError *tmp_err = NULL;
+ port = x2goclient_network_ssh_parse_sockspec_port (portspec, &tmp_err);
+ g_string_free (portspec, TRUE);
+ portspec = NULL;
+
+ if (tmp_err) {
+ g_set_error (err, X2GOCLIENT_NETWORK_SSH_ERROR, X2GOCLIENT_NETWORK_SSH_ERROR_ALIAS_CONV, "Unable to parse FQDN or alias pseudo-address: %s", tmp_err->message);
+ g_clear_error (&tmp_err);
+ }
+ }
+ }
+
+ if (!err) {
+ /*
+ * Parsed everything successfully so far, so create native socket address
+ * object.
+ */
+ struct sockaddr_ho tmp_sockaddr = { AF_HOST, };
+ g_strlcpy (tmp_sockaddr.sho_addr, address->str, max_len + 1);
+ tmp_sockaddr.sho_port = port;
+ ret = g_native_socket_address_new (&tmp_sockaddr, sizeof (struct sockaddr_ho));
+ }
+
+ g_string_free (work_sockspec, TRUE);
+ work_sockspec = NULL;
+
+ g_string_free (address, TRUE);
+ address = NULL;
+
+ return (ret);
+}
+
static GSocketAddress* x2goclient_network_ssh_parse_sockspec (X2GoClientNetworkSSH *self, const GString *sockspec) {
GSocketAddress *ret = NULL;
@@ -378,6 +483,22 @@ static GSocketAddress* x2goclient_network_ssh_parse_sockspec (X2GoClientNetworkS
g_clear_error (&tmp_err);
}
}
+
+ if (!ret) {
+ g_log (NULL, G_LOG_LEVEL_INFO, "Failed to parse socket specification as IPv4 socket.\n"
+ "Continuing with FQDN/alias parsing.");
+
+ GError *tmp_err = NULL;
+ ret = x2goclient_network_ssh_parse_sockspec_alias (sockspec, &tmp_err);
+
+ if (tmp_err) {
+ g_assert (!ret);
+
+ g_log (NULL, G_LOG_LEVEL_WARNING, "Socket specification looked like a FQDN or alias socket, but parsing as such failed: %s", tmp_err->message);
+
+ g_clear_error (&tmp_err);
+ }
+ }
}
return ret;
--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/libx2goclient.git
More information about the x2go-commits
mailing list