aboutsummaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/Makefile.nmake5
-rw-r--r--src/tools/include.am80
-rw-r--r--src/tools/tor-checkkey.c89
-rw-r--r--src/tools/tor-fw-helper/README10
-rw-r--r--src/tools/tor-gencert.c110
-rw-r--r--src/tools/tor-print-ed-signing-cert.c65
-rw-r--r--src/tools/tor-resolve.c72
-rw-r--r--src/tools/tor_runner.c112
8 files changed, 317 insertions, 226 deletions
diff --git a/src/tools/Makefile.nmake b/src/tools/Makefile.nmake
index fda1990e0b..e223d9b135 100644
--- a/src/tools/Makefile.nmake
+++ b/src/tools/Makefile.nmake
@@ -1,4 +1,4 @@
-all: tor-resolve.exe tor-gencert.exe
+all: tor-resolve.exe tor-gencert.exe tor-print-ed-signing-cert.exe
CFLAGS = /I ..\win32 /I ..\..\..\build-alpha\include /I ..\common /I ..\or
@@ -15,5 +15,8 @@ tor-gencert.exe: tor-gencert.obj
tor-resolve.exe: tor-resolve.obj
$(CC) $(CFLAGS) $(LIBS) ..\common\*.lib tor-resolve.obj
+tor-print-ed-signing-cert.exe: tor-print-ed-signing-cert.obj
+ $(CC) $(CFLAGS) $(LIBS) ..\common\*.lib tor-print-ed-signing-cert.obj
+
clean:
del *.obj *.lib *.exe
diff --git a/src/tools/include.am b/src/tools/include.am
index d0185b5887..f7aa7e0d1e 100644
--- a/src/tools/include.am
+++ b/src/tools/include.am
@@ -1,56 +1,68 @@
-bin_PROGRAMS+= src/tools/tor-resolve src/tools/tor-gencert
-noinst_PROGRAMS+= src/tools/tor-checkkey
+bin_PROGRAMS+= src/tools/tor-resolve src/tools/tor-print-ed-signing-cert
if COVERAGE_ENABLED
-noinst_PROGRAMS+= src/tools/tor-cov-resolve src/tools/tor-cov-gencert
+noinst_PROGRAMS+= src/tools/tor-cov-resolve
endif
src_tools_tor_resolve_SOURCES = src/tools/tor-resolve.c
src_tools_tor_resolve_LDFLAGS =
-src_tools_tor_resolve_LDADD = src/common/libor.a \
- src/common/libor-ctime.a \
- @TOR_LIB_MATH@ @TOR_LIB_WS32@
+src_tools_tor_resolve_LDADD = \
+ $(TOR_UTIL_LIBS) \
+ $(rust_ldadd) \
+ @TOR_LIB_MATH@ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_USERENV@
if COVERAGE_ENABLED
src_tools_tor_cov_resolve_SOURCES = src/tools/tor-resolve.c
src_tools_tor_cov_resolve_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
src_tools_tor_cov_resolve_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
-src_tools_tor_cov_resolve_LDADD = src/common/libor-testing.a \
- src/common/libor-ctime-testing.a \
+src_tools_tor_cov_resolve_LDADD = \
+ $(TOR_UTIL_TESTING_LIBS) \
@TOR_LIB_MATH@ @TOR_LIB_WS32@
endif
+if USE_NSS
+# ...
+else
+bin_PROGRAMS += src/tools/tor-gencert
src_tools_tor_gencert_SOURCES = src/tools/tor-gencert.c
-src_tools_tor_gencert_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@
-src_tools_tor_gencert_LDADD = src/common/libor.a src/common/libor-crypto.a \
- src/common/libor-ctime.a \
- $(LIBKECCAK_TINY) \
- $(LIBDONNA) \
- @TOR_LIB_MATH@ @TOR_ZLIB_LIBS@ @TOR_OPENSSL_LIBS@ \
- @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
+src_tools_tor_gencert_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB)
+src_tools_tor_gencert_LDADD = \
+ $(TOR_CRYPTO_LIBS) \
+ $(TOR_UTIL_LIBS) \
+ $(rust_ldadd) \
+ @TOR_LIB_MATH@ @TOR_ZLIB_LIBS@ $(TOR_LIBS_CRYPTLIB) \
+ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ @CURVE25519_LIBS@
+endif
+
+src_tools_tor_print_ed_signing_cert_SOURCES = src/tools/tor-print-ed-signing-cert.c
+src_tools_tor_print_ed_signing_cert_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@
+src_tools_tor_print_ed_signing_cert_LDADD = \
+ src/trunnel/libor-trunnel.a \
+ $(TOR_CRYPTO_LIBS) \
+ $(TOR_UTIL_LIBS) \
+ @TOR_LIB_MATH@ $(TOR_LIBS_CRYPTLIB) \
+ @TOR_LIB_WS32@ @TOR_LIB_USERENV@ @TOR_LIB_GDI@
+if USE_NSS
+# ...
+else
if COVERAGE_ENABLED
+noinst_PROGRAMS += src/tools/tor-cov-gencert
src_tools_tor_cov_gencert_SOURCES = src/tools/tor-gencert.c
src_tools_tor_cov_gencert_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
src_tools_tor_cov_gencert_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
-src_tools_tor_cov_gencert_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@
-src_tools_tor_cov_gencert_LDADD = src/common/libor-testing.a \
- src/common/libor-crypto-testing.a \
- src/common/libor-ctime-testing.a \
- $(LIBKECCAK_TINY) \
- $(LIBDONNA) \
- @TOR_LIB_MATH@ @TOR_ZLIB_LIBS@ @TOR_OPENSSL_LIBS@ \
- @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
+src_tools_tor_cov_gencert_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB)
+src_tools_tor_cov_gencert_LDADD = \
+ $(TOR_CRYPTO_TESTING_LIBS) \
+ $(TOR_UTIL_TESTING_LIBS) \
+ @TOR_LIB_MATH@ @TOR_ZLIB_LIBS@ $(TOR_LIBS_CRYPTLIB) \
+ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
+endif
endif
-src_tools_tor_checkkey_SOURCES = src/tools/tor-checkkey.c
-src_tools_tor_checkkey_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@
-src_tools_tor_checkkey_LDADD = src/common/libor.a \
- src/common/libor-ctime.a \
- src/common/libor-crypto.a \
- $(LIBKECCAK_TINY) \
- $(LIBDONNA) \
- @TOR_LIB_MATH@ @TOR_ZLIB_LIBS@ @TOR_OPENSSL_LIBS@ \
- @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
-
-EXTRA_DIST += src/tools/tor-fw-helper/README
+if BUILD_LIBTORRUNNER
+noinst_LIBRARIES += src/tools/libtorrunner.a
+src_tools_libtorrunner_a_SOURCES = \
+ src/tools/tor_runner.c \
+ src/feature/api/tor_api.c
+endif
diff --git a/src/tools/tor-checkkey.c b/src/tools/tor-checkkey.c
deleted file mode 100644
index 3e16fd0336..0000000000
--- a/src/tools/tor-checkkey.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 2008-2015, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-#include "orconfig.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "crypto.h"
-#include "torlog.h"
-#include "util.h"
-#include "compat.h"
-#include "compat_openssl.h"
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-
-int
-main(int c, char **v)
-{
- crypto_pk_t *env;
- char *str;
- RSA *rsa;
- int wantdigest=0;
- int fname_idx;
- char *fname=NULL;
- init_logging(1);
-
- if (c < 2) {
- fprintf(stderr, "Hi. I'm tor-checkkey. Tell me a filename that "
- "has a PEM-encoded RSA public key (like in a cert) and I'll "
- "dump the modulus. Use the --digest option too and I'll "
- "dump the digest.\n");
- return 1;
- }
-
- if (crypto_global_init(0, NULL, NULL)) {
- fprintf(stderr, "Couldn't initialize crypto library.\n");
- return 1;
- }
-
- if (!strcmp(v[1], "--digest")) {
- wantdigest = 1;
- fname_idx = 2;
- if (c<3) {
- fprintf(stderr, "too few arguments");
- return 1;
- }
- } else {
- wantdigest = 0;
- fname_idx = 1;
- }
-
- fname = expand_filename(v[fname_idx]);
- str = read_file_to_str(fname, 0, NULL);
- tor_free(fname);
- if (!str) {
- fprintf(stderr, "Couldn't read %s\n", v[fname_idx]);
- return 1;
- }
-
- env = crypto_pk_new();
- if (crypto_pk_read_public_key_from_string(env, str, strlen(str))<0) {
- fprintf(stderr, "Couldn't parse key.\n");
- return 1;
- }
- tor_free(str);
-
- if (wantdigest) {
- char digest[HEX_DIGEST_LEN+1];
- if (crypto_pk_get_fingerprint(env, digest, 0)<0)
- return 1;
- printf("%s\n",digest);
- } else {
- rsa = crypto_pk_get_rsa_(env);
-
- const BIGNUM *rsa_n;
-#ifdef OPENSSL_1_1_API
- const BIGNUM *rsa_e, *rsa_d;
- RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
-#else
- rsa_n = rsa->n;
-#endif
- str = BN_bn2hex(rsa_n);
-
- printf("%s\n", str);
- }
-
- return 0;
-}
-
diff --git a/src/tools/tor-fw-helper/README b/src/tools/tor-fw-helper/README
deleted file mode 100644
index 6a1ecaa1e4..0000000000
--- a/src/tools/tor-fw-helper/README
+++ /dev/null
@@ -1,10 +0,0 @@
-
-We no longer recommend the use of this tool. Instead, please use the
-pure-Go version of tor-fw-helper available at
- https://gitweb.torproject.org/tor-fw-helper.git
-
-Why?
-
-The C code here was fine, but frankly: we don't trust the underlying
-libraries. They don't seem to have been written with network security
-in mind, and we have very little faith in their safety.
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index db308485e6..25113420df 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2015, The Tor Project, Inc. */
+/* Copyright (c) 2007-2019, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -13,8 +13,11 @@
#include <unistd.h>
#endif
-#include "compat.h"
+#include "lib/cc/compat_compiler.h"
+#include "lib/crypt_ops/crypto_init.h"
+#include "lib/crypt_ops/crypto_openssl_mgt.h"
+#ifdef ENABLE_OPENSSL
/* Some versions of OpenSSL declare X509_STORE_CTX_set_verify_cb twice in
* x509.h and x509_vfy.h. Suppress the GCC warning so we can build with
* -Wredundant-decl. */
@@ -28,20 +31,24 @@ DISABLE_GCC_WARNING(redundant-decls)
#include <openssl/err.h>
ENABLE_GCC_WARNING(redundant-decls)
+#endif
#include <errno.h>
-#if 0
-#include <stdlib.h>
-#include <stdarg.h>
-#include <assert.h>
-#endif
-#include "compat.h"
-#include "util.h"
-#include "torlog.h"
-#include "crypto.h"
-#include "address.h"
-#include "util_format.h"
+#include "lib/crypt_ops/crypto_digest.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/crypt_ops/crypto_rsa.h"
+#include "lib/crypt_ops/crypto_util.h"
+#include "lib/encoding/binascii.h"
+#include "lib/encoding/time_fmt.h"
+#include "lib/fs/files.h"
+#include "lib/log/log.h"
+#include "lib/malloc/malloc.h"
+#include "lib/net/address.h"
+#include "lib/net/inaddr.h"
+#include "lib/net/resolve.h"
+#include "lib/string/compat_string.h"
+#include "lib/string/printf.h"
#define IDENTITY_KEY_BITS 3072
#define SIGNING_KEY_BITS 2048
@@ -76,29 +83,6 @@ show_help(void)
"[--passphrase-fd <fd>]\n");
}
-/* XXXX copied from crypto.c */
-static void
-crypto_log_errors(int severity, const char *doing)
-{
- unsigned long err;
- const char *msg, *lib, *func;
- while ((err = ERR_get_error()) != 0) {
- msg = (const char*)ERR_reason_error_string(err);
- lib = (const char*)ERR_lib_error_string(err);
- func = (const char*)ERR_func_error_string(err);
- if (!msg) msg = "(null)";
- if (!lib) lib = "(null)";
- if (!func) func = "(null)";
- if (doing) {
- tor_log(severity, LD_CRYPTO, "crypto error while %s: %s (in %s:%s)",
- doing, msg, lib, func);
- } else {
- tor_log(severity, LD_CRYPTO, "crypto error: %s (in %s:%s)",
- msg, lib, func);
- }
- }
-}
-
/** Read the passphrase from the passphrase fd. */
static int
load_passphrase(void)
@@ -106,7 +90,7 @@ load_passphrase(void)
char *cp;
char buf[1024]; /* "Ought to be enough for anybody." */
memset(buf, 0, sizeof(buf)); /* should be needless */
- ssize_t n = read_all(passphrase_fd, buf, sizeof(buf), 0);
+ ssize_t n = read_all_from_fd(passphrase_fd, buf, sizeof(buf));
if (n < 0) {
log_err(LD_GENERAL, "Couldn't read from passphrase fd: %s",
strerror(errno));
@@ -191,19 +175,23 @@ parse_commandline(int argc, char **argv)
} else if (!strcmp(argv[i], "-v")) {
verbose = 1;
} else if (!strcmp(argv[i], "-a")) {
- uint32_t addr;
+ tor_addr_t addr;
uint16_t port;
- char b[INET_NTOA_BUF_LEN];
- struct in_addr in;
if (i+1>=argc) {
fprintf(stderr, "No argument to -a\n");
return 1;
}
- if (addr_port_lookup(LOG_ERR, argv[++i], NULL, &addr, &port)<0)
+ const char *addr_arg = argv[++i];
+ if (tor_addr_port_lookup(addr_arg, &addr, &port)<0) {
+ fprintf(stderr, "Can't resolve address/port for %s", addr_arg);
return 1;
- in.s_addr = htonl(addr);
- tor_inet_ntoa(&in, b, sizeof(b));
- tor_asprintf(&address, "%s:%d", b, (int)port);
+ }
+ if (tor_addr_family(&addr) != AF_INET) {
+ fprintf(stderr, "%s must resolve to an IPv4 address", addr_arg);
+ return 1;
+ }
+ tor_free(address);
+ address = tor_strdup(fmt_addrport(&addr, port));
} else if (!strcmp(argv[i], "--create-identity-key")) {
make_new_id = 1;
} else if (!strcmp(argv[i], "--passphrase-fd")) {
@@ -254,8 +242,7 @@ generate_key(int bits)
crypto_pk_t *env = crypto_pk_new();
if (crypto_pk_generate_key_with_bits(env,bits)<0)
goto done;
- rsa = crypto_pk_get_rsa_(env);
- rsa = RSAPrivateKey_dup(rsa);
+ rsa = crypto_pk_get_openssl_rsa_(env);
done:
crypto_pk_free(env);
return rsa;
@@ -283,7 +270,7 @@ load_identity_key(void)
IDENTITY_KEY_BITS);
if (!(key = generate_key(IDENTITY_KEY_BITS))) {
log_err(LD_GENERAL, "Couldn't generate identity key.");
- crypto_log_errors(LOG_ERR, "Generating identity key");
+ crypto_openssl_log_errors(LOG_ERR, "Generating identity key");
return 1;
}
identity_key = EVP_PKEY_new();
@@ -305,7 +292,7 @@ load_identity_key(void)
NULL, NULL)) {
log_err(LD_GENERAL, "Couldn't write identity key to %s",
identity_key_file);
- crypto_log_errors(LOG_ERR, "Writing identity key");
+ crypto_openssl_log_errors(LOG_ERR, "Writing identity key");
abort_writing_to_file(open_file);
return 1;
}
@@ -370,7 +357,7 @@ generate_signing_key(void)
SIGNING_KEY_BITS);
if (!(key = generate_key(SIGNING_KEY_BITS))) {
log_err(LD_GENERAL, "Couldn't generate signing key.");
- crypto_log_errors(LOG_ERR, "Generating signing key");
+ crypto_openssl_log_errors(LOG_ERR, "Generating signing key");
return 1;
}
signing_key = EVP_PKEY_new();
@@ -386,7 +373,7 @@ generate_signing_key(void)
/* Write signing key with no encryption. */
if (!PEM_write_RSAPrivateKey(f, key, NULL, NULL, 0, NULL, NULL)) {
- crypto_log_errors(LOG_WARN, "writing signing key");
+ crypto_openssl_log_errors(LOG_WARN, "writing signing key");
abort_writing_to_file(open_file);
return 1;
}
@@ -410,7 +397,7 @@ key_to_string(EVP_PKEY *key)
b = BIO_new(BIO_s_mem());
if (!PEM_write_bio_RSAPublicKey(b, rsa)) {
- crypto_log_errors(LOG_WARN, "writing public key to string");
+ crypto_openssl_log_errors(LOG_WARN, "writing public key to string");
RSA_free(rsa);
return NULL;
}
@@ -430,8 +417,8 @@ key_to_string(EVP_PKEY *key)
static int
get_fingerprint(EVP_PKEY *pkey, char *out)
{
- int r = 1;
- crypto_pk_t *pk = crypto_new_pk_from_rsa_(EVP_PKEY_get1_RSA(pkey));
+ int r = -1;
+ crypto_pk_t *pk = crypto_new_pk_from_openssl_rsa_(EVP_PKEY_get1_RSA(pkey));
if (pk) {
r = crypto_pk_get_fingerprint(pk, out, 0);
crypto_pk_free(pk);
@@ -443,8 +430,8 @@ get_fingerprint(EVP_PKEY *pkey, char *out)
static int
get_digest(EVP_PKEY *pkey, char *out)
{
- int r = 1;
- crypto_pk_t *pk = crypto_new_pk_from_rsa_(EVP_PKEY_get1_RSA(pkey));
+ int r = -1;
+ crypto_pk_t *pk = crypto_new_pk_from_openssl_rsa_(EVP_PKEY_get1_RSA(pkey));
if (pk) {
r = crypto_pk_get_digest(pk, out);
crypto_pk_free(pk);
@@ -464,16 +451,20 @@ generate_certificate(void)
char expires[ISO_TIME_LEN+1];
char id_digest[DIGEST_LEN];
char fingerprint[FINGERPRINT_LEN+1];
- char *ident = key_to_string(identity_key);
- char *signing = key_to_string(signing_key);
FILE *f;
size_t signed_len;
char digest[DIGEST_LEN];
char signature[1024]; /* handles up to 8192-bit keys. */
int r;
- get_fingerprint(identity_key, fingerprint);
- get_digest(identity_key, id_digest);
+ if (get_fingerprint(identity_key, fingerprint) < 0) {
+ return -1;
+ }
+ if (get_digest(identity_key, id_digest)) {
+ return -1;
+ }
+ char *ident = key_to_string(identity_key);
+ char *signing = key_to_string(signing_key);
tor_localtime_r(&now, &tm);
tm.tm_mon += months_lifetime;
@@ -593,4 +584,3 @@ main(int argc, char **argv)
crypto_global_cleanup();
return r;
}
-
diff --git a/src/tools/tor-print-ed-signing-cert.c b/src/tools/tor-print-ed-signing-cert.c
new file mode 100644
index 0000000000..1f1a01ab5c
--- /dev/null
+++ b/src/tools/tor-print-ed-signing-cert.c
@@ -0,0 +1,65 @@
+/* Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "trunnel/ed25519_cert.h"
+#include "lib/cc/torint.h" /* TOR_PRIdSZ */
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/malloc/malloc.h"
+
+int
+main(int argc, char **argv)
+{
+ ed25519_cert_t *cert = NULL;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "%s <path to ed25519_signing_cert file>\n", argv[0]);
+ return -1;
+ }
+
+ const char *filepath = argv[1];
+ char *got_tag = NULL;
+
+ uint8_t certbuf[256];
+ ssize_t cert_body_len = crypto_read_tagged_contents_from_file(
+ filepath, "ed25519v1-cert",
+ &got_tag, certbuf, sizeof(certbuf));
+
+ if (cert_body_len <= 0) {
+ fprintf(stderr, "crypto_read_tagged_contents_from_file failed with "
+ "error: %s\n", strerror(errno));
+ return -2;
+ }
+
+ if (!got_tag) {
+ fprintf(stderr, "Found no tag\n");
+ return -3;
+ }
+
+ if (strcmp(got_tag, "type4") != 0) {
+ fprintf(stderr, "Wrong tag: %s\n", got_tag);
+ return -4;
+ }
+
+ tor_free(got_tag);
+
+ ssize_t parsed = ed25519_cert_parse(&cert, certbuf, cert_body_len);
+ if (parsed <= 0) {
+ fprintf(stderr, "ed25519_cert_parse failed with return value %" TOR_PRIdSZ
+ "\n", parsed);
+ return -5;
+ }
+
+ time_t expires_at = (time_t)cert->exp_field * 60 * 60;
+
+ printf("Expires at: %s", ctime(&expires_at));
+
+ ed25519_cert_free(cert);
+
+ return 0;
+}
diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c
index 6ac866d3c0..6a84abe557 100644
--- a/src/tools/tor-resolve.c
+++ b/src/tools/tor-resolve.c
@@ -1,20 +1,25 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
- * Copyright (c) 2007-2015, The Tor Project, Inc.
+ * Copyright (c) 2007-2019, The Tor Project, Inc.
*/
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "compat.h"
-#include "util.h"
-#include "address.h"
-#include "torlog.h"
-#include "sandbox.h"
+
+#include "lib/arch/bytes.h"
+#include "lib/log/log.h"
+#include "lib/malloc/malloc.h"
+#include "lib/net/address.h"
+#include "lib/net/resolve.h"
+#include "lib/net/socket.h"
+#include "lib/sandbox/sandbox.h"
+#include "lib/string/util_string.h"
+
+#include "lib/net/socks5_status.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
-#include <assert.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
@@ -192,12 +197,14 @@ socks5_reason_to_string(char reason)
* address (in host order) into *<b>result_addr</b>.
*/
static int
-do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
+do_resolve(const char *hostname,
+ const tor_addr_t *sockshost, uint16_t socksport,
int reverse, int version,
tor_addr_t *result_addr, char **result_hostname)
{
int s = -1;
- struct sockaddr_in socksaddr;
+ struct sockaddr_storage ss;
+ socklen_t socklen;
char *req = NULL;
ssize_t len = 0;
@@ -214,22 +221,21 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
return -1;
}
- memset(&socksaddr, 0, sizeof(socksaddr));
- socksaddr.sin_family = AF_INET;
- socksaddr.sin_port = htons(socksport);
- socksaddr.sin_addr.s_addr = htonl(sockshost);
- if (connect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) {
+ socklen = tor_addr_to_sockaddr(sockshost, socksport,
+ (struct sockaddr *)&ss, sizeof(ss));
+
+ if (connect(s, (struct sockaddr*)&ss, socklen)) {
log_sock_error("connecting to SOCKS host", s);
goto err;
}
if (version == 5) {
char method_buf[2];
- if (write_all(s, "\x05\x01\x00", 3, 1) != 3) {
+ if (write_all_to_socket(s, "\x05\x01\x00", 3) != 3) {
log_err(LD_NET, "Error sending SOCKS5 method list.");
goto err;
}
- if (read_all(s, method_buf, 2, 1) != 2) {
+ if (read_all_from_socket(s, method_buf, 2) != 2) {
log_err(LD_NET, "Error reading SOCKS5 methods.");
goto err;
}
@@ -251,7 +257,7 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
tor_assert(!req);
goto err;
}
- if (write_all(s, req, len, 1) != len) {
+ if (write_all_to_socket(s, req, len) != len) {
log_sock_error("sending SOCKS request", s);
tor_free(req);
goto err;
@@ -260,7 +266,7 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
if (version == 4) {
char reply_buf[RESPONSE_LEN_4];
- if (read_all(s, reply_buf, RESPONSE_LEN_4, 1) != RESPONSE_LEN_4) {
+ if (read_all_from_socket(s, reply_buf, RESPONSE_LEN_4) != RESPONSE_LEN_4) {
log_err(LD_NET, "Error reading SOCKS4 response.");
goto err;
}
@@ -271,7 +277,7 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
}
} else {
char reply_buf[16];
- if (read_all(s, reply_buf, 4, 1) != 4) {
+ if (read_all_from_socket(s, reply_buf, 4) != 4) {
log_err(LD_NET, "Error reading SOCKS5 response.");
goto err;
}
@@ -291,14 +297,14 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
}
if (reply_buf[3] == 1) {
/* IPv4 address */
- if (read_all(s, reply_buf, 4, 1) != 4) {
+ if (read_all_from_socket(s, reply_buf, 4) != 4) {
log_err(LD_NET, "Error reading address in socks5 response.");
goto err;
}
tor_addr_from_ipv4n(result_addr, get_uint32(reply_buf));
} else if (reply_buf[3] == 4) {
/* IPv6 address */
- if (read_all(s, reply_buf, 16, 1) != 16) {
+ if (read_all_from_socket(s, reply_buf, 16) != 16) {
log_err(LD_NET, "Error reading address in socks5 response.");
goto err;
}
@@ -306,13 +312,14 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
} else if (reply_buf[3] == 3) {
/* Domain name */
size_t result_len;
- if (read_all(s, reply_buf, 1, 1) != 1) {
+ if (read_all_from_socket(s, reply_buf, 1) != 1) {
log_err(LD_NET, "Error reading address_length in socks5 response.");
goto err;
}
result_len = *(uint8_t*)(reply_buf);
*result_hostname = tor_malloc(result_len+1);
- if (read_all(s, *result_hostname, result_len, 1) != (int) result_len) {
+ if (read_all_from_socket(s, *result_hostname, result_len)
+ != (int) result_len) {
log_err(LD_NET, "Error reading hostname in socks5 response.");
goto err;
}
@@ -340,14 +347,13 @@ usage(void)
int
main(int argc, char **argv)
{
- uint32_t sockshost;
+ tor_addr_t sockshost;
uint16_t socksport = 0, port_option = 0;
int isSocks4 = 0, isVerbose = 0, isReverse = 0;
char **arg;
int n_args;
tor_addr_t result;
char *result_hostname = NULL;
- log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t));
init_logging(1);
sandbox_disable_getaddrinfo_cache();
@@ -398,15 +404,18 @@ main(int argc, char **argv)
usage();
}
+ log_severity_list_t *severities =
+ tor_malloc_zero(sizeof(log_severity_list_t));
if (isVerbose)
- set_log_severity_config(LOG_DEBUG, LOG_ERR, s);
+ set_log_severity_config(LOG_DEBUG, LOG_ERR, severities);
else
- set_log_severity_config(LOG_WARN, LOG_ERR, s);
- add_stream_log(s, "<stderr>", fileno(stderr));
+ set_log_severity_config(LOG_WARN, LOG_ERR, severities);
+ add_stream_log(severities, "<stderr>", fileno(stderr));
+ tor_free(severities);
if (n_args == 1) {
log_debug(LD_CONFIG, "defaulting to localhost");
- sockshost = 0x7f000001u; /* localhost */
+ tor_addr_from_ipv4h(&sockshost, 0x7f000001u); /* localhost */
if (port_option) {
log_debug(LD_CONFIG, "Using port %d", (int)port_option);
socksport = port_option;
@@ -415,7 +424,7 @@ main(int argc, char **argv)
socksport = 9050; /* 9050 */
}
} else if (n_args == 2) {
- if (addr_port_lookup(LOG_WARN, arg[1], NULL, &sockshost, &socksport)<0) {
+ if (tor_addr_port_lookup(arg[1], &sockshost, &socksport)<0) {
fprintf(stderr, "Couldn't parse/resolve address %s", arg[1]);
return 1;
}
@@ -437,7 +446,7 @@ main(int argc, char **argv)
return 1;
}
- if (do_resolve(arg[0], sockshost, socksport, isReverse,
+ if (do_resolve(arg[0], &sockshost, socksport, isReverse,
isSocks4 ? 4 : 5, &result,
&result_hostname))
return 1;
@@ -449,4 +458,3 @@ main(int argc, char **argv)
}
return 0;
}
-
diff --git a/src/tools/tor_runner.c b/src/tools/tor_runner.c
new file mode 100644
index 0000000000..3c6ade91d9
--- /dev/null
+++ b/src/tools/tor_runner.c
@@ -0,0 +1,112 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file tor_runner.c
+ * @brief Experimental module to emulate tor_run_main() API with fork+exec
+ *
+ * The functions here are meant to allow the application developer to
+ * use the tor_run_main() API without having to care whether Tor is
+ * running in-process or out-of-process. For in-process usage, the
+ * developer can link Tor as a library and call tor_run_main(); for
+ * out-of-process usage, the developer can link this library instead.
+ *
+ * This interface is EXPERIMENTAL; please let us know if you would like
+ * to depend on it. We don't know yet whether it will be reliable in
+ * practice.
+ */
+
+/* NOTE: This module is supposed to work without the standard Tor utility
+ * functions. Don't add more dependencies!
+ */
+
+#include "feature/api/tor_api.h"
+#include "feature/api/tor_api_internal.h"
+
+#include "orconfig.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif
+
+static void child(const tor_main_configuration_t *cfg)
+ __attribute__((noreturn));
+
+const char *
+tor_api_get_provider_version(void)
+{
+ return "libtorrunner " VERSION;
+}
+
+int
+tor_run_main(const tor_main_configuration_t *cfg)
+{
+ pid_t pid = fork();
+ if (pid == 0) {
+ child(cfg);
+ exit(0); /* Unreachable */
+ }
+
+ pid_t stopped_pid;
+ int status = 0;
+ do {
+ stopped_pid = waitpid(pid, &status, 0);
+ } while (stopped_pid == -1);
+
+ /* Note: these return values are not documented. No return value is
+ * documented! */
+
+ if (stopped_pid != pid) {
+ return -99999;
+ }
+ if (WIFSTOPPED(status)) {
+ return WEXITSTATUS(status);
+ }
+ if (WIFSIGNALED(status)) {
+ return -WTERMSIG(status);
+ }
+
+ return -999988;
+}
+
+/* circumlocution to avoid getting warned about calling calloc instead of
+ * tor_calloc. */
+#define real_calloc calloc
+#define real_free free
+
+static void
+child(const tor_main_configuration_t *cfg)
+{
+ /* XXXX Close unused file descriptors. */
+
+ char **args = real_calloc(cfg->argc + cfg->argc_owned+1, sizeof(char *));
+ memcpy(args, cfg->argv, cfg->argc * sizeof(char *));
+ if (cfg->argc_owned)
+ memcpy(args + cfg->argc, cfg->argv_owned,
+ cfg->argc_owned * sizeof(char *));
+
+ args[cfg->argc + cfg->argc_owned] = NULL;
+
+ int rv = execv(BINDIR "/tor", args);
+
+ if (rv < 0) {
+ real_free(args);
+ exit(254);
+ } else {
+ abort(); /* Unreachable */
+ }
+}