[X2Go-Commits] [libx2goclient] 02/02: src/x2goclient-network-ssh.c: continue implementation of x2goclient_network_ssh_parse_sockspec().
git-admin at x2go.org
git-admin at x2go.org
Sat Jul 27 13:52:10 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 89dff4d6f8c3966724287c4efb986876d6dd925f
Author: Mihai Moldovan <ionic at ionic.de>
Date: Sat Jul 27 13:51:54 2019 +0200
src/x2goclient-network-ssh.c: continue implementation of x2goclient_network_ssh_parse_sockspec().
Additionally, start splitting the function up, because it's getting pretty complicated.
---
src/x2goclient-network-ssh.c | 167 ++++++++++++++++++++++++++++++++++---------
1 file changed, 135 insertions(+), 32 deletions(-)
diff --git a/src/x2goclient-network-ssh.c b/src/x2goclient-network-ssh.c
index 4b95b6d..702f279 100644
--- a/src/x2goclient-network-ssh.c
+++ b/src/x2goclient-network-ssh.c
@@ -24,12 +24,20 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <errno.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gprintf.h>
+#include <glib/gstdio.h>
#include <gmodule.h>
#include <gio/gio.h>
+#include <gio/gunixsocketaddress.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -57,36 +65,87 @@ struct _X2GoClientNetworkSSH {
G_DEFINE_TYPE (X2GoClientNetworkSSH, x2goclient_network_ssh, X2GOCLIENT_TYPE_NETWORK);
-static GSocketAddress* x2goclient_network_ssh_parse_sockspec (X2GoClientNetworkSSH *self, const GString *sockspec) {
+static GSocketAddress* x2goclient_network_ssh_parse_sockspec_unix_socket (const GString *sockspec) {
GSocketAddress *ret = NULL;
- if (sockspec) {
+ /*
+ * N.B.: do *not* sanitize the string, since UNIX sockets are allowed to
+ * start and end on whitespace.
+ */
+ gboolean is_socket = FALSE;
+ GUnixSocketAddressType socket_type = G_UNIX_SOCKET_ADDRESS_PATH;
+
+ /* Max. path len without terminating NULL byte */
+ if ((sizeof (((struct sockaddr_un*)(NULL))->sun_path) - 1) >= sockspec->len) {
+ /* Smells like a UNIX socket so far. */
+ if (0 == sockspec->str[0]) {
+ /*
+ * Abstract UNIX sockets are specified with a preceding NULL byte.
+ * We can't check for them, since they have no equivalent on the file
+ * system.
+ *
+ * Encountering this means that we have to trust the socket exists.
+ */
+ is_socket = TRUE;
+ socket_type = G_UNIX_SOCKET_ADDRESS_ABSTRACT;
+ }
+ else {
+ /* Check if such a file exists on the file system. */
+ GStatBuf tmp_stat_buf = { 0 };
+ if (0 == g_stat (sockspec->str, &tmp_stat_buf)) {
+ /* File exists, let's check if this is a socket. */
+ if ((tmp_stat_buf.st_mode & S_IFMT) == S_IFSOCK) {
+ is_socket = TRUE;
+ }
+ }
+ }
+
+ if (is_socket) {
+ ret = g_unix_socket_address_new_with_type (sockspec->str, sockspec->len, socket_type);
+ }
+ }
+
+ return (ret);
+}
+
+static gint32 x2goclient_network_ssh_parse_sockspec_port (const GString *portspec) {
+ gint32 ret = -1;
+
+ if (':' == portspec->str[0]) {
/*
- * Check if it's possibly a UNIX socket.
- *
- * N.B.: do *not* sanitize the string, since UNIX sockets are allowed to
- * start and end on whitespace.
+ * In the worst case, portspec->str[1] will point to a terminating NULL
+ * character, but that's non-critical.
*/
- gboolean is_abstract = FALSE;
-
- /* Max. path len without terminating NULL byte */
- if ((sizeof (((struct sockaddr_un*)(NULL))->sun_path) - 1) >= sockspec->len) {
- /* Smells like a UNIX socket so far. */
- if (0 == sockspec->str[0]) {
- /*
- * Abstract UNIX sockets are specified with a preceding NULL byte.
- * We can't check for them, since they have no equivalent on the file
- * system.
- *
- * Encountering this means that we have to trust the socket exists.
- */
- is_abstract = TRUE;
- }
- else {
- /* Check if such a file exists on the file system. */
- ... /* Parse error is fine here. */
- }
+ errno = 0;
+ long long conv = strtoll (portspec->str + 1, NULL, 10);
+
+ if (0 != errno) {
+ g_log (NULL, G_LOG_LEVEL_WARNING, "Unable to convert port specifier, invalid input.");
}
+ else if ((1 << 16) <= conv) {
+ g_log (NULL, G_LOG_LEVEL_WARNING, "Port specifier out of range (too big), invalid input.");
+ }
+ else if (0 >= conv) {
+ g_log (NULL, G_LOG_LEVEL_WARNING, "Port specifier out of range (negative or zero), invalid input.");
+ }
+ else {
+ ret = conv;
+ }
+ }
+ else {
+ /* No specifier found, assume default port. */
+ ret = 0;
+ }
+
+ return (ret);
+}
+
+static GSocketAddress* x2goclient_network_ssh_parse_sockspec (X2GoClientNetworkSSH *self, const GString *sockspec) {
+ GSocketAddress *ret = NULL;
+
+ if (sockspec) {
+ /* Check if it's possibly a UNIX socket. */
+ ret = x2goclient_network_ssh_parse_sockspec_unix_socket (sockspec);
if (!ret) {
/* Must be not a UNIX socket, continue checking for IPv6 addresses. */
@@ -94,20 +153,64 @@ static GSocketAddress* x2goclient_network_ssh_parse_sockspec (X2GoClientNetworkS
/* We're free to sanitize the string now. */
g_strstrip (sockspec->str);
+ gboolean could_be_v6 = FALSE;
gboolean is_v6 = FALSE;
- gchar *v6_end = NULL;
+ gchar *tmp_start = sockspec->str;
+ gchar *tmp_end = NULL;
+ GString *v6_address = NULL;
+ GString *address = NULL;
+ guint16 port = 0;
/*
- * As a very common convention, IPv6 address have to be encapsulated in
- * brackets, check for that.
+ * As a very common convention, IPv6 addresses have to be encapsulated in
+ * brackets if an additional port is specified, check for that.
*/
- if ('[' == sockspec->str[0]) {
- v6_end = g_strstr_len (sockspec->str, -1, "]");
+ if ('[' == tmp_start[0]) {
+ tmp_end = g_strstr_len (tmp_start, -1, "]");
+
+ if (tmp_end) {
+ /*
+ * Looks like a bracket-encapsulated IPv6 address so far.
+ * See if that checks out.
+ */
+ could_be_v6 = TRUE;
+ ++tmp_start;
+ --tmp_end;
+
+ v6_address = g_string_new_len (tmp_start, tmp_end - tmp_start);
+ }
+ }
+ else {
+ v6_address = g_string_new_len (tmp_start, sockspec->len);
+ }
- if (v6_end) {
- is_v6 = TRUE;
+ /* Check for an IPv6 address first. */
+ char binary_rep[128] = { 0 };
+ is_v6 = (1 == inet_pton (AF_INET6, v6_address->str, &binary_rep));
+
+ if (is_v6) {
+ /* Passed a valid IPv6 address. */
+ if (tmp_end) {
+ /*
+ * Specification in brackets, so check if there's a port specifier.
+ *
+ * tmp_end points to the last part of the address, so tmp_end + 1
+ * will point to the terminating bracket. tmp_end + 2 can, in the
+ * worst case, point to the terminating NULL character, which is
+ * fine.
+ */
+ GString *portspec = g_string_new (tmp_end + 2);
+ gint32 port_parse = x2goclient_network_ssh_parse_sockspec_port (portspec);
+ g_string_free (portspec, TRUE);
+ portspec = NULL;
+ }
+ else {
+ address = g_string_new (v6_address->str);
}
}
+ else {
+ /* */
+ }
}
}
--
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