mirror of
https://github.com/OpenVPN/openvpn.git
synced 2024-09-19 19:42:30 +02:00
Repair IPv6 netsh calls if Win XP is detected
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>
This commit is contained in:
parent
ca6045756e
commit
84eb66bf78
@ -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
|
||||
=============
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
81
src/compat/compat-versionhelpers.h
Normal file
81
src/compat/compat-versionhelpers.h
Normal file
@ -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
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -48,6 +48,12 @@
|
||||
|
||||
#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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user