diff options
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/Makefile.nmake | 5 | ||||
-rw-r--r-- | src/tools/include.am | 62 | ||||
-rw-r--r-- | src/tools/tor-checkkey.c | 89 | ||||
-rw-r--r-- | src/tools/tor-fw-helper/README | 10 | ||||
-rw-r--r-- | src/tools/tor-gencert.c | 88 | ||||
-rw-r--r-- | src/tools/tor-print-ed-signing-cert.c | 65 | ||||
-rw-r--r-- | src/tools/tor-resolve.c | 72 | ||||
-rw-r--r-- | src/tools/tor_runner.c | 106 |
8 files changed, 284 insertions, 213 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..d5924dda5f 100644 --- a/src/tools/include.am +++ b/src/tools/include.am @@ -1,5 +1,4 @@ -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-gencert src/tools/tor-print-ed-signing-cert if COVERAGE_ENABLED noinst_PROGRAMS+= src/tools/tor-cov-resolve src/tools/tor-cov-gencert @@ -7,50 +6,53 @@ 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 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_LDADD = \ + $(TOR_CRYPTO_LIBS) \ + $(TOR_UTIL_LIBS) \ + $(rust_ldadd) \ + @TOR_LIB_MATH@ @TOR_ZLIB_LIBS@ @TOR_OPENSSL_LIBS@ \ + @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ @CURVE25519_LIBS@ + +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_OPENSSL_LIBS@ \ + @TOR_LIB_WS32@ @TOR_LIB_USERENV@ if COVERAGE_ENABLED 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) \ +src_tools_tor_cov_gencert_LDADD = \ + $(TOR_CRYPTO_TESTING_LIBS) \ + $(TOR_UTIL_TESTING_LIBS) \ @TOR_LIB_MATH@ @TOR_ZLIB_LIBS@ @TOR_OPENSSL_LIBS@ \ - @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ + @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ 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..ff924152a6 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-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -13,7 +13,7 @@ #include <unistd.h> #endif -#include "compat.h" +#include "lib/cc/compat_compiler.h" /* 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 @@ -30,18 +30,21 @@ DISABLE_GCC_WARNING(redundant-decls) ENABLE_GCC_WARNING(redundant-decls) #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.h" +#include "lib/crypt_ops/crypto_digest.h" +#include "lib/crypt_ops/crypto_rand.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 +79,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 +86,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 +171,22 @@ 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; + } + 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")) { @@ -430,7 +413,7 @@ key_to_string(EVP_PKEY *key) static int get_fingerprint(EVP_PKEY *pkey, char *out) { - int r = 1; + int r = -1; crypto_pk_t *pk = crypto_new_pk_from_rsa_(EVP_PKEY_get1_RSA(pkey)); if (pk) { r = crypto_pk_get_fingerprint(pk, out, 0); @@ -443,7 +426,7 @@ get_fingerprint(EVP_PKEY *pkey, char *out) static int get_digest(EVP_PKEY *pkey, char *out) { - int r = 1; + int r = -1; crypto_pk_t *pk = crypto_new_pk_from_rsa_(EVP_PKEY_get1_RSA(pkey)); if (pk) { r = crypto_pk_get_digest(pk, out); @@ -464,16 +447,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 +580,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..0f64059d84 --- /dev/null +++ b/src/tools/tor-print-ed-signing-cert.c @@ -0,0 +1,65 @@ +/* Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#include "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..d5b4987832 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-2018, 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, sizeof(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..f8805e6500 --- /dev/null +++ b/src/tools/tor_runner.c @@ -0,0 +1,106 @@ +/* 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 */ + +/** + * @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 + +static void +child(const tor_main_configuration_t *cfg) +{ + /* XXXX Close unused file descriptors. */ + + char **args = real_calloc(cfg->argc+1, sizeof(char *)); + memcpy(args, cfg->argv, cfg->argc * sizeof(char *)); + args[cfg->argc] = NULL; + + int rv = execv(BINDIR "/tor", args); + + if (rv < 0) { + exit(254); + } else { + abort(); /* Unreachable */ + } +} |