diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-06-29 10:50:05 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-06-29 12:21:52 -0400 |
commit | 4e11c2ca6c9396bf8462acb13e01e3d27e4752cc (patch) | |
tree | 8717dc2fd38dc7ac6026e951883d41a8635bde36 /src/lib/term | |
parent | e0957022bd108696a941bdb284420fc55cbcf187 (diff) | |
download | tor-4e11c2ca6c9396bf8462acb13e01e3d27e4752cc.tar.gz tor-4e11c2ca6c9396bf8462acb13e01e3d27e4752cc.zip |
Extract getpass to a new lib/term library
(Term is short for terminal)
Diffstat (limited to 'src/lib/term')
-rw-r--r-- | src/lib/term/.may_include | 9 | ||||
-rw-r--r-- | src/lib/term/getpass.c | 115 | ||||
-rw-r--r-- | src/lib/term/getpass.h | 13 | ||||
-rw-r--r-- | src/lib/term/include.am | 24 |
4 files changed, 161 insertions, 0 deletions
diff --git a/src/lib/term/.may_include b/src/lib/term/.may_include new file mode 100644 index 0000000000..c93a06e59e --- /dev/null +++ b/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 diff --git a/src/lib/term/getpass.c b/src/lib/term/getpass.c new file mode 100644 index 0000000000..10c99914f8 --- /dev/null +++ b/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) || ... */ +} diff --git a/src/lib/term/getpass.h b/src/lib/term/getpass.h new file mode 100644 index 0000000000..9d03f7036c --- /dev/null +++ b/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 diff --git a/src/lib/term/include.am b/src/lib/term/include.am new file mode 100644 index 0000000000..55fe548ebc --- /dev/null +++ b/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 |