From b90c6f17b476b0ef1bd831f4a475425c94ba237f Mon Sep 17 00:00:00 2001 From: James Yonan Date: Fri, 16 Jul 2010 18:01:11 +0000 Subject: Added --register-dns option for Windows. Fixed some issues on Windows with --log, subprocess creation for command execution, and stdout/stderr redirection. Version 2.1.1m. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@6304 e7ae566f-a301-0410-adde-c780ea21d3b5 --- error.c | 4 ++++ init.c | 4 ++++ openvpn.8 | 6 ++++++ options.c | 21 ++++++++++++++++++--- tun.c | 39 ++++++++++++++++++++++++++++++++++++++- tun.h | 5 +++++ version.m4 | 2 +- win32.c | 8 ++------ win32.h | 1 + 9 files changed, 79 insertions(+), 11 deletions(-) diff --git a/error.c b/error.c index ce61f6c..ec8f9df 100644 --- a/error.c +++ b/error.c @@ -521,6 +521,10 @@ redirect_stdout_stderr (const char *file, bool append) if (msgfp == NULL) msg (M_ERR, "Error: --log redirect failed due to _fdopen"); + /* redirect C-library stdout/stderr to log file */ + if (_dup2 (log_fd, 1) == -1 || _dup2 (log_fd, 2) == -1) + msg (M_WARN, "Error: --log redirect of stdout/stderr failed"); + std_redir = true; } #elif defined(HAVE_DUP2) diff --git a/init.c b/init.c index 90b253f..a46fbde 100644 --- a/init.c +++ b/init.c @@ -1138,6 +1138,10 @@ initialization_sequence_completed (struct context *c, const unsigned int flags) if ((flags & (ISC_ERRORS|ISC_SERVER)) == 0 && connection_list_defined (&c->options)) connection_list_set_no_advance (&c->options); +#ifdef WIN32 + fork_register_dns_action (c->c1.tuntap); +#endif + #ifdef ENABLE_MANAGEMENT /* Tell management interface that we initialized */ if (management) diff --git a/openvpn.8 b/openvpn.8 index 12294be..1aa8382 100644 --- a/openvpn.8 +++ b/openvpn.8 @@ -4749,6 +4749,12 @@ This option has the same caveats as above. .\"********************************************************* .TP +.B --register-dns +Run ipconfig /flushdns and ipconfig /registerdns on +connection initiation. This is known to kick Windows into +recognizing pushed DNS servers. +.\"********************************************************* +.TP .B --pause-exit Put up a "press any key to continue" message on the console prior to OpenVPN program exit. This option is automatically used by the diff --git a/options.c b/options.c index 305704f..ce53ad5 100644 --- a/options.c +++ b/options.c @@ -615,6 +615,8 @@ static const char usage_message[] = "--dhcp-pre-release : Ask Windows to release the previous TAP adapter lease on\n" " startup.\n" "--dhcp-release : Ask Windows to release the TAP adapter lease on shutdown.\n" + "--register-dns : Run ipconfig /flushdns and ipconfig /registerdns on\n" + " connection initiation.\n" "--tap-sleep n : Sleep for n seconds after TAP adapter open before\n" " attempting to set adapter properties.\n" "--pause-exit : When run from a console window, pause before exiting.\n" @@ -5288,7 +5290,7 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_IPWIN32); options->tuntap_options.dhcp_release = true; } - else if (streq (p[0], "dhcp-rr") && p[1]) /* standalone method for internal use */ + else if (streq (p[0], "dhcp-internal") && p[1]) /* standalone method for internal use */ { unsigned int adapter_index; VERIFY_PERMISSION (OPT_P_GENERAL); @@ -5299,13 +5301,26 @@ add_option (struct options *options, dhcp_release_by_adapter_index (adapter_index); if (options->tuntap_options.dhcp_renew) dhcp_renew_by_adapter_index (adapter_index); - openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */ + openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ + } + else if (streq (p[0], "register-dns")) + { + VERIFY_PERMISSION (OPT_P_IPWIN32); + options->tuntap_options.register_dns = true; + } + else if (streq (p[0], "rdns-internal")) /* standalone method for internal use */ + { + VERIFY_PERMISSION (OPT_P_GENERAL); + set_debug_level (options->verbosity, SDL_CONSTRAIN); + if (options->tuntap_options.register_dns) + ipconfig_register_dns (NULL); + openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ } else if (streq (p[0], "show-valid-subnets")) { VERIFY_PERMISSION (OPT_P_GENERAL); show_valid_win32_tun_subnets (); - openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */ + openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ } else if (streq (p[0], "pause-exit")) { diff --git a/tun.c b/tun.c index fcc4c01..b05fcf8 100644 --- a/tun.c +++ b/tun.c @@ -3382,6 +3382,28 @@ netsh_command (const struct argv *a, int n) msg (M_FATAL, "NETSH: command failed"); } +void +ipconfig_register_dns (const struct env_set *es) +{ + struct argv argv; + bool status; + const char err[] = "ERROR: Windows ipconfig command failed"; + + netcmd_semaphore_lock (); + argv_init (&argv); + argv_printf (&argv, "%s%sc /flushdns", + get_win_sys_path(), + WIN_IPCONFIG_PATH_SUFFIX); + status = openvpn_execve_check (&argv, es, 0, err); + argv_reset(&argv); + argv_printf (&argv, "%s%sc /registerdns", + get_win_sys_path(), + WIN_IPCONFIG_PATH_SUFFIX); + status = openvpn_execve_check (&argv, es, 0, err); + argv_reset(&argv); + netcmd_semaphore_release (); +} + void ip_addr_string_to_array (in_addr_t *dest, int *dest_len, const IP_ADDR_STRING *src) { @@ -3817,13 +3839,28 @@ fork_dhcp_action (struct tuntap *tt) buf_printf (&cmd, " --dhcp-pre-release"); if (tt->options.dhcp_renew) buf_printf (&cmd, " --dhcp-renew"); - buf_printf (&cmd, " --dhcp-rr %u", (unsigned int)tt->adapter_index); + buf_printf (&cmd, " --dhcp-internal %u", (unsigned int)tt->adapter_index); fork_to_self (BSTR (&cmd)); gc_free (&gc); } } +void +fork_register_dns_action (struct tuntap *tt) +{ + if (tt && tt->options.register_dns) + { + struct gc_arena gc = gc_new (); + struct buffer cmd = alloc_buf_gc (256, &gc); + const int verb = 3; + + buf_printf (&cmd, "openvpn --verb %d --register-dns --rdns-internal", verb); + fork_to_self (BSTR (&cmd)); + gc_free (&gc); + } +} + void open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) { diff --git a/tun.h b/tun.h index 9e33fd2..011ab54 100644 --- a/tun.h +++ b/tun.h @@ -99,6 +99,8 @@ struct tuntap_options { bool dhcp_renew; bool dhcp_pre_release; bool dhcp_release; + + bool register_dns; }; #elif TARGET_LINUX @@ -335,6 +337,9 @@ void tun_show_debug (struct tuntap *tt); bool dhcp_release_by_adapter_index(const DWORD adapter_index); bool dhcp_renew_by_adapter_index (const DWORD adapter_index); +void fork_register_dns_action (struct tuntap *tt); +void ipconfig_register_dns (const struct env_set *es); + void tun_standby_init (struct tuntap *tt); bool tun_standby (struct tuntap *tt); diff --git a/version.m4 b/version.m4 index 4d88364..b6d1f61 100644 --- a/version.m4 +++ b/version.m4 @@ -1,5 +1,5 @@ dnl define the OpenVPN version -define(PRODUCT_VERSION,[2.1.1l]) +define(PRODUCT_VERSION,[2.1.1m]) dnl define the TAP version define(PRODUCT_TAP_ID,[tap0901]) define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9]) diff --git a/win32.c b/win32.c index 8fa898f..2a3350d 100644 --- a/win32.c +++ b/win32.c @@ -971,10 +971,8 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i /* fill in STARTUPINFO struct */ GetStartupInfo(&start_info); start_info.cb = sizeof(start_info); - start_info.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; + start_info.dwFlags = STARTF_USESHOWWINDOW; start_info.wShowWindow = SW_HIDE; - start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); - start_info.hStdOutput = start_info.hStdError = GetStdHandle(STD_OUTPUT_HANDLE); if (CreateProcess (cmd, cl, NULL, NULL, FALSE, 0, env, NULL, &start_info, &proc_info)) { @@ -1042,10 +1040,8 @@ fork_to_self (const char *cmdline) /* fill in STARTUPINFO struct */ GetStartupInfo(&start_info); start_info.cb = sizeof(start_info); - start_info.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; + start_info.dwFlags = STARTF_USESHOWWINDOW; start_info.wShowWindow = SW_HIDE; - start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); - start_info.hStdOutput = start_info.hStdError = GetStdHandle(STD_OUTPUT_HANDLE); if (CreateProcess (self_exe, cl, NULL, NULL, FALSE, 0, NULL, NULL, &start_info, &proc_info)) { diff --git a/win32.h b/win32.h index b661169..f974b06 100644 --- a/win32.h +++ b/win32.h @@ -33,6 +33,7 @@ #define DEFAULT_WIN_SYS_PATH "C:\\WINDOWS" /* --win-sys default value */ #define NETSH_PATH_SUFFIX "\\system32\\netsh.exe" #define WIN_ROUTE_PATH_SUFFIX "\\system32\\route.exe" +#define WIN_IPCONFIG_PATH_SUFFIX "\\system32\\ipconfig.exe" /* * Win32-specific OpenVPN code, targetted at the mingw -- cgit