[gnome-keyring] ssh-agent: Propagate stderr to journal when spawning ssh-add



commit 153ae24bd706dd505f496ffe63023c49de3842ae
Author: Daiki Ueno <dueno src gnome org>
Date:   Fri Mar 16 13:27:57 2018 +0100

    ssh-agent: Propagate stderr to journal when spawning ssh-add
    
    ssh-add fails in certain occasions, such as when the file permissions
    of private key is not unsafe.  To help diagnostics, propagate the
    stderr output from the command to journal.
    
    As the ssh commands send error message with trailing CR for each line,
    we need to scrub it so as not to confuse journald.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=794361

 daemon/ssh-agent/gkd-ssh-agent-service.c   |    8 ++++--
 daemon/ssh-agent/gkd-ssh-agent-util.c      |   16 +++++++++++++++
 daemon/ssh-agent/gkd-ssh-agent-util.h      |    1 +
 daemon/ssh-agent/test-gkd-ssh-agent-util.c |   29 ++++++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 3 deletions(-)
---
diff --git a/daemon/ssh-agent/gkd-ssh-agent-service.c b/daemon/ssh-agent/gkd-ssh-agent-service.c
index 8b9a8f1..1fad267 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-service.c
+++ b/daemon/ssh-agent/gkd-ssh-agent-service.c
@@ -228,6 +228,7 @@ ensure_key (GkdSshAgentService *self,
        const gchar *label;
        GHashTable *fields;
        GTlsInteraction *interaction;
+       gchar *standard_error;
 
        gchar *argv[] = {
                SSH_ADD,
@@ -256,14 +257,15 @@ ensure_key (GkdSshAgentService *self,
        g_object_unref (interaction);
 
        if (!g_spawn_sync (NULL, argv, NULL,
-                          G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
+                          G_SPAWN_STDOUT_TO_DEV_NULL,
                           gcr_ssh_askpass_child_setup, askpass,
-                          NULL, NULL, &status, &error)) {
+                          NULL, &standard_error, &status, &error)) {
                g_warning ("couldn't run %s: %s", argv[0], error->message);
                g_error_free (error);
        } else if (!g_spawn_check_exit_status (status, &error)) {
                g_message ("the %s command failed: %s", argv[0], error->message);
-               g_error_free (error);
+               g_printerr ("%s", _gkd_ssh_agent_canon_error (standard_error));
+               g_free (standard_error);
        } else {
                add_key (self, key);
        }
diff --git a/daemon/ssh-agent/gkd-ssh-agent-util.c b/daemon/ssh-agent/gkd-ssh-agent-util.c
index 464cd1c..4d74505 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-util.c
+++ b/daemon/ssh-agent/gkd-ssh-agent-util.c
@@ -161,3 +161,19 @@ _gkd_ssh_agent_parse_public_key (GBytes *input,
 
        return g_bytes_new_take (decoded, n_decoded);
 }
+
+gchar *
+_gkd_ssh_agent_canon_error (gchar *str)
+{
+       gchar *start = str;
+       gchar *end = str + strlen (str) + 1;
+
+       for (;;) {
+               start = strchr (start, '\r');
+               if (!start)
+                       break;
+               memmove (start, start + 1, end - (start + 1));
+       }
+
+       return str;
+}
diff --git a/daemon/ssh-agent/gkd-ssh-agent-util.h b/daemon/ssh-agent/gkd-ssh-agent-util.h
index 8b16b3e..f8aba8b 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-util.h
+++ b/daemon/ssh-agent/gkd-ssh-agent-util.h
@@ -39,5 +39,6 @@ gboolean _gkd_ssh_agent_write_packet     (GSocketConnection  *connection,
 GBytes  *_gkd_ssh_agent_parse_public_key (GBytes             *input,
                                           gchar             **comment);
 
+gchar   *_gkd_ssh_agent_canon_error      (gchar *str);
 
 #endif /* __GKD_SSH_AGENT_UTIL_H__ */
diff --git a/daemon/ssh-agent/test-gkd-ssh-agent-util.c b/daemon/ssh-agent/test-gkd-ssh-agent-util.c
index 89c10d2..b74ccf4 100644
--- a/daemon/ssh-agent/test-gkd-ssh-agent-util.c
+++ b/daemon/ssh-agent/test-gkd-ssh-agent-util.c
@@ -73,12 +73,41 @@ test_parse_public (void)
        }
 }
 
+static void
+test_canon_error (void)
+{
+       static const gchar input[] =
+               "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n"
+               "@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @\r\n"
+               "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
+               "Permissions 0620 for '/home/foo/.ssh/id_rsa' are too open.\r\n"
+               "It is required that your private key files are NOT accessible by others.\r\n"
+               "This private key will be ignored.\r\n";
+       static const gchar expected[] =
+               "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
+               "@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @\n"
+               "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
+               "Permissions 0620 for '/home/foo/.ssh/id_rsa' are too open.\n"
+               "It is required that your private key files are NOT accessible by others.\n"
+               "This private key will be ignored.\n";
+       gchar *p, *output;
+
+       p = g_strdup (input);
+       output = _gkd_ssh_agent_canon_error (p);
+
+       g_assert (output == p);
+       g_assert_cmpstr (expected, ==, output);
+
+       g_free (p);
+}
+
 int
 main (int argc, char **argv)
 {
        g_test_init (&argc, &argv, NULL);
 
        g_test_add_func ("/ssh-agent/util/parse_public", test_parse_public);
+       g_test_add_func ("/ssh-agent/util/canon_error", test_canon_error);
 
        return g_test_run ();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]