diff --git a/src/app/main/main.c b/src/app/main/main.c index 4275a98bd0..2a5cb4aa07 100644 --- a/src/app/main/main.c +++ b/src/app/main/main.c @@ -1279,6 +1279,13 @@ tor_run_main(const tor_main_configuration_t *tor_cfg) #endif } + if (tor_cfg->run_tor_only && get_options()->command != CMD_RUN_TOR) { + log_err(LD_CONFIG, "Unsupported command when running as an NT service."); + result = -1; + tor_cleanup(); + goto done; + } + switch (get_options()->command) { case CMD_RUN_TOR: #ifdef NT_SERVICE diff --git a/src/app/main/ntmain.c b/src/app/main/ntmain.c index a49dfdbbc9..3d923edf57 100644 --- a/src/app/main/ntmain.c +++ b/src/app/main/ntmain.c @@ -29,6 +29,8 @@ #include "lib/evloop/compat_libevent.h" #include "lib/fs/winlib.h" #include "lib/log/win32err.h" +#include "feature/api/tor_api.h" +#include "feature/api/tor_api_internal.h" #include #define GENSRV_SERVICENAME "tor" @@ -263,7 +265,6 @@ nt_service_control(DWORD request) static void nt_service_body(int argc, char **argv) { - int r; (void) argc; /* unused */ (void) argv; /* unused */ nt_service_loadlibrary(); @@ -283,24 +284,20 @@ nt_service_body(int argc, char **argv) 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); + tor_main_configuration_t *cfg = tor_main_configuration_new(); + cfg->run_tor_only = 1; + if (tor_main_configuration_set_command_line(cfg, backup_argc, + backup_argv) < 0) 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(); - run_tor_main_loop(); - tor_cleanup(); + + tor_run_main(cfg); + + tor_main_configuration_free(cfg); } /** Main service entry point. Starts the service control dispatcher and waits @@ -323,29 +320,14 @@ nt_service_main(void) 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)) + tor_main_configuration_t *cfg = tor_main_configuration_new(); + cfg->run_tor_only = 1; + if (tor_main_configuration_set_command_line(cfg, backup_argc, + backup_argv) < 0) return; - switch (get_options()->command) { - case CMD_RUN_TOR: - run_tor_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: - case CMD_IMMEDIATE: - default: - log_err(LD_CONFIG, "Illegal command number %d: internal error.", - get_options()->command); - } - tor_cleanup(); + + tor_run_main(cfg); + tor_main_configuration_free(cfg); } } } diff --git a/src/feature/api/tor_api_internal.h b/src/feature/api/tor_api_internal.h index 115d33d58e..40c64e1ab8 100644 --- a/src/feature/api/tor_api_internal.h +++ b/src/feature/api/tor_api_internal.h @@ -29,6 +29,11 @@ struct tor_main_configuration_t { /** Socket that Tor will use as an owning control socket. Owned. */ tor_socket_t owning_controller_socket; + + /** Disable commands other than "run tor". Not for use from outside Tor + * itself; if you need to use this for embedding, please contact the tor + * developers. */ + int run_tor_only; }; #endif /* !defined(TOR_API_INTERNAL_H) */