[libvirt PATCH 03/32] util: add API for reading password from the console

Daniel P. Berrangé berrange at redhat.com
Thu Jan 23 11:42:56 UTC 2020


This imports a simpler version of GNULIB's getpass() function
impl for Windows. Note that GNULIB's impl was buggy as it
returned a static string on UNIX, and a heap allocated string
on Windows. This new impl always heap allocates.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/libvirt.c            |  9 ++++-----
 src/libvirt_private.syms |  1 +
 src/util/virutil.c       | 29 +++++++++++++++++++++++++++++
 src/util/virutil.h       |  2 ++
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/src/libvirt.c b/src/libvirt.c
index f1ffc97261..353b3a55d8 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -30,7 +30,6 @@
 
 #include <libxml/parser.h>
 #include <libxml/xpath.h>
-#include "getpass.h"
 
 #ifdef WITH_CURL
 # include <curl/curl.h>
@@ -157,9 +156,9 @@ virConnectAuthCallbackDefault(virConnectCredentialPtr cred,
             if (fflush(stdout) != 0)
                 return -1;
 
-            bufptr = getpass("");
-            if (!bufptr)
-                return -1;
+            bufptr = virGetPassword();
+            if (STREQ(bufptr, ""))
+                VIR_FREE(bufptr);
             break;
 
         default:
@@ -167,7 +166,7 @@ virConnectAuthCallbackDefault(virConnectCredentialPtr cred,
         }
 
         if (cred[i].type != VIR_CRED_EXTERNAL) {
-            cred[i].result = g_strdup(STREQ(bufptr, "") && cred[i].defresult ? cred[i].defresult : bufptr);
+            cred[i].result = bufptr ? bufptr : g_strdup(cred[i].defresult ? cred[i].defresult : "");
             cred[i].resultlen = strlen(cred[i].result);
         }
     }
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b63feb4054..fa046051a3 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3371,6 +3371,7 @@ virGetGroupList;
 virGetGroupName;
 virGetHostname;
 virGetHostnameQuiet;
+virGetPassword;
 virGetSelfLastChanged;
 virGetSystemPageSize;
 virGetSystemPageSizeKB;
diff --git a/src/util/virutil.c b/src/util/virutil.c
index 7c2c5a78f6..87ca16c088 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -28,6 +28,10 @@
 #include <poll.h>
 #include <sys/stat.h>
 
+#ifdef WIN32
+# include <conio.h>
+#endif /* WIN32 */
+
 #ifdef MAJOR_IN_MKDEV
 # include <sys/mkdev.h>
 #elif MAJOR_IN_SYSMACROS
@@ -1731,3 +1735,28 @@ virHostGetDRMRenderNode(void)
     VIR_DIR_CLOSE(driDir);
     return ret;
 }
+
+/*
+ * Get a password from the console input stream.
+ * The caller must free the returned password.
+ *
+ * Returns: the password, or NULL
+ */
+char *virGetPassword(void)
+{
+#ifdef WIN32
+    GString *pw = g_string_new("");
+
+    while (1) {
+        char c = _getch();
+        if (c == '\r')
+            break;
+
+        g_string_append_c(pw, c);
+    }
+
+    return g_string_free(pw, FALSE);
+#else /* !WIN32 */
+    return g_strdup(getpass(""));
+#endif /* ! WIN32 */
+}
diff --git a/src/util/virutil.h b/src/util/virutil.h
index 1a6ae1787a..62a53f34cb 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -159,3 +159,5 @@ char *virHostGetDRMRenderNode(void) G_GNUC_NO_INLINE;
  */
 #define VIR_ASSIGN_IS_OVERFLOW(lvalue, rvalue) \
     (((lvalue) = (rvalue)) != (rvalue))
+
+char *virGetPassword(void);
-- 
2.24.1




More information about the libvir-list mailing list