]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Repair IPv6 netsh calls if Win XP is detected
authorLev Stipakov <lstipakov@gmail.com>
Tue, 29 Dec 2015 20:56:01 +0000 (22:56 +0200)
committerGert Doering <gert@greenie.muc.de>
Wed, 30 Dec 2015 17:14:26 +0000 (18:14 +0100)
v2:
* Add compat-versionhelpers.h to compat/Makefile.am so that
  "make dist" will include it into tarball.
* Indentation

v1:
* Use adapter name instead of index when calling netsh.exe on
  WinXP - sadly XP does not support indexes
* Write Windows version to log
* Send it with peer-info as IV_PLAT_VER

Signed-off-by: Lev Stipakov <lstipakov@gmail.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1451422561-23635-1-git-send-email-lstipakov@gmail.com>
URL: http://article.gmane.org/gmane.network.openvpn.devel/10903
Signed-off-by: Gert Doering <gert@greenie.muc.de>
13 files changed:
Changes.rst
config-msvc.h
configure.ac
src/compat/Makefile.am
src/compat/compat-versionhelpers.h [new file with mode: 0644]
src/openvpn/openvpn.c
src/openvpn/options.c
src/openvpn/options.h
src/openvpn/route.c
src/openvpn/ssl.c
src/openvpn/tun.c
src/openvpn/win32.c
src/openvpn/win32.h

index 520baf3ef845a001bbcdd3d130644fea9cc50417..813d92f5f254cfa5a5953946db783c9ed31b00b5 100644 (file)
@@ -103,12 +103,20 @@ Behavioral changes
 Version 2.3.10
 =============
 
+New features
+------------
+
+- Windows version is detected, logged and possibly signalled to server
+
 Behavioral changes
 ------------------
 
 - PolarSSL support changed from PolarSSL v1.2 to PolarSSL v1.3, 
   as v1.2 is end-of-support 2015-12-31.
 
+- fall back to using interface names for netsh.exe calls on
+  Windows XP (while keeping interface indexes on Windows 7)
+
 
 Version 2.3.9
 =============
index fa993843a947578f798634939546047c3dca32ad..ae43a5f4a88d551364636ef2bce236c3f84406f1 100644 (file)
@@ -45,6 +45,7 @@
 #define HAVE_SYS_STAT_H 1
 #define HAVE_LZO_LZO1X_H 1
 #define HAVE_LZO_LZOUTIL_H 1
+#define HAVE_VERSIONHELPERS_H 1
 
 #define HAVE_ACCESS 1
 #define HAVE_CHDIR 1
index 87d9116d1d8aa3569d62375d91a0d157798785ad..773cdeddbb74c51fc65b98c853c9373b499415b8 100644 (file)
@@ -423,6 +423,7 @@ AC_CHECK_HEADERS([ \
        netinet/in.h netinet/in_systm.h \
        netinet/tcp.h arpa/inet.h netdb.h \
        windows.h winsock2.h ws2tcpip.h \
+       versionhelpers.h \
 ])
 AC_CHECK_HEADERS([ \
        sys/time.h sys/ioctl.h sys/stat.h \
index 7ad4452533a3395097e1e692c8d73a212347b7ed..273389e293733e4ed1e4e1ebc44badc6da76434f 100644 (file)
@@ -26,4 +26,5 @@ libcompat_la_SOURCES = \
        compat-gettimeofday.c \
        compat-daemon.c \
        compat-inet_ntop.c \
-       compat-inet_pton.c
+       compat-inet_pton.c \
+       compat-versionhelpers.h
diff --git a/src/compat/compat-versionhelpers.h b/src/compat/compat-versionhelpers.h
new file mode 100644 (file)
index 0000000..f634091
--- /dev/null
@@ -0,0 +1,81 @@
+/**
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#ifndef _INC_VERSIONHELPERS
+#define _INC_VERSIONHELPERS
+
+#include <winapifamily.h>
+
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && !defined(__WIDL__)
+
+#ifdef __cplusplus
+#define VERSIONHELPERAPI inline bool
+#else
+#define VERSIONHELPERAPI FORCEINLINE BOOL
+#endif
+
+#define _WIN32_WINNT_WINBLUE    0x0603
+
+VERSIONHELPERAPI IsWindowsVersionOrGreater(WORD major, WORD minor, WORD servpack)
+{
+    OSVERSIONINFOEXW vi = {sizeof(vi),major,minor,0,0,{0},servpack};
+    return VerifyVersionInfoW(&vi, VER_MAJORVERSION|VER_MINORVERSION|VER_SERVICEPACKMAJOR,
+        VerSetConditionMask(VerSetConditionMask(VerSetConditionMask(0,
+            VER_MAJORVERSION,VER_GREATER_EQUAL),
+            VER_MINORVERSION,VER_GREATER_EQUAL),
+            VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL));
+}
+
+VERSIONHELPERAPI IsWindowsXPOrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0);
+}
+
+VERSIONHELPERAPI IsWindowsXPSP1OrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1);
+}
+
+VERSIONHELPERAPI IsWindowsXPSP2OrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2);
+}
+
+VERSIONHELPERAPI IsWindowsXPSP3OrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3);
+}
+
+VERSIONHELPERAPI IsWindowsVistaOrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
+}
+
+VERSIONHELPERAPI IsWindowsVistaSP1OrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1);
+}
+
+VERSIONHELPERAPI IsWindowsVistaSP2OrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
+}
+
+VERSIONHELPERAPI IsWindows7OrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
+}
+
+VERSIONHELPERAPI IsWindows7SP1OrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1);
+}
+
+VERSIONHELPERAPI IsWindows8OrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
+}
+
+VERSIONHELPERAPI IsWindows8Point1OrGreater(void) {
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0);
+}
+
+VERSIONHELPERAPI IsWindowsServer(void) {
+    OSVERSIONINFOEXW vi = {sizeof(vi),0,0,0,0,{0},0,0,0,VER_NT_WORKSTATION};
+    return !VerifyVersionInfoW(&vi, VER_PRODUCT_TYPE, VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL));
+}
+
+#endif
+#endif
index 32e326e9c654330018655344cd14dbf88cbb387e..823c3dd13d49c8e4cae9c48f893e01853b7e73eb 100644 (file)
@@ -220,6 +220,9 @@ openvpn_main (int argc, char *argv[])
 
          /* print version number */
          msg (M_INFO, "%s", title_string);
+#ifdef WIN32
+         show_windows_version(M_INFO);
+#endif
          show_library_versions(M_INFO);
 
          /* misc stuff */
index 1832bc598ea884a192407d6e5606932090082fc6..a49a4fba9e5aa46b7b22d1094b5c45e07cb86273 100644 (file)
@@ -3489,6 +3489,15 @@ usage_small (void)
   openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */
 }
 
+#ifdef WIN32
+void show_windows_version(const unsigned int flags)
+{
+  struct gc_arena gc = gc_new ();
+  msg (flags, "Windows version %s", win32_version_string (&gc, true));
+  gc_free (&gc);
+}
+#endif
+
 void
 show_library_versions(const unsigned int flags)
 {
@@ -3514,6 +3523,9 @@ usage_version (void)
 {
   msg (M_INFO|M_NOPREFIX, "%s", title_string);
   show_library_versions( M_INFO|M_NOPREFIX );
+#ifdef WIN32
+  show_windows_version( M_INFO|M_NOPREFIX );
+#endif
   msg (M_INFO|M_NOPREFIX, "Originally developed by James Yonan");
   msg (M_INFO|M_NOPREFIX, "Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>");
 #ifndef ENABLE_SMALL
index 622706a30287b714ec76c3906454beecfc63baa4..26b09ea405e0bdf0c6cf7387bef6a0219c281132 100644 (file)
@@ -690,6 +690,10 @@ void usage_small (void);
 
 void show_library_versions(const unsigned int flags);
 
+#ifdef WIN32
+void show_windows_version(const unsigned int flags);
+#endif
+
 void init_options (struct options *o, const bool init_gc);
 void uninit_options (struct options *o);
 
index cf5a0671414a3f44b891e828c82981e29db2058f..f35bc855b2d069a7d99724ee08b78b59f2873c4c 100644 (file)
@@ -42,6 +42,7 @@
 #include "manage.h"
 #include "win32.h"
 #include "options.h"
+#include "win32.h"
 
 #include "memdbg.h"
 
@@ -1623,9 +1624,12 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
 
 #elif defined (WIN32)
 
-  struct buffer out = alloc_buf_gc (64, &gc);
-  buf_printf (&out, "interface=%d", tt->adapter_index );
-  device = buf_bptr(&out);
+  if (win32_version_info() != WIN_XP)
+    {
+      struct buffer out = alloc_buf_gc (64, &gc);
+      buf_printf (&out, "interface=%d", tt->adapter_index );
+      device = buf_bptr(&out);
+    }
 
   /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
   argv_printf (&argv, "%s%sc interface ipv6 add route %s/%d %s",
@@ -1958,9 +1962,12 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne
 
 #elif defined (WIN32)
 
-  struct buffer out = alloc_buf_gc (64, &gc);
-  buf_printf (&out, "interface=%d", tt->adapter_index );
-  device = buf_bptr(&out);
+  if (win32_version_info() != WIN_XP)
+    {
+      struct buffer out = alloc_buf_gc (64, &gc);
+      buf_printf (&out, "interface=%d", tt->adapter_index );
+      device = buf_bptr(&out);
+    }
 
   /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
   argv_printf (&argv, "%s%sc interface ipv6 delete route %s/%d %s",
index f728ffb88be670bb32735705ec229c1dab82790b..06798904235ebd257c8c50221b53de6ed6564cdf 100644 (file)
@@ -43,6 +43,7 @@
 #endif
 
 #include "syshead.h"
+#include "win32.h"
 
 #if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
 
@@ -1848,6 +1849,9 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
          if (rgi.flags & RGI_HWADDR_DEFINED)
            buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (rgi.hwaddr, 6, 0, 1, ":", &gc));
          buf_printf (&out, "IV_SSL=%s\n", get_ssl_library_version() );
+#if defined(WIN32)
+         buf_printf (&out, "IV_PLAT_VER=%s\n", win32_version_string (&gc, false));
+#endif
         }
 
       /* push env vars that begin with UV_ and IV_GUI_VER */
index b08c8276111453925bf901b5df362d451e6095f3..bb019c085f2aae61f799071663e53c8b98710a6b 100644 (file)
@@ -1244,7 +1244,7 @@ do_ifconfig (struct tuntap *tt,
                     "%s%sc interface ipv6 set address %s %s store=active",
                     get_win_sys_path(),
                     NETSH_PATH_SUFFIX,
-                    iface,
+                    win32_version_info() == WIN_XP ? actual : iface,
                     ifconfig_ipv6_local);
        netsh_command (&argv, 4);
 
index e87cb7f65bdd5b363f4cf639513ba683f12ea962..6c6ac4c83a45205de08a1dd806b68684eed1704b 100644 (file)
 
 #include "win32_wfp.h"
 
+#ifdef HAVE_VERSIONHELPERS_H
+#include <versionhelpers.h>
+#else
+#include "compat-versionhelpers.h"
+#endif
+
 /* WFP function pointers. Initialized in win_wfp_init_funcs() */
 func_ConvertInterfaceIndexToLuid ConvertInterfaceIndexToLuid = NULL;
 func_FwpmEngineOpen0 FwpmEngineOpen0 = NULL;
@@ -1289,4 +1295,61 @@ win_wfp_uninit()
     return true;
 }
 
+int
+win32_version_info()
+{
+    if (!IsWindowsXPOrGreater())
+    {
+        msg (M_FATAL, "Error: Windows version must be XP or greater.");
+    }
+
+    if (!IsWindowsVistaOrGreater())
+    {
+        return WIN_XP;
+    }
+
+    if (!IsWindows7OrGreater())
+    {
+        return WIN_VISTA;
+    }
+
+    if (!IsWindows8OrGreater())
+    {
+        return WIN_7;
+    }
+    else
+    {
+        return WIN_8;
+    }
+}
+
+const char *
+win32_version_string(struct gc_arena *gc, bool add_name)
+{
+    int version = win32_version_info();
+    struct buffer out = alloc_buf_gc (256, gc);
+
+    switch (version)
+    {
+        case WIN_XP:
+            buf_printf (&out, "5.1%s", add_name ? " (Windows XP)" : "");
+            break;
+        case WIN_VISTA:
+            buf_printf (&out, "6.0%s", add_name ? " (Windows Vista)" : "");
+            break;
+        case WIN_7:
+            buf_printf (&out, "6.1%s", add_name ? " (Windows 7)" : "");
+            break;
+        case WIN_8:
+            buf_printf (&out, "6.2%s", add_name ? " (Windows 8 or greater)" : "");
+            break;
+        default:
+            msg (M_NONFATAL, "Unknown Windows version: %d", version);
+            buf_printf (&out, "0.0%s", add_name ? " (unknown)" : "");
+            break;
+    }
+
+    return (const char *)out.data;
+}
+
 #endif
index 776ef36d296bdfe54000c0c5d128262b9a79dfde..099018260b9a63500208c267150fcaf1003ce34e 100644 (file)
@@ -275,5 +275,18 @@ bool win_wfp_init_funcs();
 bool win_wfp_block_dns(const NET_IFINDEX index);
 bool win_wfp_uninit();
 
+#define WIN_XP 0
+#define WIN_VISTA 1
+#define WIN_7 2
+#define WIN_8 3
+
+int win32_version_info();
+
+/*
+String representation of Windows version number and name, see
+https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx
+*/
+const char * win32_version_string(struct gc_arena *gc, bool add_name);
+
 #endif
 #endif