mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 15:43:32 +01:00
Extract getpass to a new lib/term library
(Term is short for terminal)
This commit is contained in:
parent
e0957022bd
commit
4e11c2ca6c
2
.gitignore
vendored
2
.gitignore
vendored
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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) || ... */
|
||||
}
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
src/lib/term/.may_include
Normal file
9
src/lib/term/.may_include
Normal 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
115
src/lib/term/getpass.c
Normal 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
13
src/lib/term/getpass.h
Normal 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
24
src/lib/term/include.am
Normal 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
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user