aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/compat.c83
-rw-r--r--src/common/compat.h2
-rw-r--r--src/common/include.am9
-rw-r--r--src/common/sandbox.c8
-rw-r--r--src/common/tortls.c8
-rw-r--r--src/common/util.c7
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;