Version in base suite: 1.2.10-1 Base version: network-manager-ssh_1.2.10-1 Target version: network-manager-ssh_1.2.10-1+deb10u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/n/network-manager-ssh/network-manager-ssh_1.2.10-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/n/network-manager-ssh/network-manager-ssh_1.2.10-1+deb10u1.dsc changelog | 7 patches/0002-Remove-extra-options.patch | 311 ++++++++++++++++++++++++++++++++ patches/series | 1 3 files changed, 319 insertions(+) diff -Nru network-manager-ssh-1.2.10/debian/changelog network-manager-ssh-1.2.10/debian/changelog --- network-manager-ssh-1.2.10/debian/changelog 2019-05-10 08:28:16.000000000 +0000 +++ network-manager-ssh-1.2.10/debian/changelog 2020-03-04 22:07:31.000000000 +0000 @@ -1,3 +1,10 @@ +network-manager-ssh (1.2.10-1+deb10u1) buster-security; urgency=high + + * Non-maintainer upload by the Security Team. + * Privilege escalation because extra options are mishandled (CVE-2020-9355) + + -- Salvatore Bonaccorso Wed, 04 Mar 2020 23:07:31 +0100 + network-manager-ssh (1.2.10-1) unstable; urgency=high * New upstream release (Closes: #928747) diff -Nru network-manager-ssh-1.2.10/debian/patches/0002-Remove-extra-options.patch network-manager-ssh-1.2.10/debian/patches/0002-Remove-extra-options.patch --- network-manager-ssh-1.2.10/debian/patches/0002-Remove-extra-options.patch 1970-01-01 00:00:00.000000000 +0000 +++ network-manager-ssh-1.2.10/debian/patches/0002-Remove-extra-options.patch 2020-03-04 22:07:31.000000000 +0000 @@ -0,0 +1,311 @@ +From: Dan Fruehauf +Date: Sun, 16 Feb 2020 19:58:50 +0200 +Subject: Remove extra options +Origin: https://github.com/danfruehauf/NetworkManager-ssh/commit/5d88cd89795352b5df54cc0ebb6a0076b8c89ee4 +Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1803499 +Bug: https://github.com/danfruehauf/NetworkManager-ssh/pull/98 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2020-9355 + +After analyzing some privilege escalation possibilites, it was decided +it is best to remove extra options +--- + properties/advanced-dialog.c | 39 -------------------------------- + properties/nm-ssh-dialog.ui | 44 ------------------------------------ + properties/nm-ssh.c | 35 +--------------------------- + properties/nm-ssh.h | 1 - + src/nm-ssh-service-defines.h | 2 -- + src/nm-ssh-service.c | 32 ++++---------------------- + 6 files changed, 5 insertions(+), 148 deletions(-) + +diff --git a/properties/advanced-dialog.c b/properties/advanced-dialog.c +index a3730fec3bca..7ca4a458af8a 100644 +--- a/properties/advanced-dialog.c ++++ b/properties/advanced-dialog.c +@@ -51,7 +51,6 @@ + static const char *advanced_keys[] = { + NM_SSH_KEY_PORT, + NM_SSH_KEY_TUNNEL_MTU, +- NM_SSH_KEY_EXTRA_OPTS, + NM_SSH_KEY_REMOTE_DEV, + NM_SSH_KEY_TAP_DEV, + NM_SSH_KEY_REMOTE_USERNAME, +@@ -107,16 +106,6 @@ tunmtu_toggled_cb (GtkWidget *check, gpointer user_data) + gtk_widget_set_sensitive (widget, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check))); + } + +-static void +-extra_opts_toggled_cb (GtkWidget *check, gpointer user_data) +-{ +- GtkBuilder *builder = (GtkBuilder *) user_data; +- GtkWidget *widget; +- +- widget = GTK_WIDGET (gtk_builder_get_object (builder, "extra_opts_entry")); +- gtk_widget_set_sensitive (widget, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check))); +-} +- + static void + remote_dev_toggled_cb (GtkWidget *check, gpointer user_data) + { +@@ -233,25 +222,6 @@ advanced_dialog_new (GHashTable *hash) + gtk_widget_set_sensitive (widget, FALSE); + } + +- widget = GTK_WIDGET (gtk_builder_get_object (builder, "extra_opts_checkbutton")); +- g_assert (widget); +- g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (extra_opts_toggled_cb), builder); +- +- value = g_hash_table_lookup (hash, NM_SSH_KEY_EXTRA_OPTS); +- if (value && strlen (value)) { +- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); +- +- widget = GTK_WIDGET (gtk_builder_get_object (builder, "extra_opts_entry")); +- gtk_entry_set_text (GTK_ENTRY (widget), value); +- gtk_widget_set_sensitive (widget, TRUE); +- } else { +- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); +- +- widget = GTK_WIDGET (gtk_builder_get_object (builder, "extra_opts_entry")); +- gtk_entry_set_text (GTK_ENTRY (widget), NM_SSH_DEFAULT_EXTRA_OPTS); +- gtk_widget_set_sensitive (widget, FALSE); +- } +- + widget = GTK_WIDGET (gtk_builder_get_object (builder, "remote_dev_checkbutton")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (remote_dev_toggled_cb), builder); +@@ -339,15 +309,6 @@ advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error) + g_hash_table_insert (hash, g_strdup (NM_SSH_KEY_PORT), g_strdup_printf ("%d", port)); + } + +- widget = GTK_WIDGET (gtk_builder_get_object (builder, "extra_opts_checkbutton")); +- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { +- const gchar *extra_options; +- +- widget = GTK_WIDGET (gtk_builder_get_object (builder, "extra_opts_entry")); +- extra_options = gtk_entry_get_text (GTK_ENTRY (widget)); +- g_hash_table_insert (hash, g_strdup (NM_SSH_KEY_EXTRA_OPTS), g_strdup(extra_options)); +- } +- + widget = GTK_WIDGET (gtk_builder_get_object (builder, "remote_dev_checkbutton")); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { + int remote_dev; +diff --git a/properties/nm-ssh-dialog.ui b/properties/nm-ssh-dialog.ui +index 89d4462048e6..511a93fcb0d6 100644 +--- a/properties/nm-ssh-dialog.ui ++++ b/properties/nm-ssh-dialog.ui +@@ -246,50 +246,6 @@ + 1 + + +- +- +- True +- False +- 6 +- +- +- Extra SSH options: +- True +- True +- False +- True +- True +- +- +- False +- True +- 0 +- +- +- +- +- True +- True +- +- -o ServerAliveInterval=10 -o TCPKeepAlive=yes +- False +- False +- True +- True +- +- +- True +- True +- 1 +- +- +- +- +- False +- True +- 2 +- +- + + + True +diff --git a/properties/nm-ssh.c b/properties/nm-ssh.c +index 6d9b6ea6a31d..8f24232190a6 100644 +--- a/properties/nm-ssh.c ++++ b/properties/nm-ssh.c +@@ -1045,31 +1045,6 @@ import (NMVpnEditorPlugin *iface, const char *path, GError **error) + PARSE_IMPORT_KEY_WITH_DEFAULT_VALUE_INT (MTU_KEY, NM_SSH_KEY_TUNNEL_MTU, items, s_vpn, NM_SSH_DEFAULT_MTU) + PARSE_IMPORT_KEY_WITH_DEFAULT_VALUE_INT (REMOTE_DEV_KEY, NM_SSH_KEY_REMOTE_DEV, items, s_vpn, NM_SSH_DEFAULT_REMOTE_DEV) + PARSE_IMPORT_KEY_BOOL (DEV_TYPE_KEY, NM_SSH_KEY_TAP_DEV, items, s_vpn, "tap") +- +- /* Some extra care required with extra_opts as we need to: +- * 1. Use the whole line (might contain = chars in it) +- * 2. Strip the single/double quotes */ +- if (!strncmp (items[0], EXTRA_OPTS_KEY, strlen (items[0]))) { +- gchar *parsed_extra_opts = NULL; +- gchar *unquoted_extra_opts = NULL; +- /* Read the whole line, witout the EXTRA_OPTS= part */ +- parsed_extra_opts = g_strdup(*line + strlen(EXTRA_OPTS_KEY) + 1); +- +- /* Check if string is quoted */ +- if ( (parsed_extra_opts[0] == '"' && parsed_extra_opts[strlen(parsed_extra_opts)-1] == '"') || +- /* String is quoted (would usually be), lets strip the quotes */ +- (parsed_extra_opts[0] == '\'' && parsed_extra_opts[strlen(parsed_extra_opts)-1] == '\'') ) { +- /* Unquote string */ +- parsed_extra_opts[strlen(parsed_extra_opts)-1] = '\0'; +- unquoted_extra_opts = parsed_extra_opts + 1; +- } +- /* After all this effort, try to compare to the default value */ +- if (strncmp(unquoted_extra_opts, NM_SSH_DEFAULT_EXTRA_OPTS, strlen(unquoted_extra_opts))) +- nm_setting_vpn_add_data_item (s_vpn, NM_SSH_KEY_EXTRA_OPTS, unquoted_extra_opts); +- g_free (items); +- g_free (parsed_extra_opts); +- continue; +- } + } + + if (connection) +@@ -1104,7 +1079,6 @@ export (NMVpnEditorPlugin *iface, + const char *local_ip_6 = NULL; + const char *remote_ip_6 = NULL; + const char *netmask_6 = NULL; +- const char *extra_opts = NULL; + const char *remote_dev = NULL; + const char *mtu = NULL; + const char *remote_username = NULL; +@@ -1189,12 +1163,6 @@ export (NMVpnEditorPlugin *iface, + else + mtu = g_strdup_printf("%d", NM_SSH_DEFAULT_MTU); + +- value = nm_setting_vpn_get_data_item (s_vpn, NM_SSH_KEY_EXTRA_OPTS); +- if (value && strlen (value)) +- extra_opts = value; +- else +- extra_opts = g_strdup(NM_SSH_DEFAULT_EXTRA_OPTS); +- + value = nm_setting_vpn_get_data_item (s_vpn, NM_SSH_KEY_REMOTE_DEV); + if (value && strlen (value)) + remote_dev = value; +@@ -1274,7 +1242,6 @@ export (NMVpnEditorPlugin *iface, + } + fprintf (f, "%s=%s\n", PORT_KEY, port); + fprintf (f, "%s=%s\n", MTU_KEY, mtu); +- fprintf (f, "%s='%s'\n", EXTRA_OPTS_KEY, extra_opts); + fprintf (f, "%s=%s\n", REMOTE_DEV_KEY, remote_dev); + + /* Assign tun/tap */ +@@ -1286,7 +1253,7 @@ export (NMVpnEditorPlugin *iface, + + /* The generic lines that will perform the connection */ + fprintf (f, "\n"); +- fprintf(f, "ssh -f %s -o PreferredAuthentications=%s -o NumberOfPasswordPrompts=%d -o Tunnel=$TUNNEL_TYPE $EXTRA_OPTS -o TunnelDevice=$LOCAL_DEV:$REMOTE_DEV -o User=$REMOTE_USERNAME -o Port=$PORT -o HostName=$REMOTE $REMOTE \"%s $DEV_TYPE$REMOTE_DEV $REMOTE_IP netmask $NETMASK pointopoint $LOCAL_IP; %s\" && \\\n", ++ fprintf(f, "ssh -f %s -o PreferredAuthentications=%s -o NumberOfPasswordPrompts=%d -o Tunnel=$TUNNEL_TYPE -o ServerAliveInterval=10 -o TCPKeepAlive=yes -o TunnelDevice=$LOCAL_DEV:$REMOTE_DEV -o User=$REMOTE_USERNAME -o Port=$PORT -o HostName=$REMOTE $REMOTE \"%s $DEV_TYPE$REMOTE_DEV $REMOTE_IP netmask $NETMASK pointopoint $LOCAL_IP; %s\" && \\\n", + (key_file ? g_strconcat("-i ", key_file, NULL) : ""), + preferred_authentication, + password_prompt_nr, +diff --git a/properties/nm-ssh.h b/properties/nm-ssh.h +index 98a96c0de932..9e460cee3074 100644 +--- a/properties/nm-ssh.h ++++ b/properties/nm-ssh.h +@@ -93,7 +93,6 @@ void init_auth_widget (GtkBuilder *builder, + #define NETMASK_6_KEY "NETMASK_6" + #define PORT_KEY "PORT" + #define MTU_KEY "MTU" +-#define EXTRA_OPTS_KEY "EXTRA_OPTS" + #define REMOTE_DEV_KEY "REMOTE_DEV" + #define DEV_TYPE_KEY "DEV_TYPE" + #define NO_DEFAULT_ROUTE_KEY "NO_DEFAULT_ROUTE" +diff --git a/src/nm-ssh-service-defines.h b/src/nm-ssh-service-defines.h +index 121c6e9589f3..d533f0e26e7c 100644 +--- a/src/nm-ssh-service-defines.h ++++ b/src/nm-ssh-service-defines.h +@@ -36,7 +36,6 @@ + #define NM_SSH_KEY_NETMASK "netmask" + #define NM_SSH_KEY_PORT "port" + #define NM_SSH_KEY_TUNNEL_MTU "tunnel-mtu" +-#define NM_SSH_KEY_EXTRA_OPTS "extra-opts" + #define NM_SSH_KEY_REMOTE_DEV "remote-dev" + #define NM_SSH_KEY_SSH_AUTH_SOCK "ssh-auth-sock" + #define NM_SSH_KEY_TAP_DEV "tap-dev" +@@ -52,7 +51,6 @@ + #define NM_SSH_DEFAULT_PORT 22 + #define NM_SSH_DEFAULT_MTU 1500 + #define NM_SSH_DEFAULT_REMOTE_DEV 100 +-#define NM_SSH_DEFAULT_EXTRA_OPTS "-o ServerAliveInterval=10 -o TCPKeepAlive=yes" + #define NM_SSH_DEFAULT_REMOTE_USERNAME "root" + + #define NM_SSH_AUTH_TYPE_SSH_AGENT "ssh-agent" +diff --git a/src/nm-ssh-service.c b/src/nm-ssh-service.c +index 185e67e7bfd5..694c16cce422 100644 +--- a/src/nm-ssh-service.c ++++ b/src/nm-ssh-service.c +@@ -113,7 +113,6 @@ static ValidProperty valid_properties[] = { + { NM_SSH_KEY_NETMASK, G_TYPE_STRING, 0, 0, TRUE }, + { NM_SSH_KEY_PORT, G_TYPE_INT, 1, 65535, FALSE }, + { NM_SSH_KEY_TUNNEL_MTU, G_TYPE_INT, 1, 9000, FALSE }, +- { NM_SSH_KEY_EXTRA_OPTS, G_TYPE_STRING, 0, 0, FALSE }, + { NM_SSH_KEY_REMOTE_DEV, G_TYPE_INT, 0, 255, FALSE }, + { NM_SSH_KEY_TAP_DEV, G_TYPE_BOOLEAN, 0, 0, FALSE }, + { NM_SSH_KEY_REMOTE_USERNAME, G_TYPE_STRING, 0, 0, FALSE }, +@@ -717,25 +716,6 @@ add_ssh_arg (GPtrArray *args, const char *arg) + g_ptr_array_add (args, (gpointer) g_strdup (arg)); + } + +-static void +-add_ssh_extra_opts (GPtrArray *args, const char *extra_opts) +-{ +- gchar **extra_opts_split; +- gchar **iter; +- +- /* Needs to separate arguements nicely */ +- extra_opts_split = g_strsplit (extra_opts, " ", 256); +- iter = extra_opts_split; +- +- /* Ensure it's a valid DNS name or IP address */ +- while (*iter) { +- g_message("%s", *iter); +- add_ssh_arg (args, *iter); +- iter++; +- } +- g_strfreev (extra_opts_split); +-} +- + static gboolean + get_ssh_arg_int (const char *arg, long int *retval) + { +@@ -964,14 +944,10 @@ nm_ssh_start_ssh_binary (NMSshPlugin *plugin, + g_free(known_hosts_file); + } + +- /* Extra SSH options */ +- tmp = nm_setting_vpn_get_data_item (s_vpn, NM_SSH_KEY_EXTRA_OPTS); +- if (tmp && strlen (tmp)) { +- add_ssh_extra_opts (args, tmp); +- } else { +- /* Add default extra options */ +- add_ssh_extra_opts (args, NM_SSH_DEFAULT_EXTRA_OPTS); +- } ++ add_ssh_arg (args, "-o"); ++ add_ssh_arg (args, "ServerAliveInterval=10"); ++ add_ssh_arg (args, "-o"); ++ add_ssh_arg (args, "TCPKeepAlive=yes"); + + /* Device, either tun or tap */ + add_ssh_arg (args, "-o"); +-- +2.25.1 + diff -Nru network-manager-ssh-1.2.10/debian/patches/series network-manager-ssh-1.2.10/debian/patches/series --- network-manager-ssh-1.2.10/debian/patches/series 2019-05-10 08:28:16.000000000 +0000 +++ network-manager-ssh-1.2.10/debian/patches/series 2020-03-04 22:07:31.000000000 +0000 @@ -1 +1,2 @@ 0001-Moved-appdata-to-new-metainfo-directory.patch +0002-Remove-extra-options.patch