Package: vinagre Version: 3.4.2-1 Severity: important Tags: upstream patch Control: forwarded -1 https://bugzilla.gnome.org/show_bug.cgi?id=690449
Dear Maintainers, Tunneling VNC connections through SSH does not work. After clicking the "Connect" button, Vinagre waits a dozen of seconds, then fails with "Connection to host $HOST was closed". I identified the cause of the problem as being a blocking read (which ought to be non-blocking). I attach a patch that fixes the problem for me, and that I have forwarded upstream. Cheers, -- System Information: Debian Release: wheezy/sid APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.2.0-4-amd64 (SMP w/2 CPU cores) Locale: LANG=fr_FR.utf8, LC_CTYPE=fr_FR.utf8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages vinagre depends on: ii dconf-gsettings-backend [gsettings-backend] 0.12.1-3 ii libavahi-common3 0.6.31-1 ii libavahi-gobject0 0.6.31-1 ii libavahi-ui-gtk3-0 0.6.31-1 ii libc6 2.13-37 ii libcairo2 1.12.2-2 ii libdbus-glib-1-2 0.100-1 ii libgdk-pixbuf2.0-0 2.26.1-1 ii libglib2.0-0 2.33.12+really2.32.4-3 ii libgnome-keyring0 3.4.1-1 ii libgtk-3-0 3.4.2-4 ii libgtk-vnc-2.0-0 0.5.0-3 ii libtelepathy-glib0 0.18.2-2 ii libvte-2.90-9 1:0.32.2-1 ii libxml2 2.8.0+dfsg1-7 Versions of packages vinagre recommends: ii gnome-icon-theme 3.4.0-2 ii rdesktop 1.7.1-1 vinagre suggests no packages. -- no debconf information
Description: Fix VNC tunneling through SSH Use GPollableInputStream when checking for SSH errors. Otherwise the read on stderr blocks, causing the SSH connection to timeout. . The original code sets O_NONBLOCK on stderr, but this does not work. This flag is not propagated to the corresponding GDataInputStream (at least with glib >= 2.32; it may have worked with older versions). . As a side effect, the patch fixes a minor memory leak in vinagre-ssh.c:look_for_stderr_errors() where the "line" variable was not correctly freed in all cases. Author: Sébastien Villemot <[email protected]> Bug: https://bugzilla.gnome.org/show_bug.cgi?id=690449 Last-Update: 2012-12-25 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/vinagre/vinagre-ssh.c +++ b/vinagre/vinagre-ssh.c @@ -667,17 +667,30 @@ } static gboolean -look_for_stderr_errors (GDataInputStream *error_stream, GError **error) +look_for_stderr_errors (GInputStream *is, GError **error) { - char *line; + GDataInputStream *error_stream; + char *line = NULL; + gboolean ret; + + error_stream = g_data_input_stream_new (is); while (1) { +#ifndef G_OS_WIN32 + if (!g_pollable_input_stream_is_readable (G_POLLABLE_INPUT_STREAM (is))) + { + ret = TRUE; + break; + } +#endif + line = g_data_input_stream_read_line (error_stream, NULL, NULL, NULL); if (line == NULL) { - return TRUE; + ret = TRUE; + break; } if (strstr (line, "Permission denied") != NULL) @@ -685,41 +698,49 @@ g_set_error_literal (error, VINAGRE_SSH_ERROR, VINAGRE_SSH_ERROR_PERMISSION_DENIED, _("Permission denied")); - return FALSE; + ret = FALSE; + break; } else if (strstr (line, "Name or service not known") != NULL) { g_set_error_literal (error, VINAGRE_SSH_ERROR, VINAGRE_SSH_ERROR_HOST_NOT_FOUND, _("Hostname not known")); - return FALSE; + ret = FALSE; + break; } else if (strstr (line, "No route to host") != NULL) { g_set_error_literal (error, VINAGRE_SSH_ERROR, VINAGRE_SSH_ERROR_HOST_NOT_FOUND, _("No route to host")); - return FALSE; + ret = FALSE; + break; } else if (strstr (line, "Connection refused") != NULL) { g_set_error_literal (error, VINAGRE_SSH_ERROR, VINAGRE_SSH_ERROR_PERMISSION_DENIED, _("Connection refused by server")); - return FALSE; + ret = FALSE; + break; } else if (strstr (line, "Host key verification failed") != NULL) { g_set_error_literal (error, VINAGRE_SSH_ERROR, VINAGRE_SSH_ERROR_FAILED, _("Host key verification failed")); - return FALSE; + ret = FALSE; + break; } - g_free (line); } - return TRUE; + if (line) + g_free (line); + + g_object_unref (error_stream); + return ret; } gboolean @@ -737,7 +758,6 @@ gchar *user, *host, **args; gboolean res; GInputStream *is; - GDataInputStream *error_stream; if (!hostname) return FALSE; @@ -791,14 +811,12 @@ ioctlsocket (stderr_fd, FIONBIO, &mode); is = g_win32_input_stream_new (stderr_fd, FALSE); #else /* !G_OS_WIN32 */ - fcntl (stderr_fd, F_SETFL, O_NONBLOCK | fcntl (stderr_fd, F_GETFL)); is = g_unix_input_stream_new (stderr_fd, FALSE); #endif /* G_OS_WIN32 */ - error_stream = g_data_input_stream_new (is); - g_object_unref (is); - res = look_for_stderr_errors (error_stream, error); - g_object_unref (error_stream); + res = look_for_stderr_errors (is, error); + + g_object_unref (is); if (!res) return FALSE;

