diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-07-05 16:04:32 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-07-05 17:15:50 -0400 |
commit | 81cb0afb2b0163d95a435583041dce1064eec65c (patch) | |
tree | 69f13e56ecb7e0dd899636ef70185c9416ac2448 /src/or | |
parent | 4eac5c6ce6f19829bf1aed46e8d3d72fa3ae1a74 (diff) | |
download | tor-81cb0afb2b0163d95a435583041dce1064eec65c.tar.gz tor-81cb0afb2b0163d95a435583041dce1064eec65c.zip |
Start splitting src/or
This is a very gentle commit that just lays the groundwork in the
build system: it puts the include files to build libtor-app.a into
src/core, and to build the tor executable into src/app. The
executable is now "src/app/tor".
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/include.am | 370 | ||||
-rw-r--r-- | src/or/main.c | 2 | ||||
-rw-r--r-- | src/or/ntmain.c | 783 | ||||
-rw-r--r-- | src/or/ntmain.h | 28 | ||||
-rw-r--r-- | src/or/tor_main.c | 42 |
5 files changed, 1 insertions, 1224 deletions
diff --git a/src/or/include.am b/src/or/include.am deleted file mode 100644 index ad7ee69bf5..0000000000 --- a/src/or/include.am +++ /dev/null @@ -1,370 +0,0 @@ -bin_PROGRAMS+= src/or/tor -noinst_LIBRARIES += \ - src/or/libtor-app.a -if UNITTESTS_ENABLED -noinst_LIBRARIES += \ - src/or/libtor-app-testing.a -endif -if COVERAGE_ENABLED -noinst_PROGRAMS+= src/or/tor-cov -endif - -if BUILD_NT_SERVICES -tor_platform_source=src/or/ntmain.c -else -tor_platform_source= -endif - -EXTRA_DIST+= src/or/ntmain.c src/or/Makefile.nmake - -LIBTOR_APP_A_SOURCES = \ - src/or/addressmap.c \ - src/or/address_set.c \ - src/or/bridges.c \ - src/or/channel.c \ - src/or/channelpadding.c \ - src/or/channeltls.c \ - src/or/circpathbias.c \ - src/or/circuitbuild.c \ - src/or/circuitlist.c \ - src/or/circuitmux.c \ - src/or/circuitmux_ewma.c \ - src/or/circuitstats.c \ - src/or/circuituse.c \ - src/or/command.c \ - src/or/config.c \ - src/or/confparse.c \ - src/or/connection.c \ - src/or/connection_edge.c \ - src/or/connection_or.c \ - src/or/conscache.c \ - src/or/consdiff.c \ - src/or/consdiffmgr.c \ - src/or/control.c \ - src/or/cpuworker.c \ - src/or/directory.c \ - src/or/dirserv.c \ - src/or/dns.c \ - src/or/dnsserv.c \ - src/or/dos.c \ - src/or/fp_pair.c \ - src/or/geoip.c \ - src/or/entrynodes.c \ - src/or/ext_orport.c \ - src/or/git_revision.c \ - src/or/hibernate.c \ - src/or/hs_cache.c \ - src/or/hs_cell.c \ - src/or/hs_circuit.c \ - src/or/hs_circuitmap.c \ - src/or/hs_client.c \ - src/or/hs_common.c \ - src/or/hs_config.c \ - src/or/hs_control.c \ - src/or/hs_descriptor.c \ - src/or/hs_ident.c \ - src/or/hs_intropoint.c \ - src/or/hs_ntor.c \ - src/or/hs_service.c \ - src/or/hs_stats.c \ - src/or/keypin.c \ - src/or/main.c \ - src/or/microdesc.c \ - src/or/networkstatus.c \ - src/or/nodelist.c \ - src/or/onion.c \ - src/or/onion_fast.c \ - src/or/onion_tap.c \ - src/or/transports.c \ - src/or/parsecommon.c \ - src/or/periodic.c \ - src/or/protover.c \ - src/or/protover_rust.c \ - src/or/proto_cell.c \ - src/or/proto_control0.c \ - src/or/proto_ext_or.c \ - src/or/proto_http.c \ - src/or/proto_socks.c \ - src/or/policies.c \ - src/or/reasons.c \ - src/or/relay.c \ - src/or/relay_crypto.c \ - src/or/rendcache.c \ - src/or/rendclient.c \ - src/or/rendcommon.c \ - src/or/rendmid.c \ - src/or/rendservice.c \ - src/or/rephist.c \ - src/or/replaycache.c \ - src/or/router.c \ - src/or/routerkeys.c \ - src/or/routerlist.c \ - src/or/routerparse.c \ - src/or/routerset.c \ - src/or/scheduler.c \ - src/or/scheduler_kist.c \ - src/or/scheduler_vanilla.c \ - src/or/shared_random_client.c \ - src/or/statefile.c \ - src/or/status.c \ - src/or/torcert.c \ - src/or/tor_api.c \ - src/or/voting_schedule.c \ - src/or/onion_ntor.c \ - $(tor_platform_source) - -# -# Modules are conditionnally compiled in tor starting here. We add the C files -# only if the modules has been enabled at configure time. We always add the -# source files of every module to libtor-testing.a so we can build the unit -# tests for everything. See the UNITTESTS_ENABLED branch below. -# -LIBTOR_APP_TESTING_A_SOURCES = $(LIBTOR_APP_A_SOURCES) - -# The Directory Authority module. -MODULE_DIRAUTH_SOURCES = \ - src/or/dirauth/dircollate.c \ - src/or/dirauth/dirvote.c \ - src/or/dirauth/shared_random.c \ - src/or/dirauth/shared_random_state.c -if BUILD_MODULE_DIRAUTH -LIBTOR_APP_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) -endif - -src_or_libtor_app_a_SOURCES = $(LIBTOR_APP_A_SOURCES) -if UNITTESTS_ENABLED - -# Add the sources of the modules that are needed for tests to work here. -LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) - -src_or_libtor_app_testing_a_SOURCES = $(LIBTOR_APP_TESTING_A_SOURCES) -else -src_or_libtor_app_testing_a_SOURCES = -endif - -src_or_tor_SOURCES = src/or/tor_main.c - -src/or/git_revision.$(OBJEXT) \ - src/or/src_or_libtor_app_testing_a-git_revision.$(OBJEXT): micro-revision.i - -AM_CPPFLAGS += -DSHARE_DATADIR="\"$(datadir)\"" \ - -DLOCALSTATEDIR="\"$(localstatedir)\"" \ - -DBINDIR="\"$(bindir)\"" - -src_or_libtor_app_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS) -src_or_libtor_app_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) - -# -L flags need to go in LDFLAGS. -l flags need to go in LDADD. -# This seems to matter nowhere but on windows, but I assure you that it -# matters a lot there, and is quite hard to debug if you forget to do it. - - -src_or_tor_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@ -src_or_tor_LDADD = $(TOR_INTERNAL_LIBS) \ - $(rust_ldadd) \ - @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \ - @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \ - @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ \ - @TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@ - -if COVERAGE_ENABLED -src_or_tor_cov_SOURCES = src/or/tor_main.c -src_or_tor_cov_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS) -src_or_tor_cov_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) -src_or_tor_cov_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@ -src_or_tor_cov_LDADD = $(TOR_INTERNAL_TESTING_LIBS) \ - @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \ - @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ \ - @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ \ - @TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@ -endif - -ORHEADERS = \ - src/or/addressmap.h \ - src/or/address_set.h \ - src/or/addr_policy_st.h \ - src/or/authority_cert_st.h \ - src/or/auth_dirs.inc \ - src/or/bridges.h \ - src/or/cell_st.h \ - src/or/cell_queue_st.h \ - src/or/channel.h \ - src/or/channelpadding.h \ - src/or/channeltls.h \ - src/or/circpathbias.h \ - src/or/circuitbuild.h \ - src/or/circuitlist.h \ - src/or/circuitmux.h \ - src/or/circuitmux_ewma.h \ - src/or/circuitstats.h \ - src/or/circuituse.h \ - src/or/circuit_st.h \ - src/or/cached_dir_st.h \ - src/or/command.h \ - src/or/config.h \ - src/or/confparse.h \ - src/or/connection.h \ - src/or/connection_st.h \ - src/or/connection_edge.h \ - src/or/connection_or.h \ - src/or/conscache.h \ - src/or/consdiff.h \ - src/or/consdiffmgr.h \ - src/or/control_connection_st.h \ - src/or/control.h \ - src/or/cpath_build_state_st.h \ - src/or/crypt_path_st.h \ - src/or/crypt_path_reference_st.h \ - src/or/cpuworker.h \ - src/or/desc_store_st.h \ - src/or/destroy_cell_queue_st.h \ - src/or/directory.h \ - src/or/dirserv.h \ - src/or/dir_connection_st.h \ - src/or/dir_server_st.h \ - src/or/document_signature_st.h \ - src/or/download_status_st.h \ - src/or/dns.h \ - src/or/dns_structs.h \ - src/or/dnsserv.h \ - src/or/dos.h \ - src/or/edge_connection_st.h \ - src/or/entry_connection_st.h \ - src/or/entry_port_cfg_st.h \ - src/or/ext_orport.h \ - src/or/extend_info_st.h \ - src/or/extrainfo_st.h \ - src/or/fallback_dirs.inc \ - src/or/fp_pair.h \ - src/or/geoip.h \ - src/or/entrynodes.h \ - src/or/git_revision.h \ - src/or/hibernate.h \ - src/or/hs_cache.h \ - src/or/hs_cell.h \ - src/or/hs_circuit.h \ - src/or/hs_circuitmap.h \ - src/or/hs_client.h \ - src/or/hs_common.h \ - src/or/hs_config.h \ - src/or/hs_control.h \ - src/or/hs_descriptor.h \ - src/or/hs_ident.h \ - src/or/hs_intropoint.h \ - src/or/hs_ntor.h \ - src/or/hs_stats.h \ - src/or/hs_service.h \ - src/or/hsdir_index_st.h \ - src/or/keypin.h \ - src/or/listener_connection_st.h \ - src/or/main.h \ - src/or/microdesc.h \ - src/or/microdesc_st.h \ - src/or/networkstatus.h \ - src/or/networkstatus_st.h \ - src/or/networkstatus_sr_info_st.h \ - src/or/networkstatus_voter_info_st.h \ - src/or/nodelist.h \ - src/or/node_st.h \ - src/or/ns_detached_signatures_st.h \ - src/or/ntmain.h \ - src/or/onion.h \ - src/or/onion_fast.h \ - src/or/onion_ntor.h \ - src/or/onion_tap.h \ - src/or/or.h \ - src/or/or_circuit_st.h \ - src/or/or_connection_st.h \ - src/or/or_handshake_certs_st.h \ - src/or/or_handshake_state_st.h \ - src/or/or_options_st.h \ - src/or/or_state_st.h \ - src/or/origin_circuit_st.h \ - src/or/transports.h \ - src/or/parsecommon.h \ - src/or/periodic.h \ - src/or/port_cfg_st.h \ - src/or/policies.h \ - src/or/protover.h \ - src/or/proto_cell.h \ - src/or/proto_control0.h \ - src/or/proto_ext_or.h \ - src/or/proto_http.h \ - src/or/proto_socks.h \ - src/or/reasons.h \ - src/or/relay.h \ - src/or/relay_crypto.h \ - src/or/relay_crypto_st.h \ - src/or/rendcache.h \ - src/or/rendclient.h \ - src/or/rendcommon.h \ - src/or/rendmid.h \ - src/or/rendservice.h \ - src/or/rend_authorized_client_st.h \ - src/or/rend_encoded_v2_service_descriptor_st.h \ - src/or/rend_intro_point_st.h \ - src/or/rend_service_descriptor_st.h \ - src/or/rephist.h \ - src/or/replaycache.h \ - src/or/router.h \ - src/or/routerinfo_st.h \ - src/or/routerkeys.h \ - src/or/routerlist.h \ - src/or/routerlist_st.h \ - src/or/routerkeys.h \ - src/or/routerset.h \ - src/or/routerparse.h \ - src/or/routerstatus_st.h \ - src/or/scheduler.h \ - src/or/server_port_cfg_st.h \ - src/or/shared_random_client.h \ - src/or/signed_descriptor_st.h \ - src/or/socks_request_st.h \ - src/or/statefile.h \ - src/or/status.h \ - src/or/torcert.h \ - src/or/tor_api_internal.h \ - src/or/tor_version_st.h \ - src/or/var_cell_st.h \ - src/or/vote_microdesc_hash_st.h \ - src/or/vote_routerstatus_st.h \ - src/or/vote_timing_st.h \ - src/or/voting_schedule.h - -# We add the headers of the modules even though they are disabled so we can -# properly compiled the entry points stub. - -# The Directory Authority module headers. -ORHEADERS += \ - src/or/dirauth/dircollate.h \ - src/or/dirauth/dirvote.h \ - src/or/dirauth/mode.h \ - src/or/dirauth/shared_random.h \ - src/or/dirauth/shared_random_state.h - -# This may someday want to be an installed file? -noinst_HEADERS += src/or/tor_api.h - -noinst_HEADERS += $(ORHEADERS) micro-revision.i - -micro-revision.i: FORCE - $(AM_V_at)rm -f micro-revision.tmp; \ - if test -r "$(top_srcdir)/.git" && \ - test -x "`which git 2>&1;true`"; then \ - HASH="`cd "$(top_srcdir)" && git rev-parse --short=16 HEAD`"; \ - echo \"$$HASH\" > micro-revision.tmp; \ - fi; \ - if test ! -f micro-revision.tmp; then \ - if test ! -f micro-revision.i; then \ - echo '""' > micro-revision.i; \ - fi; \ - elif test ! -f micro-revision.i || \ - test x"`cat micro-revision.tmp`" != x"`cat micro-revision.i`"; then \ - mv micro-revision.tmp micro-revision.i; \ - fi; \ - rm -f micro-revision.tmp; \ - true - -CLEANFILES+= micro-revision.i src/or/micro-revision.i micro-revision.tmp - -FORCE: diff --git a/src/or/main.c b/src/or/main.c index 7e3eb2b595..2a57aa587a 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -88,7 +88,7 @@ #include "or/microdesc.h" #include "or/networkstatus.h" #include "or/nodelist.h" -#include "or/ntmain.h" +#include "app/ntmain.h" #include "or/onion.h" #include "or/periodic.h" #include "or/policies.h" diff --git a/src/or/ntmain.c b/src/or/ntmain.c deleted file mode 100644 index f6b57753d3..0000000000 --- a/src/or/ntmain.c +++ /dev/null @@ -1,783 +0,0 @@ -/* 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 ntmain.c - * - * \brief Entry points for running/configuring Tor as a Windows Service. - * - * Windows Services expect to be registered with the operating system, and to - * have entry points for starting, stopping, and monitoring them. This module - * implements those entry points so that a tor relay or client or hidden - * service can run as a Windows service. Therefore, this module - * is only compiled when building for Windows. - * - * Warning: this module is not very well tested or very well maintained. - */ - -#ifdef _WIN32 - -#include "or/or.h" -#include "or/config.h" -#include "or/main.h" -#include "or/ntmain.h" -#include "lib/log/win32err.h" -#include "lib/fs/winlib.h" -#include "lib/evloop/compat_libevent.h" - -#include <windows.h> -#define GENSRV_SERVICENAME "tor" -#define GENSRV_DISPLAYNAME "Tor Win32 Service" -#define GENSRV_DESCRIPTION \ - "Provides an anonymous Internet communication system" -#define GENSRV_USERACCT "NT AUTHORITY\\LocalService" - -// Cheating: using the pre-defined error codes, tricks Windows into displaying -// a semi-related human-readable error message if startup fails as -// opposed to simply scaring people with Error: 0xffffffff -#define NT_SERVICE_ERROR_TORINIT_FAILED ERROR_EXCEPTION_IN_SERVICE - -static SERVICE_STATUS service_status; -static SERVICE_STATUS_HANDLE hStatus; - -/* XXXX This 'backup argv' and 'backup argc' business is an ugly hack. This - * is a job for arguments, not globals. Alas, some of the functions that - * use them use them need to have fixed signatures, so they can be passed - * to the NT service functions. */ -static char **backup_argv; -static int backup_argc; - -static void nt_service_control(DWORD request); -static void nt_service_body(int argc, char **argv); -static void nt_service_main(void); -static SC_HANDLE nt_service_open_scm(void); -static SC_HANDLE nt_service_open(SC_HANDLE hSCManager); -static int nt_service_start(SC_HANDLE hService); -static int nt_service_stop(SC_HANDLE hService); -static int nt_service_install(int argc, char **argv); -static int nt_service_remove(void); -static int nt_service_cmd_start(void); -static int nt_service_cmd_stop(void); - -/** Struct to hold dynamically loaded NT-service related function pointers. - */ -struct service_fns { - int loaded; - - /** @{ */ - /** Function pointers for Windows API functions related to service - * management. These are NULL, or they point to the . They're set by - * calling the LOAD macro below. */ - - BOOL (WINAPI *ChangeServiceConfig2A_fn)( - SC_HANDLE hService, - DWORD dwInfoLevel, - LPVOID lpInfo); - - BOOL (WINAPI *CloseServiceHandle_fn)( - SC_HANDLE hSCObject); - - BOOL (WINAPI *ControlService_fn)( - SC_HANDLE hService, - DWORD dwControl, - LPSERVICE_STATUS lpServiceStatus); - - SC_HANDLE (WINAPI *CreateServiceA_fn)( - SC_HANDLE hSCManager, - LPCSTR lpServiceName, - LPCSTR lpDisplayName, - DWORD dwDesiredAccess, - DWORD dwServiceType, - DWORD dwStartType, - DWORD dwErrorControl, - LPCSTR lpBinaryPathName, - LPCSTR lpLoadOrderGroup, - LPDWORD lpdwTagId, - LPCSTR lpDependencies, - LPCSTR lpServiceStartName, - LPCSTR lpPassword); - - BOOL (WINAPI *DeleteService_fn)( - SC_HANDLE hService); - - SC_HANDLE (WINAPI *OpenSCManagerA_fn)( - LPCSTR lpMachineName, - LPCSTR lpDatabaseName, - DWORD dwDesiredAccess); - - SC_HANDLE (WINAPI *OpenServiceA_fn)( - SC_HANDLE hSCManager, - LPCSTR lpServiceName, - DWORD dwDesiredAccess); - - BOOL (WINAPI *QueryServiceStatus_fn)( - SC_HANDLE hService, - LPSERVICE_STATUS lpServiceStatus); - - SERVICE_STATUS_HANDLE (WINAPI *RegisterServiceCtrlHandlerA_fn)( - LPCSTR lpServiceName, - LPHANDLER_FUNCTION lpHandlerProc); - - BOOL (WINAPI *SetServiceStatus_fn)(SERVICE_STATUS_HANDLE, - LPSERVICE_STATUS); - - BOOL (WINAPI *StartServiceCtrlDispatcherA_fn)( - const SERVICE_TABLE_ENTRYA* lpServiceTable); - - BOOL (WINAPI *StartServiceA_fn)( - SC_HANDLE hService, - DWORD dwNumServiceArgs, - LPCSTR* lpServiceArgVectors); - - BOOL (WINAPI *LookupAccountNameA_fn)( - LPCSTR lpSystemName, - LPCSTR lpAccountName, - PSID Sid, - LPDWORD cbSid, - LPTSTR ReferencedDomainName, - LPDWORD cchReferencedDomainName, - PSID_NAME_USE peUse); - /** @} */ -} service_fns = { 0, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL}; - -/** Loads functions used by NT services. Returns on success, or prints a - * complaint to stdout and exits on error. */ -static void -nt_service_loadlibrary(void) -{ - HMODULE library = 0; - void *fn; - - if (service_fns.loaded) - return; - - if (!(library = load_windows_system_library(TEXT("advapi32.dll")))) { - log_err(LD_GENERAL, "Couldn't open advapi32.dll. Are you trying to use " - "NT services on Windows 98? That doesn't work."); - goto err; - } - -/* Helper macro: try to load a function named <b>f</b> from "library" into - * service_functions.<b>f</b>_fn. On failure, log an error message, and goto - * err. - */ -#define LOAD(f) STMT_BEGIN \ - if (!(fn = GetProcAddress(library, #f))) { \ - log_err(LD_BUG, \ - "Couldn't find %s in advapi32.dll! We probably got the " \ - "name wrong.", #f); \ - goto err; \ - } else { \ - service_fns.f ## _fn = fn; \ - } \ - STMT_END - - LOAD(ChangeServiceConfig2A); - LOAD(CloseServiceHandle); - LOAD(ControlService); - LOAD(CreateServiceA); - LOAD(DeleteService); - LOAD(OpenSCManagerA); - LOAD(OpenServiceA); - LOAD(QueryServiceStatus); - LOAD(RegisterServiceCtrlHandlerA); - LOAD(SetServiceStatus); - LOAD(StartServiceCtrlDispatcherA); - LOAD(StartServiceA); - LOAD(LookupAccountNameA); - - service_fns.loaded = 1; - - return; - err: - printf("Unable to load library support for NT services: exiting.\n"); - exit(1); // exit ok: ntmain can't read libraries -} - -/** If we're compiled to run as an NT service, and the service wants to - * shut down, then change our current status and return 1. Else - * return 0. - */ -int -nt_service_is_stopping(void) -{ - /* If we haven't loaded the function pointers, we can't possibly be an NT - * service trying to shut down. */ - if (!service_fns.loaded) - return 0; - - if (service_status.dwCurrentState == SERVICE_STOP_PENDING) { - service_status.dwWin32ExitCode = 0; - service_status.dwCurrentState = SERVICE_STOPPED; - service_fns.SetServiceStatus_fn(hStatus, &service_status); - return 1; - } else if (service_status.dwCurrentState == SERVICE_STOPPED) { - return 1; - } - return 0; -} - -/** Set the dwCurrentState field for our service to <b>state</b>. */ -void -nt_service_set_state(DWORD state) -{ - service_status.dwCurrentState = state; -} - -/** Handles service control requests, such as stopping or starting the - * Tor service. */ -static void -nt_service_control(DWORD request) -{ - static struct timeval exit_now; - exit_now.tv_sec = 0; - exit_now.tv_usec = 0; - - nt_service_loadlibrary(); - - switch (request) { - case SERVICE_CONTROL_STOP: - case SERVICE_CONTROL_SHUTDOWN: - log_notice(LD_GENERAL, - "Got stop/shutdown request; shutting down cleanly."); - service_status.dwCurrentState = SERVICE_STOP_PENDING; - tor_libevent_exit_loop_after_delay(tor_libevent_get_base(), - &exit_now); - return; - } - service_fns.SetServiceStatus_fn(hStatus, &service_status); -} - -/** Called when the service is started via the system's service control - * manager. This calls tor_init() and starts the main event loop. If - * tor_init() fails, the service will be stopped and exit code set to - * NT_SERVICE_ERROR_TORINIT_FAILED. */ -static void -nt_service_body(int argc, char **argv) -{ - int r; - (void) argc; /* unused */ - (void) argv; /* unused */ - nt_service_loadlibrary(); - service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - service_status.dwCurrentState = SERVICE_START_PENDING; - service_status.dwControlsAccepted = - SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; - service_status.dwWin32ExitCode = 0; - service_status.dwServiceSpecificExitCode = 0; - service_status.dwCheckPoint = 0; - service_status.dwWaitHint = 1000; - hStatus = service_fns.RegisterServiceCtrlHandlerA_fn(GENSRV_SERVICENAME, - (LPHANDLER_FUNCTION) nt_service_control); - - if (hStatus == 0) { - /* Failed to register the service control handler function */ - return; - } - - r = tor_init(backup_argc, backup_argv); - if (r) { - /* Failed to start the Tor service */ - r = NT_SERVICE_ERROR_TORINIT_FAILED; - service_status.dwCurrentState = SERVICE_STOPPED; - service_status.dwWin32ExitCode = r; - service_status.dwServiceSpecificExitCode = r; - service_fns.SetServiceStatus_fn(hStatus, &service_status); - return; - } - - /* Set the service's status to SERVICE_RUNNING and start the main - * event loop */ - service_status.dwCurrentState = SERVICE_RUNNING; - service_fns.SetServiceStatus_fn(hStatus, &service_status); - set_main_thread(); - do_main_loop(); - tor_cleanup(); -} - -/** Main service entry point. Starts the service control dispatcher and waits - * until the service status is set to SERVICE_STOPPED. */ -static void -nt_service_main(void) -{ - SERVICE_TABLE_ENTRYA table[2]; - DWORD result = 0; - char *errmsg; - nt_service_loadlibrary(); - table[0].lpServiceName = (char*)GENSRV_SERVICENAME; - table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)nt_service_body; - table[1].lpServiceName = NULL; - table[1].lpServiceProc = NULL; - - if (!service_fns.StartServiceCtrlDispatcherA_fn(table)) { - result = GetLastError(); - errmsg = format_win32_error(result); - printf("Service error %d : %s\n", (int) result, errmsg); - tor_free(errmsg); - if (result == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { - if (tor_init(backup_argc, backup_argv)) - return; - switch (get_options()->command) { - case CMD_RUN_TOR: - do_main_loop(); - break; - case CMD_LIST_FINGERPRINT: - case CMD_HASH_PASSWORD: - case CMD_VERIFY_CONFIG: - case CMD_DUMP_CONFIG: - case CMD_KEYGEN: - case CMD_KEY_EXPIRATION: - log_err(LD_CONFIG, "Unsupported command (--list-fingerprint, " - "--hash-password, --keygen, --dump-config, --verify-config, " - "or --key-expiration) in NT service."); - break; - case CMD_RUN_UNITTESTS: - default: - log_err(LD_CONFIG, "Illegal command number %d: internal error.", - get_options()->command); - } - tor_cleanup(); - } - } -} - -/** Return a handle to the service control manager on success, or NULL on - * failure. */ -static SC_HANDLE -nt_service_open_scm(void) -{ - SC_HANDLE hSCManager; - char *errmsg = NULL; - - nt_service_loadlibrary(); - if ((hSCManager = service_fns.OpenSCManagerA_fn( - NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) { - errmsg = format_win32_error(GetLastError()); - printf("OpenSCManager() failed : %s\n", errmsg); - tor_free(errmsg); - } - return hSCManager; -} - -/** Open a handle to the Tor service using <b>hSCManager</b>. Return NULL - * on failure. */ -static SC_HANDLE -nt_service_open(SC_HANDLE hSCManager) -{ - SC_HANDLE hService; - char *errmsg = NULL; - nt_service_loadlibrary(); - if ((hService = service_fns.OpenServiceA_fn(hSCManager, GENSRV_SERVICENAME, - SERVICE_ALL_ACCESS)) == NULL) { - errmsg = format_win32_error(GetLastError()); - printf("OpenService() failed : %s\n", errmsg); - tor_free(errmsg); - } - return hService; -} - -/** Start the Tor service. Return 0 if the service is started or was - * previously running. Return -1 on error. */ -static int -nt_service_start(SC_HANDLE hService) -{ - char *errmsg = NULL; - - nt_service_loadlibrary(); - - service_fns.QueryServiceStatus_fn(hService, &service_status); - if (service_status.dwCurrentState == SERVICE_RUNNING) { - printf("Service is already running\n"); - return 0; - } - - if (service_fns.StartServiceA_fn(hService, 0, NULL)) { - /* Loop until the service has finished attempting to start */ - while (service_fns.QueryServiceStatus_fn(hService, &service_status) && - (service_status.dwCurrentState == SERVICE_START_PENDING)) { - Sleep(500); - } - - /* Check if it started successfully or not */ - if (service_status.dwCurrentState == SERVICE_RUNNING) { - printf("Service started successfully\n"); - return 0; - } else { - errmsg = format_win32_error(service_status.dwWin32ExitCode); - printf("Service failed to start : %s\n", errmsg); - tor_free(errmsg); - } - } else { - errmsg = format_win32_error(GetLastError()); - printf("StartService() failed : %s\n", errmsg); - tor_free(errmsg); - } - return -1; -} - -/** Stop the Tor service. Return 0 if the service is stopped or was not - * previously running. Return -1 on error. */ -static int -nt_service_stop(SC_HANDLE hService) -{ -/** Wait at most 10 seconds for the service to stop. */ -#define MAX_SERVICE_WAIT_TIME 10 - int wait_time; - char *errmsg = NULL; - nt_service_loadlibrary(); - - service_fns.QueryServiceStatus_fn(hService, &service_status); - if (service_status.dwCurrentState == SERVICE_STOPPED) { - printf("Service is already stopped\n"); - return 0; - } - - if (service_fns.ControlService_fn(hService, SERVICE_CONTROL_STOP, - &service_status)) { - wait_time = 0; - while (service_fns.QueryServiceStatus_fn(hService, &service_status) && - (service_status.dwCurrentState != SERVICE_STOPPED) && - (wait_time < MAX_SERVICE_WAIT_TIME)) { - Sleep(1000); - wait_time++; - } - if (service_status.dwCurrentState == SERVICE_STOPPED) { - printf("Service stopped successfully\n"); - return 0; - } else if (wait_time == MAX_SERVICE_WAIT_TIME) { - printf("Service did not stop within %d seconds.\n", wait_time); - } else { - errmsg = format_win32_error(GetLastError()); - printf("QueryServiceStatus() failed : %s\n",errmsg); - tor_free(errmsg); - } - } else { - errmsg = format_win32_error(GetLastError()); - printf("ControlService() failed : %s\n", errmsg); - tor_free(errmsg); - } - return -1; -} - -/** Build a formatted command line used for the NT service. Return a - * pointer to the formatted string on success, or NULL on failure. Set - * *<b>using_default_torrc</b> to true if we're going to use the default - * location to torrc, or 1 if an option was specified on the command line. - */ -static char * -nt_service_command_line(int *using_default_torrc) -{ - TCHAR tor_exe[MAX_PATH+1]; - char tor_exe_ascii[MAX_PATH*2+1]; - char *command=NULL, *options=NULL; - smartlist_t *sl; - int i; - *using_default_torrc = 1; - - /* Get the location of tor.exe */ - if (0 == GetModuleFileName(NULL, tor_exe, MAX_PATH)) - return NULL; - - /* Get the service arguments */ - sl = smartlist_new(); - for (i = 1; i < backup_argc; ++i) { - if (!strcmp(backup_argv[i], "--options") || - !strcmp(backup_argv[i], "-options")) { - while (++i < backup_argc) { - if (!strcmp(backup_argv[i], "-f")) - *using_default_torrc = 0; - smartlist_add(sl, backup_argv[i]); - } - } - } - if (smartlist_len(sl)) - options = smartlist_join_strings(sl,"\" \"",0,NULL); - smartlist_free(sl); - -#ifdef UNICODE - wcstombs(tor_exe_ascii, tor_exe, sizeof(tor_exe_ascii)); - tor_exe_ascii[sizeof(tor_exe_ascii)-1] = '\0'; -#else - strlcpy(tor_exe_ascii, tor_exe, sizeof(tor_exe_ascii)); -#endif /* defined(UNICODE) */ - - /* Allocate a string for the NT service command line and */ - /* Format the service command */ - if (options) { - tor_asprintf(&command, "\"%s\" --nt-service \"%s\"", - tor_exe_ascii, options); - } else { /* ! options */ - tor_asprintf(&command, "\"%s\" --nt-service", tor_exe_ascii); - } - - tor_free(options); - return command; -} - -/** Creates a Tor NT service, set to start on boot. The service will be - * started if installation succeeds. Returns 0 on success, or -1 on - * failure. */ -static int -nt_service_install(int argc, char **argv) -{ - /* Notes about developing NT services: - * - * 1. Don't count on your CWD. If an absolute path is not given, the - * fopen() function goes wrong. - * 2. The parameters given to the nt_service_body() function differ - * from those given to main() function. - */ - - SC_HANDLE hSCManager = NULL; - SC_HANDLE hService = NULL; - SERVICE_DESCRIPTIONA sdBuff; - char *command; - char *errmsg; - const char *user_acct = NULL; - const char *password = ""; - int i; - OSVERSIONINFOEX info; - SID_NAME_USE sidUse; - DWORD sidLen = 0, domainLen = 0; - int is_win2k_or_worse = 0; - int using_default_torrc = 0; - - nt_service_loadlibrary(); - - /* Open the service control manager so we can create a new service */ - if ((hSCManager = nt_service_open_scm()) == NULL) - return -1; - /* Build the command line used for the service */ - if ((command = nt_service_command_line(&using_default_torrc)) == NULL) { - printf("Unable to build service command line.\n"); - service_fns.CloseServiceHandle_fn(hSCManager); - return -1; - } - - for (i=1; i < argc; ++i) { - if (!strcmp(argv[i], "--user") && i+1<argc) { - user_acct = argv[i+1]; - ++i; - } - if (!strcmp(argv[i], "--password") && i+1<argc) { - password = argv[i+1]; - ++i; - } - } - - /* Compute our version and see whether we're running win2k or earlier. */ - memset(&info, 0, sizeof(info)); - info.dwOSVersionInfoSize = sizeof(info); - if (! GetVersionEx((LPOSVERSIONINFO)&info)) { - printf("Call to GetVersionEx failed.\n"); - is_win2k_or_worse = 1; - } else { - if (info.dwMajorVersion < 5 || - (info.dwMajorVersion == 5 && info.dwMinorVersion == 0)) - is_win2k_or_worse = 1; - } - - if (!user_acct) { - if (is_win2k_or_worse) { - /* On Win2k, there is no LocalService account, so we actually need to - * fall back on NULL (the system account). */ - printf("Running on Win2K or earlier, so the LocalService account " - "doesn't exist. Falling back to SYSTEM account.\n"); - } else { - /* Genericity is apparently _so_ last year in Redmond, where some - * accounts are accounts that you can look up, and some accounts - * are magic and undetectable via the security subsystem. See - * http://msdn2.microsoft.com/en-us/library/ms684188.aspx - */ - printf("Running on a Post-Win2K OS, so we'll assume that the " - "LocalService account exists.\n"); - user_acct = GENSRV_USERACCT; - } - } else if (0 && service_fns.LookupAccountNameA_fn(NULL, // On this system - user_acct, - NULL, &sidLen, // Don't care about the SID - NULL, &domainLen, // Don't care about the domain - &sidUse) == 0) { - /* XXXX For some reason, the above test segfaults. Fix that. */ - printf("User \"%s\" doesn't seem to exist.\n", user_acct); - return -1; - } else { - printf("Will try to install service as user \"%s\".\n", user_acct); - } - /* XXXX This warning could be better about explaining how to resolve the - * situation. */ - if (using_default_torrc) - printf("IMPORTANT NOTE:\n" - " The Tor service will run under the account \"%s\". This means\n" - " that Tor will look for its configuration file under that\n" - " account's Application Data directory, which is probably not\n" - " the same as yours.\n", user_acct?user_acct:"<local system>"); - - /* Create the Tor service, set to auto-start on boot */ - if ((hService = service_fns.CreateServiceA_fn(hSCManager, GENSRV_SERVICENAME, - GENSRV_DISPLAYNAME, - SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, - SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, - command, NULL, NULL, NULL, - user_acct, password)) == NULL) { - errmsg = format_win32_error(GetLastError()); - printf("CreateService() failed : %s\n", errmsg); - service_fns.CloseServiceHandle_fn(hSCManager); - tor_free(errmsg); - tor_free(command); - return -1; - } - printf("Done with CreateService.\n"); - - /* Set the service's description */ - sdBuff.lpDescription = (char*)GENSRV_DESCRIPTION; - service_fns.ChangeServiceConfig2A_fn(hService, SERVICE_CONFIG_DESCRIPTION, - &sdBuff); - printf("Service installed successfully\n"); - - /* Start the service initially */ - nt_service_start(hService); - - service_fns.CloseServiceHandle_fn(hService); - service_fns.CloseServiceHandle_fn(hSCManager); - tor_free(command); - - return 0; -} - -/** Removes the Tor NT service. Returns 0 if the service was successfully - * removed, or -1 on error. */ -static int -nt_service_remove(void) -{ - SC_HANDLE hSCManager = NULL; - SC_HANDLE hService = NULL; - char *errmsg; - - nt_service_loadlibrary(); - if ((hSCManager = nt_service_open_scm()) == NULL) - return -1; - if ((hService = nt_service_open(hSCManager)) == NULL) { - service_fns.CloseServiceHandle_fn(hSCManager); - return -1; - } - - nt_service_stop(hService); - if (service_fns.DeleteService_fn(hService) == FALSE) { - errmsg = format_win32_error(GetLastError()); - printf("DeleteService() failed : %s\n", errmsg); - tor_free(errmsg); - service_fns.CloseServiceHandle_fn(hService); - service_fns.CloseServiceHandle_fn(hSCManager); - return -1; - } - - service_fns.CloseServiceHandle_fn(hService); - service_fns.CloseServiceHandle_fn(hSCManager); - printf("Service removed successfully\n"); - - return 0; -} - -/** Starts the Tor service. Returns 0 on success, or -1 on error. */ -static int -nt_service_cmd_start(void) -{ - SC_HANDLE hSCManager; - SC_HANDLE hService; - int start; - - if ((hSCManager = nt_service_open_scm()) == NULL) - return -1; - if ((hService = nt_service_open(hSCManager)) == NULL) { - service_fns.CloseServiceHandle_fn(hSCManager); - return -1; - } - - start = nt_service_start(hService); - service_fns.CloseServiceHandle_fn(hService); - service_fns.CloseServiceHandle_fn(hSCManager); - - return start; -} - -/** Stops the Tor service. Returns 0 on success, or -1 on error. */ -static int -nt_service_cmd_stop(void) -{ - SC_HANDLE hSCManager; - SC_HANDLE hService; - int stop; - - if ((hSCManager = nt_service_open_scm()) == NULL) - return -1; - if ((hService = nt_service_open(hSCManager)) == NULL) { - service_fns.CloseServiceHandle_fn(hSCManager); - return -1; - } - - stop = nt_service_stop(hService); - service_fns.CloseServiceHandle_fn(hService); - service_fns.CloseServiceHandle_fn(hSCManager); - - return stop; -} - -int -nt_service_parse_options(int argc, char **argv, int *should_exit) -{ - backup_argv = argv; - backup_argc = argc; - *should_exit = 0; - - if ((argc >= 3) && - (!strcmp(argv[1], "-service") || !strcmp(argv[1], "--service"))) { - nt_service_loadlibrary(); - *should_exit = 1; - if (!strcmp(argv[2], "install")) - return nt_service_install(argc, argv); - if (!strcmp(argv[2], "remove")) - return nt_service_remove(); - if (!strcmp(argv[2], "start")) - return nt_service_cmd_start(); - if (!strcmp(argv[2], "stop")) - return nt_service_cmd_stop(); - printf("Unrecognized service command '%s'\n", argv[2]); - return 1; - } - if (argc >= 2) { - if (!strcmp(argv[1], "-nt-service") || !strcmp(argv[1], "--nt-service")) { - nt_service_loadlibrary(); - nt_service_main(); - *should_exit = 1; - return 0; - } - // These values have been deprecated since 0.1.1.2-alpha; we've warned - // about them since 0.1.2.7-alpha. - if (!strcmp(argv[1], "-install") || !strcmp(argv[1], "--install")) { - nt_service_loadlibrary(); - fprintf(stderr, - "The %s option is deprecated; use \"--service install\" instead.", - argv[1]); - *should_exit = 1; - return nt_service_install(argc, argv); - } - if (!strcmp(argv[1], "-remove") || !strcmp(argv[1], "--remove")) { - nt_service_loadlibrary(); - fprintf(stderr, - "The %s option is deprecated; use \"--service remove\" instead.", - argv[1]); - *should_exit = 1; - return nt_service_remove(); - } - } - *should_exit = 0; - return 0; -} - -#endif /* defined(_WIN32) */ diff --git a/src/or/ntmain.h b/src/or/ntmain.h deleted file mode 100644 index 223d9e318b..0000000000 --- a/src/or/ntmain.h +++ /dev/null @@ -1,28 +0,0 @@ -/* 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 ntmain.h - * \brief Header file for ntmain.c. - **/ - -#ifndef TOR_NTMAIN_H -#define TOR_NTMAIN_H - -#ifdef _WIN32 -#define NT_SERVICE -#endif - -#ifdef NT_SERVICE -int nt_service_parse_options(int argc, char **argv, int *should_exit); -int nt_service_is_stopping(void); -void nt_service_set_state(DWORD state); -#else -#define nt_service_is_stopping() 0 -#endif /* defined(NT_SERVICE) */ - -#endif /* !defined(TOR_NTMAIN_H) */ - diff --git a/src/or/tor_main.c b/src/or/tor_main.c deleted file mode 100644 index 8c497fff8a..0000000000 --- a/src/or/tor_main.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright 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 */ - -#include "orconfig.h" -#ifdef ENABLE_RESTART_DEBUGGING -#include <stdlib.h> -#endif - -/** - * \file tor_main.c - * \brief Stub module containing a main() function. - * - * We keep the main function in a separate module so that the unit - * tests, which have their own main()s, can link against main.c. - **/ - -int tor_main(int argc, char *argv[]); - -/** We keep main() in a separate file so that our unit tests can use - * functions from main.c. - */ -int -main(int argc, char *argv[]) -{ - int r; -#ifdef ENABLE_RESTART_DEBUGGING - int restart_count = getenv("TOR_DEBUG_RESTART") ? 1 : 0; - again: -#endif - r = tor_main(argc, argv); - if (r < 0 || r > 255) - return 1; -#ifdef ENABLE_RESTART_DEBUGGING - else if (r == 0 && restart_count--) - goto again; -#endif - else - return r; -} - |