Extract getpass to a new lib/term library

(Term is short for terminal)
This commit is contained in:
Nick Mathewson 2018-06-29 10:50:05 -04:00
parent e0957022bd
commit 4e11c2ca6c
11 changed files with 168 additions and 112 deletions

2
.gitignore vendored
View File

@ -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

View File

@ -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 \

View File

@ -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) || ... */
}

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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
src/lib/term/getpass.c Normal file
View File

@ -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
src/lib/term/getpass.h Normal file
View File

@ -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
src/lib/term/include.am Normal file
View File

@ -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

View File

@ -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"