Browse Source

Extract getpass to a new lib/term library

(Term is short for terminal)
Nick Mathewson 5 years ago
parent
commit
4e11c2ca6c

+ 2 - 0
.gitignore

@@ -205,6 +205,8 @@ uptime-*.json
 /src/lib/libtor-string-testing.a
 /src/lib/libtor-smartlist-core.a
 /src/lib/libtor-smartlist-core-testing.a
+/src/lib/libtor-term.a
+/src/lib/libtor-term-testing.a
 /src/lib/libtor-thread.a
 /src/lib/libtor-thread-testing.a
 /src/lib/libtor-time.a

+ 2 - 0
Makefile.am

@@ -56,6 +56,7 @@ TOR_UTIL_LIBS = \
 	src/lib/libtor-lock.a \
 	src/lib/libtor-fdio.a \
 	src/lib/libtor-string.a \
+	src/lib/libtor-term.a \
 	src/lib/libtor-smartlist-core.a \
 	src/lib/libtor-malloc.a \
 	src/lib/libtor-wallclock.a \
@@ -79,6 +80,7 @@ TOR_UTIL_TESTING_LIBS = \
 	src/lib/libtor-math-testing.a \
         src/lib/libtor-meminfo-testing.a \
 	src/lib/libtor-osinfo-testing.a \
+	src/lib/libtor-term-testing.a \
 	src/lib/libtor-log-testing.a \
 	src/lib/libtor-lock-testing.a \
 	src/lib/libtor-fdio-testing.a \

+ 0 - 102
src/common/compat.c

@@ -67,31 +67,6 @@
 #include <sys/capability.h>
 #endif
 
-#ifdef _WIN32
-#include <conio.h>
-#include <wchar.h>
-/* Some mingw headers lack these. :p */
-#if defined(HAVE_DECL__GETWCH) && !HAVE_DECL__GETWCH
-wint_t _getwch(void);
-#endif
-#ifndef WEOF
-#define WEOF (wchar_t)(0xFFFF)
-#endif
-#if defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY
-static inline void
-SecureZeroMemory(PVOID ptr, SIZE_T cnt)
-{
-  volatile char *vcptr = (volatile char*)ptr;
-  while (cnt--)
-    *vcptr++ = 0;
-}
-#endif /* defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY */
-#elif defined(HAVE_READPASSPHRASE_H)
-#include <readpassphrase.h>
-#else
-#include "tor_readpassphrase.h"
-#endif /* defined(_WIN32) || ... */
-
 /* Includes for the process attaching prevention */
 #if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
 /* Only use the linux prctl;  the IRIX prctl is totally different */
@@ -131,80 +106,3 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
 /*
  *   Process control
  */
-
-/** Emit the password prompt <b>prompt</b>, then read up to <b>buflen</b>
- * bytes of passphrase into <b>output</b>. Return the number of bytes in
- * the passphrase, excluding terminating NUL.
- */
-ssize_t
-tor_getpass(const char *prompt, char *output, size_t buflen)
-{
-  tor_assert(buflen <= SSIZE_MAX);
-  tor_assert(buflen >= 1);
-#if defined(HAVE_READPASSPHRASE)
-  char *pwd = readpassphrase(prompt, output, buflen, RPP_ECHO_OFF);
-  if (pwd == NULL)
-    return -1;
-  return strlen(pwd);
-#elif defined(_WIN32)
-  int r = -1;
-  while (*prompt) {
-    _putch(*prompt++);
-  }
-
-  tor_assert(buflen <= INT_MAX);
-  wchar_t *buf = tor_calloc(buflen, sizeof(wchar_t));
-
-  wchar_t *ptr = buf, *lastch = buf + buflen - 1;
-  while (ptr < lastch) {
-    wint_t ch = _getwch();
-    switch (ch) {
-      case '\r':
-      case '\n':
-      case WEOF:
-        goto done_reading;
-      case 3:
-        goto done; /* Can't actually read ctrl-c this way. */
-      case '\b':
-        if (ptr > buf)
-          --ptr;
-        continue;
-      case 0:
-      case 0xe0:
-        ch = _getwch(); /* Ignore; this is a function or arrow key */
-        break;
-      default:
-        *ptr++ = ch;
-        break;
-    }
-  }
- done_reading:
-  ;
-
-#ifndef WC_ERR_INVALID_CHARS
-#define WC_ERR_INVALID_CHARS 0x80
-#endif
-
-  /* Now convert it to UTF-8 */
-  r = WideCharToMultiByte(CP_UTF8,
-                          WC_NO_BEST_FIT_CHARS|WC_ERR_INVALID_CHARS,
-                          buf, (int)(ptr-buf),
-                          output, (int)(buflen-1),
-                          NULL, NULL);
-  if (r <= 0) {
-    r = -1;
-    goto done;
-  }
-
-  tor_assert(r < (int)buflen);
-
-  output[r] = 0;
-
- done:
-  SecureZeroMemory(buf, sizeof(wchar_t)*buflen);
-  tor_free(buf);
-  return r;
-#else
-#error "No implementation for tor_getpass found!"
-#endif /* defined(HAVE_READPASSPHRASE) || ... */
-}

+ 0 - 2
src/common/compat.h

@@ -86,8 +86,6 @@ typedef enum {
 
 /* ===== OS compatibility */
 
-ssize_t tor_getpass(const char *prompt, char *output, size_t buflen);
-
 /* This needs some of the declarations above so we include it here. */
 #include "lib/thread/threads.h"
 

+ 1 - 8
src/common/include.am

@@ -17,20 +17,13 @@ else
 libor_extra_source=
 endif
 
-if BUILD_READPASSPHRASE_C
-readpassphrase_source=src/ext/readpassphrase.c
-else
-readpassphrase_source=
-endif
-
 LIBOR_A_SRC = \
   src/common/address_set.c				\
   src/common/compat.c					\
   src/common/util.c					\
   src/common/token_bucket.c				\
   src/common/workqueue.c				\
-  $(libor_extra_source)					\
-  $(readpassphrase_source)
+  $(libor_extra_source)
 
 src/common/src_common_libor_testing_a-log.$(OBJEXT) \
   src/common/log.$(OBJEXT): micro-revision.i

+ 1 - 0
src/include.am

@@ -24,6 +24,7 @@ include src/lib/process/include.am
 include src/lib/sandbox/include.am
 include src/lib/string/include.am
 include src/lib/smartlist_core/include.am
+include src/lib/term/include.am
 include src/lib/testsupport/include.am
 include src/lib/thread/include.am
 include src/lib/time/include.am

+ 9 - 0
src/lib/term/.may_include

@@ -0,0 +1,9 @@
+orconfig.h
+
+lib/cc/*.h
+lib/log/*.h
+lib/term/*.h
+lib/malloc/*.h
+
+# From src/ext
+tor_readpassphrase.h

+ 115 - 0
src/lib/term/getpass.c

@@ -0,0 +1,115 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/term/getpass.h"
+
+#include "lib/log/util_bug.h"
+#include "lib/malloc/util_malloc.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#include <conio.h>
+#include <wchar.h>
+/* Some mingw headers lack these. :p */
+#if defined(HAVE_DECL__GETWCH) && !HAVE_DECL__GETWCH
+wint_t _getwch(void);
+#endif
+#ifndef WEOF
+#define WEOF (wchar_t)(0xFFFF)
+#endif
+#if defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY
+static inline void
+SecureZeroMemory(PVOID ptr, SIZE_T cnt)
+{
+  volatile char *vcptr = (volatile char*)ptr;
+  while (cnt--)
+    *vcptr++ = 0;
+}
+#endif /* defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY */
+#elif defined(HAVE_READPASSPHRASE_H)
+#include <readpassphrase.h>
+#else
+#include "tor_readpassphrase.h"
+#endif /* defined(_WIN32) || ... */
+
+#include <stdlib.h>
+#include <string.h>
+
+/** Emit the password prompt <b>prompt</b>, then read up to <b>buflen</b>
+ * bytes of passphrase into <b>output</b>. Return the number of bytes in
+ * the passphrase, excluding terminating NUL.
+ */
+ssize_t
+tor_getpass(const char *prompt, char *output, size_t buflen)
+{
+  tor_assert(buflen <= SSIZE_MAX);
+  tor_assert(buflen >= 1);
+#if defined(HAVE_READPASSPHRASE)
+  char *pwd = readpassphrase(prompt, output, buflen, RPP_ECHO_OFF);
+  if (pwd == NULL)
+    return -1;
+  return strlen(pwd);
+#elif defined(_WIN32)
+  int r = -1;
+  while (*prompt) {
+    _putch(*prompt++);
+  }
+
+  tor_assert(buflen <= INT_MAX);
+  wchar_t *buf = tor_calloc(buflen, sizeof(wchar_t));
+
+  wchar_t *ptr = buf, *lastch = buf + buflen - 1;
+  while (ptr < lastch) {
+    wint_t ch = _getwch();
+    switch (ch) {
+      case '\r':
+      case '\n':
+      case WEOF:
+        goto done_reading;
+      case 3:
+        goto done; /* Can't actually read ctrl-c this way. */
+      case '\b':
+        if (ptr > buf)
+          --ptr;
+        continue;
+      case 0:
+      case 0xe0:
+        ch = _getwch(); /* Ignore; this is a function or arrow key */
+        break;
+      default:
+        *ptr++ = ch;
+        break;
+    }
+  }
+ done_reading:
+  ;
+
+#ifndef WC_ERR_INVALID_CHARS
+#define WC_ERR_INVALID_CHARS 0x80
+#endif
+
+  /* Now convert it to UTF-8 */
+  r = WideCharToMultiByte(CP_UTF8,
+                          WC_NO_BEST_FIT_CHARS|WC_ERR_INVALID_CHARS,
+                          buf, (int)(ptr-buf),
+                          output, (int)(buflen-1),
+                          NULL, NULL);
+  if (r <= 0) {
+    r = -1;
+    goto done;
+  }
+
+  tor_assert(r < (int)buflen);
+
+  output[r] = 0;
+
+ done:
+  SecureZeroMemory(buf, sizeof(wchar_t)*buflen);
+  tor_free(buf);
+  return r;
+#else
+#error "No implementation for tor_getpass found!"
+#endif /* defined(HAVE_READPASSPHRASE) || ... */
+}

+ 13 - 0
src/lib/term/getpass.h

@@ -0,0 +1,13 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_GETPASS_H
+#define TOR_GETPASS_H
+
+#include "lib/cc/torint.h"
+
+ssize_t tor_getpass(const char *prompt, char *output, size_t buflen);
+
+#endif

+ 24 - 0
src/lib/term/include.am

@@ -0,0 +1,24 @@
+
+noinst_LIBRARIES += src/lib/libtor-term.a
+
+if UNITTESTS_ENABLED
+noinst_LIBRARIES += src/lib/libtor-term-testing.a
+endif
+
+if BUILD_READPASSPHRASE_C
+readpassphrase_source=src/ext/readpassphrase.c
+else
+readpassphrase_source=
+endif
+
+src_lib_libtor_term_a_SOURCES =			\
+	src/lib/term/getpass.c			\
+	$(readpassphrase_source)
+
+src_lib_libtor_term_testing_a_SOURCES = \
+	$(src_lib_libtor_term_a_SOURCES)
+src_lib_libtor_term_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
+src_lib_libtor_term_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
+
+noinst_HEADERS +=					\
+	src/lib/term/getpass.h

+ 1 - 0
src/or/routerkeys.c

@@ -21,6 +21,7 @@
 #include "lib/crypt_ops/crypto_pwbox.h"
 #include "or/routerkeys.h"
 #include "or/torcert.h"
+#include "lib/term/getpass.h"
 
 #define ENC_KEY_HEADER "Boxed Ed25519 key"
 #define ENC_KEY_TAG "master"