Skip to content

Commit

Permalink
Detecting and logging Windows versions
Browse files Browse the repository at this point in the history
Also 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: <1451422957-23951-1-git-send-email-lstipakov@gmail.com>
URL: http://article.gmane.org/gmane.network.openvpn.devel/10904
Signed-off-by: Gert Doering <gert@greenie.muc.de>
  • Loading branch information
lstipakov authored and cron2 committed Dec 30, 2015
1 parent 0e591a2 commit cdc65ea
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Changes.rst
Expand Up @@ -33,6 +33,9 @@ LZ4 Compression
Additionally to LZO compression OpenVPN now also supports LZ4
compression.

Windows version
Windows version is detected, logged and possibly signalled to server
(IV_PLAT_VER=<nn> if --push-peer-info is set on client)

User-visible Changes
--------------------
Expand Down
1 change: 1 addition & 0 deletions config-msvc.h
Expand Up @@ -44,6 +44,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
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Expand Up @@ -434,6 +434,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 \
Expand Down
3 changes: 2 additions & 1 deletion src/compat/Makefile.am
Expand Up @@ -27,4 +27,5 @@ libcompat_la_SOURCES = \
compat-daemon.c \
compat-inet_ntop.c \
compat-inet_pton.c \
compat-lz4.c compat-lz4.h
compat-lz4.c compat-lz4.h \
compat-versionhelpers.h
81 changes: 81 additions & 0 deletions src/compat/compat-versionhelpers.h
@@ -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
3 changes: 3 additions & 0 deletions src/openvpn/openvpn.c
Expand Up @@ -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 */
Expand Down
12 changes: 12 additions & 0 deletions src/openvpn/options.c
Expand Up @@ -3438,6 +3438,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)
{
Expand All @@ -3463,6 +3472,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
Expand Down
4 changes: 4 additions & 0 deletions src/openvpn/options.h
Expand Up @@ -688,6 +688,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);

Expand Down
4 changes: 4 additions & 0 deletions src/openvpn/ssl.c
Expand Up @@ -42,6 +42,7 @@
#endif

#include "syshead.h"
#include "win32.h"

#if defined(ENABLE_CRYPTO)

Expand Down Expand Up @@ -1868,6 +1869,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 */
Expand Down
63 changes: 63 additions & 0 deletions src/openvpn/win32.c
Expand Up @@ -46,6 +46,12 @@

#include "memdbg.h"

#ifdef HAVE_VERSIONHELPERS_H
#include <versionhelpers.h>
#else
#include "compat-versionhelpers.h"
#endif

/*
* WFP-related defines and GUIDs.
*/
Expand Down Expand Up @@ -1288,4 +1294,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
13 changes: 13 additions & 0 deletions src/openvpn/win32.h
Expand Up @@ -274,5 +274,18 @@ WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
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

0 comments on commit cdc65ea

Please sign in to comment.