Blob Blame History Raw
From e65b2e73ff4f3c6bf692d12c34a0188aa51b552b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 16 Jun 2016 21:22:16 +0100
Subject: [PATCH] p2v: ssh: Print ssh error if user gives invalid conversion
 server (RHBZ#1167916).

Instead of throwing away the ssh error and printing the generic
message "unexpected end of file waiting for password prompt", we
capture the ssh error and print it.  The user will see the ssh
diagnostic, eg. "No route to host".

(cherry picked from commit 8717a110120f84973f1148adf48e59222cf45e73)
---
 p2v/ssh.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/p2v/ssh.c b/p2v/ssh.c
index ce2b17b..d9210f3 100644
--- a/p2v/ssh.c
+++ b/p2v/ssh.c
@@ -97,6 +97,7 @@ static void compile_regexps (void) __attribute__((constructor));
 static void free_regexps (void) __attribute__((destructor));
 
 static pcre *password_re;
+static pcre *ssh_message_re;
 static pcre *prompt_re;
 static pcre *version_re;
 static pcre *feature_libguestfs_rewrite_re;
@@ -138,6 +139,7 @@ compile_regexps (void)
   } while (0)
 
   COMPILE (password_re, "password:", 0);
+  COMPILE (ssh_message_re, "(ssh: .*)", 0);
   /* The magic synchronization strings all match this expression.  See
    * start_ssh function below.
    */
@@ -156,6 +158,7 @@ static void
 free_regexps (void)
 {
   pcre_free (password_re);
+  pcre_free (ssh_message_re);
   pcre_free (prompt_re);
   pcre_free (version_re);
   pcre_free (feature_libguestfs_rewrite_re);
@@ -350,10 +353,14 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt)
 
   if (using_password_auth &&
       config->password && strlen (config->password) > 0) {
+    CLEANUP_FREE char *ssh_message = NULL;
+
     /* Wait for the password prompt. */
+  wait_password_again:
     switch (mexp_expect (h,
                          (mexp_regexp[]) {
                            { 100, .re = password_re },
+                           { 101, .re = ssh_message_re },
                            { 0 }
                          }, ovector, ovecsize)) {
     case 100:                   /* Got password prompt. */
@@ -364,9 +371,23 @@ start_ssh (struct config *config, char **extra_args, int wait_prompt)
       }
       break;
 
+    case 101:
+      free (ssh_message);
+      ssh_message = strndup (&h->buffer[ovector[2]], ovector[3]-ovector[2]);
+      goto wait_password_again;
+
     case MEXP_EOF:
       mexp_close (h);
-      set_ssh_error ("unexpected end of file waiting for password prompt");
+      /* This is where we get to if the user enters an incorrect or
+       * impossible hostname or port number.  Hopefully ssh printed an
+       * error message, and we picked it up and put it in
+       * 'ssh_message' in case 101 above.  If not we have to print a
+       * generic error instead.
+       */
+      if (ssh_message)
+        set_ssh_error ("%s", ssh_message);
+      else
+        set_ssh_error ("unknown ssh error");
       return NULL;
 
     case MEXP_TIMEOUT:
-- 
2.7.4