]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: add API for reading password from the console
authorDaniel P. Berrangé <berrange@redhat.com>
Tue, 14 Jan 2020 10:40:52 +0000 (10:40 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Wed, 29 Jan 2020 14:51:39 +0000 (14:51 +0000)
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.

Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/libvirt.c
src/libvirt_private.syms
src/util/virutil.c
src/util/virutil.h
tools/virsh-secret.c

index 04f9fd7ab177754034569e29afef747cade44a11..2d02808a899a112f023186c542b1187852353e03 100644 (file)
@@ -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);
         }
     }
index 970f412527339b20bfcae46ebfb985e72cfebd6a..2a61eba3e1b41b9189636d4cd9ec7ecaf812b68f 100644 (file)
@@ -3380,6 +3380,7 @@ virGetGroupList;
 virGetGroupName;
 virGetHostname;
 virGetHostnameQuiet;
+virGetPassword;
 virGetSelfLastChanged;
 virGetSystemPageSize;
 virGetSystemPageSizeKB;
index 7c2c5a78f663e026405985675881b5154d8d9893..87ca16c088ceb496743240ba223c9bc52aa910d7 100644 (file)
 #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 */
+}
index 1a6ae1787a81f029de877defb42489dc42fedfd9..62a53f34cb5c94e616d8780158beebc521f9899f 100644 (file)
@@ -159,3 +159,5 @@ char *virHostGetDRMRenderNode(void) G_GNUC_NO_INLINE;
  */
 #define VIR_ASSIGN_IS_OVERFLOW(lvalue, rvalue) \
     (((lvalue) = (rvalue)) != (rvalue))
+
+char *virGetPassword(void);
index 00a434e997511bc1dc7f5e0774192dd6c56849e9..be4adc416ec349aeca2e51f21032041fce340897 100644 (file)
@@ -250,7 +250,7 @@ cmdSecretSetValue(vshControl *ctl, const vshCmd *cmd)
         vshPrint(ctl, "%s", _("Enter new value for secret:"));
         fflush(stdout);
 
-        if (!(file_buf = getpass(""))) {
+        if (!(file_buf = virGetPassword())) {
             vshError(ctl, "%s", _("Failed to read secret"));
             return false;
         }