This is an automated email from the git hooks/post-receive script. x2go pushed a change to branch master in repository libx2goclient. from dc7f904 src/x2goclient-network-ssh.c: start implementation x2goclient_network_ssh_parse_sockspec (). new 1bedee7 configure.ac: also use gio-unix. new 89dff4d src/x2goclient-network-ssh.c: continue implementation of x2goclient_network_ssh_parse_sockspec(). The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Summary of changes: configure.ac | 2 +- src/x2goclient-network-ssh.c | 167 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 136 insertions(+), 33 deletions(-) -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/libx2goclient.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository libx2goclient. commit 1bedee77335756ca17fbf2bc08c0fc0e837048ae Author: Mihai Moldovan <ionic@ionic.de> Date: Sat Jul 27 13:50:49 2019 +0200 configure.ac: also use gio-unix. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ae79817..031b0d9 100644 --- a/configure.ac +++ b/configure.ac @@ -55,7 +55,7 @@ GOBJECT_INTROSPECTION_CHECK([0.9.7]) dnl pkg-config dependency checks -PKG_CHECK_MODULES(LIBX2GOCLIENT, glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GIO_REQUIRED) +PKG_CHECK_MODULES(LIBX2GOCLIENT, glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GIO_REQUIRED gio-unix-2.0 >= $GIO_REQUIRED) dnl Language Support -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/libx2goclient.git
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@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