diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/compat.c | 83 | ||||
-rw-r--r-- | src/common/compat.h | 2 | ||||
-rw-r--r-- | src/common/include.am | 9 | ||||
-rw-r--r-- | src/common/sandbox.c | 8 | ||||
-rw-r--r-- | src/common/tortls.c | 8 | ||||
-rw-r--r-- | src/common/util.c | 7 |
6 files changed, 111 insertions, 6 deletions
diff --git a/src/common/compat.c b/src/common/compat.c index ac4732179e..91d117d7b5 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -67,6 +67,13 @@ #ifdef HAVE_CRT_EXTERNS_H #include <crt_externs.h> #endif +#ifdef HAVE_READPASSPHRASE_H +#include <readpassphrase.h> +#elif !defined(_WIN32) +#include "readpassphrase.h" +#else +#include <conio.h> +#endif #ifndef HAVE_GETTIMEOFDAY #ifdef HAVE_FTIME @@ -3275,3 +3282,79 @@ tor_sleep_msec(int msec) } #endif +/** 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 +} diff --git a/src/common/compat.h b/src/common/compat.h index acf5ffd1ae..e1b860f229 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -708,6 +708,8 @@ STATIC int tor_ersatz_socketpair(int family, int type, int protocol, #endif #endif +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 "compat_threads.h" diff --git a/src/common/include.am b/src/common/include.am index b782310663..789f4003c9 100644 --- a/src/common/include.am +++ b/src/common/include.am @@ -51,6 +51,12 @@ if THREADS_WIN32 threads_impl_source=src/common/compat_winthreads.c endif +if BUILD_READPASSPHRASE_C +readpassphrase_source=src/ext/readpassphrase.c +else +readpassphrase_source= +endif + LIBOR_A_SOURCES = \ src/common/address.c \ src/common/backtrace.c \ @@ -67,7 +73,8 @@ LIBOR_A_SOURCES = \ src/ext/csiphash.c \ src/ext/trunnel/trunnel.c \ $(libor_extra_source) \ - $(threads_impl_source) + $(threads_impl_source) \ + $(readpassphrase_source) src/common/log.o: micro-revision.i diff --git a/src/common/sandbox.c b/src/common/sandbox.c index cdb4521c82..161eab7aad 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -129,7 +129,15 @@ static int filter_nopar_gen[] = { SCMP_SYS(clone), SCMP_SYS(epoll_create), SCMP_SYS(epoll_wait), +#ifdef HAVE_EVENTFD SCMP_SYS(eventfd2), +#endif +#ifdef HAVE_PIPE2 + SCMP_SYS(pipe2), +#endif +#ifdef HAVE_PIPE + SCMP_SYS(pipe), +#endif SCMP_SYS(fcntl), SCMP_SYS(fstat), #ifdef __NR_fstat64 diff --git a/src/common/tortls.c b/src/common/tortls.c index 4cfe94e182..bd0eaffa27 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -2631,16 +2631,16 @@ SSL_get_server_random(SSL *s, uint8_t *out, size_t len) static size_t SSL_SESSION_get_master_key(SSL_SESSION *s, uint8_t *out, size_t len) { + tor_assert(s); if (len == 0) return s->master_key_length; tor_assert(len == (size_t)s->master_key_length); - tor_assert(s->master_key); + tor_assert(out); memcpy(out, s->master_key, len); return len; } #endif - /** Set the DIGEST256_LEN buffer at <b>secrets_out</b> to the value used in * the v3 handshake to prove that the client knows the TLS secrets for the * connection <b>tls</b>. Return 0 on success, -1 on failure. @@ -2676,7 +2676,9 @@ tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out)) tor_assert(r == client_random_len); } { - size_t r = SSL_get_server_random(ssl, buf+client_random_len, server_random_len); + size_t r = SSL_get_server_random(ssl, + buf+client_random_len, + server_random_len); tor_assert(r == server_random_len); } uint8_t *master_key = tor_malloc_zero(master_key_len); diff --git a/src/common/util.c b/src/common/util.c index 942d0c290e..449015054f 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1036,6 +1036,9 @@ string_is_valid_ipv6_address(const char *string) /** Return true iff <b>string</b> matches a pattern of DNS names * that we allow Tor clients to connect to. + * + * Note: This allows certain technically invalid characters ('_') to cope + * with misconfigured zones that have been encountered in the wild. */ int string_is_valid_hostname(const char *string) @@ -1048,7 +1051,7 @@ string_is_valid_hostname(const char *string) smartlist_split_string(components,string,".",0,0); SMARTLIST_FOREACH_BEGIN(components, char *, c) { - if (c[0] == '-') { + if ((c[0] == '-') || (*c == '_')) { result = 0; break; } @@ -1057,7 +1060,7 @@ string_is_valid_hostname(const char *string) if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') || (*c >= '0' && *c <= '9') || - (*c == '-')) + (*c == '-') || (*c == '_')) c++; else result = 0; |