aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-06-26 20:51:17 -0400
committerNick Mathewson <nickm@torproject.org>2018-06-26 20:51:17 -0400
commit7159edf9090e0a0e4c7d02e80b81bc00083884cc (patch)
tree49b2f6465f058b8f52cc07fedddce0ad00a3ee64 /src/lib
parent5f41bc91c6817649ebcfbecd184640aad7a5c8f1 (diff)
downloadtor-7159edf9090e0a0e4c7d02e80b81bc00083884cc.tar.gz
tor-7159edf9090e0a0e4c7d02e80b81bc00083884cc.zip
Move the escape-for-log code into src/lib/log
It doesn't need anything higher-level, and everything that needs the logs potentially needs this.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/log/escape.c132
-rw-r--r--src/lib/log/escape.h18
-rw-r--r--src/lib/log/include.am2
3 files changed, 152 insertions, 0 deletions
diff --git a/src/lib/log/escape.c b/src/lib/log/escape.c
new file mode 100644
index 0000000000..7561710309
--- /dev/null
+++ b/src/lib/log/escape.c
@@ -0,0 +1,132 @@
+/* Copyright (c) 2003, 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/log/escape.h"
+#include "lib/log/util_bug.h"
+#include "lib/string/compat_ctype.h"
+#include "lib/string/printf.h"
+#include "lib/malloc/util_malloc.h"
+
+/** Allocate and return a new string representing the contents of <b>s</b>,
+ * surrounded by quotes and using standard C escapes.
+ *
+ * Generally, we use this for logging values that come in over the network to
+ * keep them from tricking users, and for sending certain values to the
+ * controller.
+ *
+ * We trust values from the resolver, OS, configuration file, and command line
+ * to not be maliciously ill-formed. We validate incoming routerdescs and
+ * SOCKS requests and addresses from BEGIN cells as they're parsed;
+ * afterwards, we trust them as non-malicious.
+ */
+char *
+esc_for_log(const char *s)
+{
+ const char *cp;
+ char *result, *outp;
+ size_t len = 3;
+ if (!s) {
+ return tor_strdup("(null)");
+ }
+
+ for (cp = s; *cp; ++cp) {
+ switch (*cp) {
+ case '\\':
+ case '\"':
+ case '\'':
+ case '\r':
+ case '\n':
+ case '\t':
+ len += 2;
+ break;
+ default:
+ if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127)
+ ++len;
+ else
+ len += 4;
+ break;
+ }
+ }
+
+ tor_assert(len <= SSIZE_MAX);
+
+ result = outp = tor_malloc(len);
+ *outp++ = '\"';
+ for (cp = s; *cp; ++cp) {
+ /* This assertion should always succeed, since we will write at least
+ * one char here, and two chars for closing quote and nul later */
+ tor_assert((outp-result) < (ssize_t)len-2);
+ switch (*cp) {
+ case '\\':
+ case '\"':
+ case '\'':
+ *outp++ = '\\';
+ *outp++ = *cp;
+ break;
+ case '\n':
+ *outp++ = '\\';
+ *outp++ = 'n';
+ break;
+ case '\t':
+ *outp++ = '\\';
+ *outp++ = 't';
+ break;
+ case '\r':
+ *outp++ = '\\';
+ *outp++ = 'r';
+ break;
+ default:
+ if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127) {
+ *outp++ = *cp;
+ } else {
+ tor_assert((outp-result) < (ssize_t)len-4);
+ tor_snprintf(outp, 5, "\\%03o", (int)(uint8_t) *cp);
+ outp += 4;
+ }
+ break;
+ }
+ }
+
+ tor_assert((outp-result) <= (ssize_t)len-2);
+ *outp++ = '\"';
+ *outp++ = 0;
+
+ return result;
+}
+
+/** Similar to esc_for_log. Allocate and return a new string representing
+ * the first n characters in <b>chars</b>, surround by quotes and using
+ * standard C escapes. If a NUL character is encountered in <b>chars</b>,
+ * the resulting string will be terminated there.
+ */
+char *
+esc_for_log_len(const char *chars, size_t n)
+{
+ char *string = tor_strndup(chars, n);
+ char *string_escaped = esc_for_log(string);
+ tor_free(string);
+ return string_escaped;
+}
+
+/** Allocate and return a new string representing the contents of <b>s</b>,
+ * surrounded by quotes and using standard C escapes.
+ *
+ * THIS FUNCTION IS NOT REENTRANT. Don't call it from outside the main
+ * thread. Also, each call invalidates the last-returned value, so don't
+ * try log_warn(LD_GENERAL, "%s %s", escaped(a), escaped(b));
+ */
+const char *
+escaped(const char *s)
+{
+ static char *escaped_val_ = NULL;
+ tor_free(escaped_val_);
+
+ if (s)
+ escaped_val_ = esc_for_log(s);
+ else
+ escaped_val_ = NULL;
+
+ return escaped_val_;
+}
diff --git a/src/lib/log/escape.h b/src/lib/log/escape.h
new file mode 100644
index 0000000000..5d2e79d6c2
--- /dev/null
+++ b/src/lib/log/escape.h
@@ -0,0 +1,18 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-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_ESCAPE_H
+#define TOR_ESCAPE_H
+
+#include "orconfig.h"
+#include "lib/cc/compat_compiler.h"
+#include <stddef.h>
+
+char *esc_for_log(const char *string) ATTR_MALLOC;
+char *esc_for_log_len(const char *chars, size_t n) ATTR_MALLOC;
+const char *escaped(const char *string);
+
+#endif /* !defined(TOR_TORLOG_H) */
diff --git a/src/lib/log/include.am b/src/lib/log/include.am
index bbe345de7a..235c95fdf1 100644
--- a/src/lib/log/include.am
+++ b/src/lib/log/include.am
@@ -6,6 +6,7 @@ noinst_LIBRARIES += src/lib/libtor-log-testing.a
endif
src_lib_libtor_log_a_SOURCES = \
+ src/lib/log/escape.c \
src/lib/log/ratelim.c \
src/lib/log/torlog.c \
src/lib/log/util_bug.c
@@ -19,6 +20,7 @@ src/lib/log/torlog.$(OBJEXT) \
src/lib/log/src_lib_libtor_log_testing_a-torlog.$(OBJEXT): micro-revision.i
noinst_HEADERS += \
+ src/lib/log/escape.h \
src/lib/log/ratelim.h \
src/lib/log/torlog.h \
src/lib/log/util_bug.h