Переглянути джерело

vlmcsd-1106-2016-12-06-Hotbird64

Wind4 9 роки тому
батько
коміт
af593fc11b

+ 3 - 0
VisualStudio/vlmcsd/vlmcsd.vcxproj

@@ -306,9 +306,11 @@
     <ClInclude Include="..\..\src\output.h" />
     <ClInclude Include="..\..\src\rpc.h" />
     <ClInclude Include="..\..\src\shared_globals.h" />
+    <ClInclude Include="..\..\src\tap-windows.h" />
     <ClInclude Include="..\..\src\types.h" />
     <ClInclude Include="..\..\src\vlmcsd.h" />
     <ClInclude Include="..\..\src\wingetopt.h" />
+    <ClInclude Include="..\..\src\wintap.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\crypto.c" />
@@ -324,6 +326,7 @@
     <ClCompile Include="..\..\src\shared_globals.c" />
     <ClCompile Include="..\..\src\vlmcsd.c" />
     <ClCompile Include="..\..\src\wingetopt.c" />
+    <ClCompile Include="..\..\src\wintap.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 9 - 0
VisualStudio/vlmcsd/vlmcsd.vcxproj.filters

@@ -63,6 +63,12 @@
     <ClInclude Include="..\..\src\kmsdata.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\tap-windows.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\wintap.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\crypto.c">
@@ -104,5 +110,8 @@
     <ClCompile Include="..\..\src\kmsdata.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\wintap.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 3 - 0
VisualStudio/vlmcsdmulti/vlmcsdmulti.vcxproj

@@ -292,6 +292,7 @@
     <ClCompile Include="..\..\src\vlmcsd.c" />
     <ClCompile Include="..\..\src\vlmcsdmulti.c" />
     <ClCompile Include="..\..\src\wingetopt.c" />
+    <ClCompile Include="..\..\src\wintap.c" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\config.h" />
@@ -307,10 +308,12 @@
     <ClInclude Include="..\..\src\output.h" />
     <ClInclude Include="..\..\src\rpc.h" />
     <ClInclude Include="..\..\src\shared_globals.h" />
+    <ClInclude Include="..\..\src\tap-windows.h" />
     <ClInclude Include="..\..\src\types.h" />
     <ClInclude Include="..\..\src\vlmcs.h" />
     <ClInclude Include="..\..\src\vlmcsd.h" />
     <ClInclude Include="..\..\src\wingetopt.h" />
+    <ClInclude Include="..\..\src\wintap.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 9 - 0
VisualStudio/vlmcsdmulti/vlmcsdmulti.vcxproj.filters

@@ -63,6 +63,9 @@
     <ClCompile Include="..\..\src\kmsdata-full.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\wintap.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\config.h">
@@ -116,5 +119,11 @@
     <ClInclude Include="..\..\src\kmsdata.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\tap-windows.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\wintap.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>

+ 6 - 0
etc/vlmcsd.ini

@@ -23,6 +23,12 @@
 # Set ePID/HwId for Office 2016 (including Visio and Project) explicitly
 ;Office2016 = 06401-00206-437-444444-03-1033-9600.0000-3622014 / 01 02 03 04 05 06 07 08
 
+# Use a compatible VPN device to create a hidden local IPv4 address
+# Command line: -O
+# VPN = <VPN adapter name>[=<IPv4 address>][/<CIDR mask>][:<DHCP lease duration>]
+# Use VPN adapter "KMS Mirror" give it IP address 192.168.123.100 with a lease duration of one day and make entire 192.168.128.x a hidden local IPv4 address.
+;VPN = KMS Mirror=192.168.123.100/24:1d
+
 # Use custom TCP port
 # Command line: -P 
 # ***The Port directive only works if vlmcsd was compiled to use MS RPC or simple sockets

BIN
floppy/floppy144.vfd


+ 1 - 1
man/vlmcs.1.html

@@ -1,5 +1,5 @@
 <!-- Creator     : groff version 1.22.3 -->
-<!-- CreationDate: Mon Nov 28 01:28:23 2016 -->
+<!-- CreationDate: Mon Dec  5 18:18:46 2016 -->
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
 <html>

BIN
man/vlmcs.1.pdf


+ 1 - 1
man/vlmcsd-floppy.7.html

@@ -1,5 +1,5 @@
 <!-- Creator     : groff version 1.22.3 -->
-<!-- CreationDate: Mon Nov 28 01:28:23 2016 -->
+<!-- CreationDate: Mon Dec  5 18:18:46 2016 -->
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
 <html>

BIN
man/vlmcsd-floppy.7.pdf


+ 1 - 1
man/vlmcsd.7.html

@@ -1,5 +1,5 @@
 <!-- Creator     : groff version 1.22.3 -->
-<!-- CreationDate: Mon Nov 28 01:28:23 2016 -->
+<!-- CreationDate: Mon Dec  5 18:18:46 2016 -->
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
 <html>

BIN
man/vlmcsd.7.pdf


+ 16 - 3
man/vlmcsd.8

@@ -1,5 +1,5 @@
 .mso www.tmac
-.TH VLMCSD 8 "November 2016" "Hotbird64" "KMS Activation Manual"
+.TH VLMCSD 8 "December 2016" "Hotbird64" "KMS Activation Manual"
 .LO 8
 
 .SH NAME
@@ -76,10 +76,23 @@ in the 32-bit ABI of the 64-bit kernel. If you have a 64-bit FreeBSD kernel, you
 If vlmcsd was started by an internet superserver or was compiled to use Microsoft RPC (Windows only) or simple sockets, \fB-o1\fR and \fB-o3\fR are not available by design.
 .RE
 
-.IP "\fB-P\fR \fIport"
+.IP "\fB-P\fR \fIport\fR"
 Use TCP \fIport\fR for all subsequent \fB-L\fR statements that do not include an optional port. If you use \fB-P\fR and \fB-L\fR, \fB-P\fR must be specified before \fB-L\fR.
 
-.IP "\fB-F0\fR and \fB-F1\fR
+.IP "\fB-O\fR \fIvpn-adapter-name\fR[=\fIipv4-address\fR][/\fIcidr-mask\fR][:\fIdhcp-lease-duration\fR]"
+Enables a compatible VPN adapter to create additional local IPv4 addresses (like 127.0.0.1) that appear as remote IPv4 addresses to the system. This allows product activation using a local instance of vlmcsd. This feature is only available in Windows and Cygwin builds of vlmcsd since it is not of any use on other operating systems. Compatible VPN adapters are Tap-windows version 8.2 or higher (from OpenVPN) and the TeamViewer VPN adapter. There are two special \fIvpn-adapter-name\fRs. A single period (.) instructs vlmcsd to use the first available compatible VPN adapter. A single dash (\-) disables the use of a VPN adapter if one has been configured in \fBvlmcsd.ini\fR(5). The \fIvpn-adapter-name\fR is \fBnot\fR case-sensitive. If the \fIvpn-adapter-name\fR contains spaces (e.g. Ethernet 3), you must enclose it in quotes.
+
+The default \fIipv4-address\fR is 10.10.10.9 and the default \fIcidr-mask\fR is 30. If you are using the default values, your VPN adapter uses an IPv4 address of 10.10.10.9 and you can set your activation client to use the easy to remember address 10.10.10.10 (e.g. slmgr /skms 10.10.10.10 or cscript ospp.vbs /sethst:10.10.10.10).
+
+The \fIdhcp-lease-duration\fR is a number optionally followed by s, m, h, d or w to indicate seconds, minutes, hours, days or weeks. The default \fIdhcp-lease-duration\fR is 1d (one day). It is normally not required to change this value.
+
+It is advised not to manually configure your OpenVPN TAP or TeamViewer VPN adapter in "Network Connections". If you set the IPv4 configuration manually anyway, the IPv4 address and the subnet mask must match the \fB-O\fR parameter. It is safe leave the IPv4 configuration to automatic (DHCP). vlmcsd will wait up to four seconds for the DHCP configuration to complete before binding to and listenin on any interfaces.
+
+You should be aware that only one program can use a VPN adapter at a time. If you use the TeamViewer VPN adapter for example, you will not be able to use the VPN feature of TeamViewer as long as vlmcsd is running. The same applies to OpenVPN TAP adapters that are in use by other programs (for example OpenVPN, QEMU, Ratiborus VM, aiccu, etc.). The best way to avoid conflicts is to install Tap-Windows from OpenVPN, cd to C:\\Program Files\\TAP-Windows\\bin and run addtap.bat to install an additional TAP adapter. Go to "Network Connections" and rename the new adapter to "vlmcsd" and specify \fB-O vlmcsd\fR to use it.
+
+Example: \fB-O "Ethernet 7"=192.168.123.1/24\fR (uses VPN adapter Ethernet 7 with IPv4 address 192.168.123.1 and have 192.168.123.2 to 192.168.123.254 as additional local (but apparently remote) IPv4 addresses.
+
+.IP "\fB-F0\fR and \fB-F1\fR"
 Allow (\fB-F1\fR) or disallow (\fB-F0\fR) binding to IP addresses that are currently not configured on your system. The default is \fB-F0\fR. \fB-F1\fR allows you to bind to an IP address that may be configured after you started \fBvlmcsd\fR. \fBvlmcsd\fR will listen on that address as soon as it becomes available. This feature is only available under Linux (IPv4 and IPv6) and FreeBSD (IPv4 only). FreeBSD allows this feature only for the root user (more correctly: processes that have the PRIV_NETINET_BINDANY privilege). Linux does not require a capability for this.
 
 .IP "\fB-t\fR \fIseconds\fR"

+ 53 - 1
man/vlmcsd.8.dos.txt

@@ -172,6 +172,58 @@ OPTIONS
               ified before -L.
 
 
+       -O vpn-adapter-name[=ipv4-address][/cidr-mask][:dhcp-lease-duration]
+              Enables a compatible VPN adapter to create additional local IPv4
+              addresses  (like 127.0.0.1) that appear as remote IPv4 addresses
+              to the system. This allows  product  activation  using  a  local
+              instance  of  vlmcsd.  This feature is only available in Windows
+              and Cygwin builds of vlmcsd since it is not of any use on  other
+              operating  systems. Compatible VPN adapters are Tap-windows ver‐
+              sion 8.2  or  higher  (from  OpenVPN)  and  the  TeamViewer  VPN
+              adapter.  There  are  two  special  vpn-adapter-names.  A single
+              period (.) instructs vlmcsd to use the first available  compati‐
+              ble  VPN  adapter.  A  single dash (-) disables the use of a VPN
+              adapter if one has been configured in  vlmcsd.ini(5).  The  vpn-
+              adapter-name is not case-sensitive. If the vpn-adapter-name con‐
+              tains spaces (e.g. Ethernet 3), you must enclose it in quotes.
+
+              The default ipv4-address is 10.10.10.9 and the default cidr-mask
+              is  30.  If  you  are using the default values, your VPN adapter
+              uses an IPv4 address of 10.10.10.9 and you can set your  activa‐
+              tion  client  to  use  the  easy to remember address 10.10.10.10
+              (e.g.   slmgr   /skms   10.10.10.10    or    cscript    ospp.vbs
+              /sethst:10.10.10.10).
+
+              The dhcp-lease-duration is a number optionally followed by s, m,
+              h, d or w to indicate seconds, minutes, hours,  days  or  weeks.
+              The  default dhcp-lease-duration is 1d (one day). It is normally
+              not required to change this value.
+
+              It is advised not to manually  configure  your  OpenVPN  TAP  or
+              TeamViewer  VPN adapter in "Network Connections". If you set the
+              IPv4 configuration manually anyway, the  IPv4  address  and  the
+              subnet  mask  must  match the -O parameter. It is safe leave the
+              IPv4 configuration to automatic (DHCP). vlmcsd will wait  up  to
+              four seconds for the DHCP configuration to complete before bind‐
+              ing to and listenin on any interfaces.
+
+              You should be aware that only one program can use a VPN  adapter
+              at  a  time.  If you use the TeamViewer VPN adapter for example,
+              you will not be able to use the VPN  feature  of  TeamViewer  as
+              long  as  vlmcsd  is  running.  The  same applies to OpenVPN TAP
+              adapters that are in use by other programs (for example OpenVPN,
+              QEMU,  Ratiborus  VM,  aiccu,  etc.). The best way to avoid con‐
+              flicts is to install Tap-Windows from OpenVPN, cd to  C:\Program
+              Files\TAP-Windows\bin  and  run  addtap.bat  to install an addi‐
+              tional TAP adapter. Go to "Network Connections" and  rename  the
+              new adapter to "vlmcsd" and specify -O vlmcsd to use it.
+
+              Example: -O "Ethernet 7"=192.168.123.1/24 (uses VPN adapter Eth‐
+              ernet 7 with IPv4 address 192.168.123.1 and  have  192.168.123.2
+              to  192.168.123.254  as additional local (but apparently remote)
+              IPv4 addresses.
+
+
        -F0 and -F1
               Allow (-F1) or disallow (-F0) binding to IP addresses  that  are
               currently not configured on your system. The default is -F0. -F1
@@ -705,4 +757,4 @@ SEE ALSO
 
 
 
-Hotbird64                        November 2016                       VLMCSD(8)
+Hotbird64                        December 2016                       VLMCSD(8)

+ 65 - 1
man/vlmcsd.8.html

@@ -1,5 +1,5 @@
 <!-- Creator     : groff version 1.22.3 -->
-<!-- CreationDate: Mon Nov 28 01:28:23 2016 -->
+<!-- CreationDate: Mon Dec  5 18:18:46 2016 -->
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
 <html>
@@ -273,6 +273,70 @@ subsequent <b>-L</b> statements that do not include an
 optional port. If you use <b>-P</b> and <b>-L</b>, <b>-P</b>
 must be specified before <b>-L</b>.</p>
 
+<p style="margin-left:11%;"><b>-O</b>
+<i>vpn-adapter-name</i>[=<i>ipv4-address</i>][/<i>cidr-mask</i>][:<i>dhcp-lease-duration</i>]</p>
+
+<p style="margin-left:22%;">Enables a compatible VPN
+adapter to create additional local IPv4 addresses (like
+127.0.0.1) that appear as remote IPv4 addresses to the
+system. This allows product activation using a local
+instance of vlmcsd. This feature is only available in
+Windows and Cygwin builds of vlmcsd since it is not of any
+use on other operating systems. Compatible VPN adapters are
+Tap-windows version 8.2 or higher (from OpenVPN) and the
+TeamViewer VPN adapter. There are two special
+<i>vpn-adapter-name</i>s. A single period (.) instructs
+vlmcsd to use the first available compatible VPN adapter. A
+single dash (-) disables the use of a VPN adapter if one has
+been configured in <b>vlmcsd.ini</b>(5). The
+<i>vpn-adapter-name</i> is <b>not</b> case-sensitive. If the
+<i>vpn-adapter-name</i> contains spaces (e.g. Ethernet 3),
+you must enclose it in quotes.</p>
+
+<p style="margin-left:22%; margin-top: 1em">The default
+<i>ipv4-address</i> is 10.10.10.9 and the default
+<i>cidr-mask</i> is 30. If you are using the default values,
+your VPN adapter uses an IPv4 address of 10.10.10.9 and you
+can set your activation client to use the easy to remember
+address 10.10.10.10 (e.g. slmgr /skms 10.10.10.10 or cscript
+ospp.vbs /sethst:10.10.10.10).</p>
+
+<p style="margin-left:22%; margin-top: 1em">The
+<i>dhcp-lease-duration</i> is a number optionally followed
+by s, m, h, d or w to indicate seconds, minutes, hours, days
+or weeks. The default <i>dhcp-lease-duration</i> is 1d (one
+day). It is normally not required to change this value.</p>
+
+<p style="margin-left:22%; margin-top: 1em">It is advised
+not to manually configure your OpenVPN TAP or TeamViewer VPN
+adapter in &quot;Network Connections&quot;. If you set the
+IPv4 configuration manually anyway, the IPv4 address and the
+subnet mask must match the <b>-O</b> parameter. It is safe
+leave the IPv4 configuration to automatic (DHCP). vlmcsd
+will wait up to four seconds for the DHCP configuration to
+complete before binding to and listenin on any
+interfaces.</p>
+
+<p style="margin-left:22%; margin-top: 1em">You should be
+aware that only one program can use a VPN adapter at a time.
+If you use the TeamViewer VPN adapter for example, you will
+not be able to use the VPN feature of TeamViewer as long as
+vlmcsd is running. The same applies to OpenVPN TAP adapters
+that are in use by other programs (for example OpenVPN,
+QEMU, Ratiborus VM, aiccu, etc.). The best way to avoid
+conflicts is to install Tap-Windows from OpenVPN, cd to
+C:\Program Files\TAP-Windows\bin and run addtap.bat to
+install an additional TAP adapter. Go to &quot;Network
+Connections&quot; and rename the new adapter to
+&quot;vlmcsd&quot; and specify <b>-O vlmcsd</b> to use
+it.</p>
+
+<p style="margin-left:22%; margin-top: 1em">Example: <b>-O
+&quot;Ethernet 7&quot;=192.168.123.1/24</b> (uses VPN
+adapter Ethernet 7 with IPv4 address 192.168.123.1 and have
+192.168.123.2 to 192.168.123.254 as additional local (but
+apparently remote) IPv4 addresses.</p>
+
 <p style="margin-left:11%;"><b>-F0</b> and <b>-F1</b></p>
 
 <p style="margin-left:22%;">Allow (<b>-F1</b>) or disallow

BIN
man/vlmcsd.8.pdf


+ 53 - 1
man/vlmcsd.8.unix.txt

@@ -172,6 +172,58 @@ OPTIONS
               ified before -L.
 
 
+       -O vpn-adapter-name[=ipv4-address][/cidr-mask][:dhcp-lease-duration]
+              Enables a compatible VPN adapter to create additional local IPv4
+              addresses  (like 127.0.0.1) that appear as remote IPv4 addresses
+              to the system. This allows  product  activation  using  a  local
+              instance  of  vlmcsd.  This feature is only available in Windows
+              and Cygwin builds of vlmcsd since it is not of any use on  other
+              operating  systems. Compatible VPN adapters are Tap-windows ver‐
+              sion 8.2  or  higher  (from  OpenVPN)  and  the  TeamViewer  VPN
+              adapter.  There  are  two  special  vpn-adapter-names.  A single
+              period (.) instructs vlmcsd to use the first available  compati‐
+              ble  VPN  adapter.  A  single dash (-) disables the use of a VPN
+              adapter if one has been configured in  vlmcsd.ini(5).  The  vpn-
+              adapter-name is not case-sensitive. If the vpn-adapter-name con‐
+              tains spaces (e.g. Ethernet 3), you must enclose it in quotes.
+
+              The default ipv4-address is 10.10.10.9 and the default cidr-mask
+              is  30.  If  you  are using the default values, your VPN adapter
+              uses an IPv4 address of 10.10.10.9 and you can set your  activa‐
+              tion  client  to  use  the  easy to remember address 10.10.10.10
+              (e.g.   slmgr   /skms   10.10.10.10    or    cscript    ospp.vbs
+              /sethst:10.10.10.10).
+
+              The dhcp-lease-duration is a number optionally followed by s, m,
+              h, d or w to indicate seconds, minutes, hours,  days  or  weeks.
+              The  default dhcp-lease-duration is 1d (one day). It is normally
+              not required to change this value.
+
+              It is advised not to manually  configure  your  OpenVPN  TAP  or
+              TeamViewer  VPN adapter in "Network Connections". If you set the
+              IPv4 configuration manually anyway, the  IPv4  address  and  the
+              subnet  mask  must  match the -O parameter. It is safe leave the
+              IPv4 configuration to automatic (DHCP). vlmcsd will wait  up  to
+              four seconds for the DHCP configuration to complete before bind‐
+              ing to and listenin on any interfaces.
+
+              You should be aware that only one program can use a VPN  adapter
+              at  a  time.  If you use the TeamViewer VPN adapter for example,
+              you will not be able to use the VPN  feature  of  TeamViewer  as
+              long  as  vlmcsd  is  running.  The  same applies to OpenVPN TAP
+              adapters that are in use by other programs (for example OpenVPN,
+              QEMU,  Ratiborus  VM,  aiccu,  etc.). The best way to avoid con‐
+              flicts is to install Tap-Windows from OpenVPN, cd to  C:\Program
+              Files\TAP-Windows\bin  and  run  addtap.bat  to install an addi‐
+              tional TAP adapter. Go to "Network Connections" and  rename  the
+              new adapter to "vlmcsd" and specify -O vlmcsd to use it.
+
+              Example: -O "Ethernet 7"=192.168.123.1/24 (uses VPN adapter Eth‐
+              ernet 7 with IPv4 address 192.168.123.1 and  have  192.168.123.2
+              to  192.168.123.254  as additional local (but apparently remote)
+              IPv4 addresses.
+
+
        -F0 and -F1
               Allow (-F1) or disallow (-F0) binding to IP addresses  that  are
               currently not configured on your system. The default is -F0. -F1
@@ -705,4 +757,4 @@ SEE ALSO
 
 
 
-Hotbird64                        November 2016                       VLMCSD(8)
+Hotbird64                        December 2016                       VLMCSD(8)

+ 14 - 1
man/vlmcsd.ini.5

@@ -1,4 +1,4 @@
-.TH VLMCSD.INI 5 "November 2016" "Hotbird64" "KMS Activation Manual"
+.TH VLMCSD.INI 5 "December 2016" "Hotbird64" "KMS Activation Manual"
 .LO 8
 
 .SH NAME
@@ -66,6 +66,19 @@ Set the level of protection against KMS activations from public IP addresses.
 
 For details on public IP protection levels see \fBvlmcsd\fR(8) command line option \fB-o\fR.
 
+.IP "\fBVPN\fR"
+Has to be in the form \fIvpn-adapter-name\fR[=\fIipv4-address\fR][/\fIcidr-mask\fR][:\fIdhcp-lease-duration\fR].
+
+Enables a compatible VPN adapter to create additional local IPv4 addresses (like 127.0.0.1) that appear as remote IPv4 addresses to the system. This allows product activation using a local instance of vlmcsd. This feature is only available in Windows and Cygwin builds of vlmcsd since it is not of any use on other operating systems. Compatible VPN adapters are Tap-windows version 8.2 or higher (from OpenVPN) and the TeamViewer VPN adapter. There is a special \fIvpn-adapter-name\fR. A single period (.) instructs vlmcsd to use the first available compatible VPN adapter. The \fIvpn-adapter-name\fR is \fBnot\fR case-sensitive. If the \fIvpn-adapter-name\fR contains spaces (e.g. Ethernet 3), do \fBnot\fR enclose it in quotes.
+
+The default \fIipv4-address\fR is 10.10.10.9 and the default \fIcidr-mask\fR is 30. If you are using the default values, your VPN adapter uses an IPv4 address of 10.10.10.9 and you can set your activation client to use the easy to remember address 10.10.10.10 (e.g. slmgr /skms 10.10.10.10 or cscript ospp.vbs /sethst:10.10.10.10).
+
+The \fIdhcp-lease-duration\fR is a number optionally followed by s, m, h, d or w to indicate seconds, minutes, hours, days or weeks. The default \fIdhcp-lease-duration\fR is 1d (one day). It is normally not required to change this value.
+
+It is advised not to manually configure your OpenVPN TAP or TeamViewer VPN adapter in "Network Connections". If you set the IPv4 configuration manually anyway, the IPv4 address and the subnet mask must match the \fBVPN=\fR directive. It is safe leave the IPv4 configuration to automatic (DHCP). vlmcsd will wait up to four seconds for the DHCP configuration to complete before binding to and listenin on any interfaces.
+
+You should be aware that only one program can use a VPN adapter at a time. If you use the TeamViewer VPN adapter for example, you will not be able to use the VPN feature of TeamViewer as long as vlmcsd is running. The same applies to OpenVPN TAP adapters that are in use by other programs (for example OpenVPN, QEMU, Ratiborus VM, aiccu, etc.). The best way to avoid conflicts is to install Tap-Windows from OpenVPN, cd to C:\\Program Files\\TAP-Windows\\bin and run addtap.bat to install an additional TAP adapter. Go to "Network Connections" and rename the new adapter to "vlmcsd" and specify \fBVPN=vlmcsd\fR to use it.
+
 .IP "\fBUseNDR64\fR"
 Can be TRUE or FALSE. Specifies whether you want to use the NDR64 transfer syntax. See options \fB-n0\fR and \fB-n1\fR in \fBvlmcsd\fR(8). The default is TRUE.
 

+ 160 - 112
man/vlmcsd.ini.5.dos.txt

@@ -123,261 +123,309 @@ KEYWORDS
               line option -o.
 
 
+       VPN    Has  to  be  in  the form vpn-adapter-name[=ipv4-address][/cidr-
+              mask][:dhcp-lease-duration].
+
+              Enables a compatible VPN adapter to create additional local IPv4
+              addresses  (like 127.0.0.1) that appear as remote IPv4 addresses
+              to the system. This allows  product  activation  using  a  local
+              instance  of  vlmcsd.  This feature is only available in Windows
+              and Cygwin builds of vlmcsd since it is not of any use on  other
+              operating  systems. Compatible VPN adapters are Tap-windows ver‐
+              sion 8.2  or  higher  (from  OpenVPN)  and  the  TeamViewer  VPN
+              adapter.  There  is  a special vpn-adapter-name. A single period
+              (.) instructs vlmcsd to use the first available  compatible  VPN
+              adapter. The vpn-adapter-name is not case-sensitive. If the vpn-
+              adapter-name contains spaces (e.g. Ethernet 3), do  not  enclose
+              it in quotes.
+
+              The default ipv4-address is 10.10.10.9 and the default cidr-mask
+              is 30. If you are using the default  values,  your  VPN  adapter
+              uses  an IPv4 address of 10.10.10.9 and you can set your activa‐
+              tion client to use the  easy  to  remember  address  10.10.10.10
+              (e.g.    slmgr    /skms    10.10.10.10   or   cscript   ospp.vbs
+              /sethst:10.10.10.10).
+
+              The dhcp-lease-duration is a number optionally followed by s, m,
+              h,  d  or  w to indicate seconds, minutes, hours, days or weeks.
+              The default dhcp-lease-duration is 1d (one day). It is  normally
+              not required to change this value.
+
+              It  is  advised  not  to  manually configure your OpenVPN TAP or
+              TeamViewer VPN adapter in "Network Connections". If you set  the
+              IPv4  configuration  manually  anyway,  the IPv4 address and the
+              subnet mask must match the VPN= directive. It is safe leave  the
+              IPv4  configuration  to automatic (DHCP). vlmcsd will wait up to
+              four seconds for the DHCP configuration to complete before bind‐
+              ing to and listenin on any interfaces.
+
+              You  should be aware that only one program can use a VPN adapter
+              at a time. If you use the TeamViewer VPN  adapter  for  example,
+              you  will  not  be  able to use the VPN feature of TeamViewer as
+              long as vlmcsd is running.  The  same  applies  to  OpenVPN  TAP
+              adapters that are in use by other programs (for example OpenVPN,
+              QEMU, Ratiborus VM, aiccu, etc.). The best  way  to  avoid  con‐
+              flicts  is to install Tap-Windows from OpenVPN, cd to C:\Program
+              Files\TAP-Windows\bin and run addtap.bat  to  install  an  addi‐
+              tional  TAP  adapter. Go to "Network Connections" and rename the
+              new adapter to "vlmcsd" and specify VPN=vlmcsd to use it.
+
+
        UseNDR64
-              Can  be  TRUE  or  FALSE.  Specifies whether you want to use the
+              Can be TRUE or FALSE. Specifies whether  you  want  to  use  the
               NDR64 transfer syntax. See options -n0 and -n1 in vlmcsd(8). The
               default is TRUE.
 
 
        UseBTFN
-              Can  be  TRUE  or  FALSE. Specifies whether you want to use bind
+              Can be TRUE or FALSE. Specifies whether you  want  to  use  bind
               time feature negotiation in RPC. See options -b0 and -b1 in vlm‐
               csd(8). The default is TRUE.
 
 
        RandomizationLevel
-              The  argument must 0, 1 or 2. This specifies the ePID randomiza‐
-              tion level. See options -r0,  -r1  and  -r2  in  vlmcsd(8).  The
-              default  randomization  level is 1. A RandomizationLevel of 2 is
+              The argument must 0, 1 or 2. This specifies the ePID  randomiza‐
+              tion  level.  See  options  -r0,  -r1  and -r2 in vlmcsd(8). The
+              default randomization level is 1. A RandomizationLevel of  2  is
               not recommended and should be treated as a debugging level.
 
 
        LCID   Use a specific culture id (LCID) even if the ePID is randomized.
-              The  argument  must  be  a number between 1 and 32767. While any
+              The argument must be a number between 1  and  32767.  While  any
               number in that range is valid, you should use an offcial LCID. A
-              list  of  assigned  LCIDs  can  be  found  at http://msdn.micro‐
-              soft.com/en-us/goglobal/bb964664.aspx. On the command  line  you
+              list of  assigned  LCIDs  can  be  found  at  http://msdn.micro‐
+              soft.com/en-us/goglobal/bb964664.aspx.  On  the command line you
               control this setting with option -C.
 
 
        MaxWorkers
               The argument specifies the maximum number of worker processes or
-              threads that will be used to serve activation  requests  concur‐
-              rently.  This  is the same as specifying -m on the command line.
-              Minimum is 1. The maximum is platform specific and is  at  least
-              32767  but  is likely to be greater on most systems. The default
+              threads  that  will be used to serve activation requests concur‐
+              rently. This is the same as specifying -m on the  command  line.
+              Minimum  is  1. The maximum is platform specific and is at least
+              32767 but is likely to be greater on most systems.  The  default
               is no limit.
 
 
        ConnectionTimeout
-              Used to control when the vlmcsd  disconnects  idle  TPC  connec‐
+              Used  to  control  when  the vlmcsd disconnects idle TPC connec‐
               tions. The default is 30 seconds. This is the same setting as -t
               on the command line.
 
 
        DisconnectClientsImmediately
-              Set this to TRUE to disconnect a client after it got an  activa‐
-              tion  response  regardless whether a timeout has occured or not.
-              The default is FALSE.  Setting  this  to  TRUE  is  non-standard
-              behavior.  Use only if you are experiencing DoS or DDoS attacks.
-              On the command line you control this behavior  with  options  -d
+              Set  this to TRUE to disconnect a client after it got an activa‐
+              tion response regardless whether a timeout has occured  or  not.
+              The  default  is  FALSE.  Setting  this  to TRUE is non-standard
+              behavior. Use only if you are experiencing DoS or DDoS  attacks.
+              On  the  command  line you control this behavior with options -d
               and -k.
 
 
        PidFile
-              Write  a  pid  file.  The argument is the full pathname of a pid
-              file. The pid  file  contains  is  single  line  containing  the
-              process  id  of  the  vlmcsd  process.  It  can  be used to stop
-              (SIGTERM) or restart (SIGHUP)  vlmcsd.  This  directive  can  be
+              Write a pid file. The argument is the full  pathname  of  a  pid
+              file.  The  pid  file  contains  is  single  line containing the
+              process id of the  vlmcsd  process.  It  can  be  used  to  stop
+              (SIGTERM)  or  restart  (SIGHUP)  vlmcsd.  This directive can be
               overriden using -p on the command line.
 
 
        LogFile
-              Write  a  log  file.  The argument is the full pathname of a log
-              file. On a unixoid OS and with Cygwin you can  use  the  special
-              filename  'syslog'  to  log  to the syslog facility. This is the
+              Write a log file. The argument is the full  pathname  of  a  log
+              file.  On  a  unixoid OS and with Cygwin you can use the special
+              filename 'syslog' to log to the syslog  facility.  This  is  the
               same as specifying -l on the command line.
 
 
        KmsData
-              Use a KMS data file. The argument is the full pathname of a  KMS
-              data  file.  By default vlmcsd only contains the minimum product
-              data that is required to perform all operations  correctly.  You
+              Use  a KMS data file. The argument is the full pathname of a KMS
+              data file. By default vlmcsd only contains the  minimum  product
+              data  that  is required to perform all operations correctly. You
               may use a more complete KMS data file that contains all detailed
-              product names. This is especially useful if you are logging  KMS
+              product  names. This is especially useful if you are logging KMS
               requests. If you don't log, there is no need to load an external
               KMS data file.
 
-              You may use KmsData = - to prevent the default KMS data file  to
+              You  may use KmsData = - to prevent the default KMS data file to
               be loaded.
 
 
        LogDateAndTime
               Can be TRUE or FALSE. The default is TRUE. If set to FALSE, log‐
-              ging output does not include date and time. This  is  useful  if
-              you  log  to  stdout(3)  which  is redirected to another logging
+              ging  output  does  not include date and time. This is useful if
+              you log to stdout(3) which  is  redirected  to  another  logging
               mechanism that already includes date and time in its output, for
-              instance  systemd-journald(8). If you log to syslog(3), LogDate‐
-              AndTime is ignored and date and time will never be  included  in
+              instance systemd-journald(8). If you log to syslog(3),  LogDate‐
+              AndTime  is  ignored and date and time will never be included in
               the output sent to syslog(3). Using the command line you control
               this setting with options -T0 and -T1.
 
 
        LogVerbose
-              Set this to either TRUE or FALSE. The default is FALSE.  If  set
+              Set  this  to either TRUE or FALSE. The default is FALSE. If set
               to TRUE, more details of each activation will be logged. You use
-              -v and -q in the command line to control this  setting.  LogVer‐
-              bose  has  an  effect only if you specify a log file or redirect
+              -v  and  -q in the command line to control this setting. LogVer‐
+              bose has an effect only if you specify a log  file  or  redirect
               logging to stdout(3).
 
 
        WhitelistingLevel
-              Can be 0, 1, 2 or 3. The default is  0.  Sets  the  whitelisting
+              Can  be  0,  1,  2 or 3. The default is 0. Sets the whitelisting
               level to determine which products vlmcsd activates or refuses.
 
                    0:  activate  all  products  with  an  unknown,  retail  or
                    beta/preview KMS ID.
-                   1: activate products with a retail or beta/preview  KMS  ID
+                   1:  activate  products with a retail or beta/preview KMS ID
                    but refuse to activate products with an unknown KMS ID.
-                   2:  activate  products  with  an  unknown KMS ID but refuse
+                   2: activate products with an  unknown  KMS  ID  but  refuse
                    products with a retail or beta/preview KMS ID.
-                   3: activate only products with a known volume  license  RTM
+                   3:  activate  only products with a known volume license RTM
                    KMS ID and refuse all others.
 
 
-              The  SKU  ID  is  not  checked. Like a genuine KMS server vlmcsd
-              activates a product that has a random or unknown SKU ID. If  you
-              select  1  or  3, vlmcsd also checks the Application ID for cor‐
-              rectness. If Microsoft introduces a new KMS ID for a  new  prod‐
-              uct,  you cannot activate it if you used 1 or 3 until a new ver‐
+              The SKU ID is not checked. Like  a  genuine  KMS  server  vlmcsd
+              activates  a product that has a random or unknown SKU ID. If you
+              select 1 or 3, vlmcsd also checks the Application  ID  for  cor‐
+              rectness.  If  Microsoft introduces a new KMS ID for a new prod‐
+              uct, you cannot activate it if you used 1 or 3 until a new  ver‐
               sion of vlmcsd is available.
 
 
        CheckClientTime
-              Can be TRUE or FALSE. The default is FALSE. If you set  this  to
-              TRUE  vlmcsd(8)  checks  if the client time differs no more than
-              four hours from the system time. This is useful to prevent  emu‐
+              Can  be  TRUE or FALSE. The default is FALSE. If you set this to
+              TRUE vlmcsd(8) checks if the client time differs  no  more  than
+              four  hours from the system time. This is useful to prevent emu‐
               lator detection. A client that tries to detect an emulator could
-              simply send two subsequent request with  two  time  stamps  that
-              differ  more  than  four hours from each other. If both requests
+              simply  send  two  subsequent  request with two time stamps that
+              differ more than four hours from each other.  If  both  requests
               succeed, the server is an emulator. If you set this to TRUE on a
-              system  with  no reliable time source, activations will fail. It
-              is ok to set the correct system  time  after  you  started  vlm‐
+              system with no reliable time source, activations will  fail.  It
+              is  ok  to  set  the  correct system time after you started vlm‐
               csd(8).
 
 
        MaintainClients
-              Can  be TRUE or FALSE (the default). Disables (FALSE) or enables
+              Can be TRUE or FALSE (the default). Disables (FALSE) or  enables
               (TRUE) maintaining a list of client machine IDs (CMIDs). TRUE is
-              useful  to prevent emulator detection. By maintaing a CMID list,
-              vlmcsd(8) reports current active clients exactly like a  genuine
+              useful to prevent emulator detection. By maintaing a CMID  list,
+              vlmcsd(8)  reports current active clients exactly like a genuine
               KMS emulator. This includes bug compatibility to the extent that
-              you can permanently kill a genuine KMS emulator  by  sending  an
+              you  can  permanently  kill a genuine KMS emulator by sending an
               "overcharge request" with a required client count of 376 or more
-              and then request activation for 671 clients.  vlmcsd(8)  can  be
-              reset  from  this  condition by restarting it. If FALSE is used,
+              and  then  request  activation for 671 clients. vlmcsd(8) can be
+              reset from this condition by restarting it. If  FALSE  is  used,
               vlmcsd(8) reports current active clients as good as possible. If
-              no  client  sends an "overcharge request", it is not possible to
-              detect vlmcsd(8) as an emulator with  MaintainClients  =  FALSE.
-              Maintaining  clients requires the allocation of a buffer that is
-              about 50 kB in size. On hardware with few memory  resources  use
+              no client sends an "overcharge request", it is not  possible  to
+              detect  vlmcsd(8)  as  an emulator with MaintainClients = FALSE.
+              Maintaining clients requires the allocation of a buffer that  is
+              about  50  kB in size. On hardware with few memory resources use
               it only if you really need it.
 
-              If  you  start vlmcsd(8) from an internet superserver, this set‐
-              ting cannot be used. Since vlmcsd(8) exits  after  each  activa‐
+              If you start vlmcsd(8) from an internet superserver,  this  set‐
+              ting  cannot  be  used. Since vlmcsd(8) exits after each activa‐
               tion, it cannot maintain any state in memory.
 
 
        StartEmpty
-              This  setting  is  ignored  if you do not also specify Maintain‐
-              Clients = TRUE. If you specify FALSE  (the  default),  vlmcsd(8)
-              starts  up  as  a  fully  "charged" KMS server. Clients activate
-              immediately. StartEmpty = TRUE lets you start up vlmcsd(8)  with
+              This setting is ignored if you do  not  also  specify  Maintain‐
+              Clients  =  TRUE.  If you specify FALSE (the default), vlmcsd(8)
+              starts up as a fully  "charged"  KMS  server.  Clients  activate
+              immediately.  StartEmpty = TRUE lets you start up vlmcsd(8) with
               an empty CMID list. Activation will start when the required min‐
-              imum clients (25 for Windows Client OSses, 5 for Windows  Server
-              OSses  and  Office) have registered with the KMS server. As long
+              imum  clients (25 for Windows Client OSses, 5 for Windows Server
+              OSses and Office) have registered with the KMS server.  As  long
               as the minimum client count has not been reached, clients end up
               in HRESULT 0xC004F038 "The count reported by your Key Management
               Service (KMS) is insufficient. Please contact your system admin‐
-              istrator".  You  may use vlmcs(1) or another KMS client emulator
-              to "charge" vlmcsd(8). Setting this parameter to TRUE  does  not
-              improve  emulator  detection prevention. It's primary purpose is
-              to help developers of KMS  clients  to  test  "charging"  a  KMS
+              istrator". You may use vlmcs(1) or another KMS  client  emulator
+              to  "charge"  vlmcsd(8). Setting this parameter to TRUE does not
+              improve emulator detection prevention. It's primary  purpose  is
+              to  help  developers  of  KMS  clients  to test "charging" a KMS
               server.
 
 
        ActivationInterval
-              This  is the same as specifying -A on the command line. See vlm‐
+              This is the same as specifying -A on the command line. See  vlm‐
               csd(8) for details. The default is 2 hours. Example: Activation‐
               Interval = 1h
 
 
        RenewalInterval
-              This  is the same as specifying -R on the command line. See vlm‐
-              csd(8) for details. The default is 7 days.  Example:  RenewalIn‐
+              This is the same as specifying -R on the command line. See  vlm‐
+              csd(8)  for  details. The default is 7 days. Example: RenewalIn‐
               terval = 3d. Please note that the KMS client decides itself when
               to renew activation. Even though vlmcsd sends the renewal inter‐
-              val  you specify, it is no more than some kind of recommendation
-              to the client. Older KMS clients did follow  the  recommendation
+              val you specify, it is no more than some kind of  recommendation
+              to  the  client. Older KMS clients did follow the recommendation
               from a KMS server or emulator. Newer clients do not.
 
 
-       User   Run  vlmcsd  as  another, preferrably less privileged, user. The
-              argument can be a user name or a numeric user id. You must  have
-              the  required  privileges  (capabilities on Linux) to change the
-              security context of a process without providing any  credentials
-              (a  password in most cases). On most unixoid OSses 'root' is the
+       User   Run vlmcsd as another, preferrably less  privileged,  user.  The
+              argument  can be a user name or a numeric user id. You must have
+              the required privileges (capabilities on Linux)  to  change  the
+              security  context of a process without providing any credentials
+              (a password in most cases). On most unixoid OSses 'root' is  the
               only user who has these privileges in the default configuration.
-              This  setting  is not available in the native Windows version of
-              vlmcsd. See -u in vlmcsd(8). This setting cannot be  changed  on
+              This setting is not available in the native Windows  version  of
+              vlmcsd.  See  -u in vlmcsd(8). This setting cannot be changed on
               the fly by sending SIGHUP to vlmcsd.
 
 
-       Group  Run  vlmcsd  as another, preferrably less privileged, group. The
-              argument can be a group name or a numeric  group  id.  You  must
-              have  the  required privileges (capabilities on Linux) to change
-              the security context of a process without providing any  creden‐
-              tials  (a  password in most cases). On most unixoid OSses 'root'
+       Group  Run vlmcsd as another, preferrably less privileged,  group.  The
+              argument  can  be  a  group name or a numeric group id. You must
+              have the required privileges (capabilities on Linux)  to  change
+              the  security context of a process without providing any creden‐
+              tials (a password in most cases). On most unixoid  OSses  'root'
               is the only user who has these privileges in the default config‐
-              uration.  This  setting  is  not available in the native Windows
-              version of vlmcsd. See -g in vlmcsd(8). This setting  cannot  be
+              uration. This setting is not available  in  the  native  Windows
+              version  of  vlmcsd. See -g in vlmcsd(8). This setting cannot be
               changed on the fly by sending SIGHUP to vlmcsd.
 
 
        Windows
-              The  argument  has the form ePID [ / HwId ]. Always use ePID and
-              HwId for Windows activations. If  specified,  RandomizationLevel
+              The argument has the form ePID [ / HwId ]. Always use  ePID  and
+              HwId  for  Windows activations. If specified, RandomizationLevel
               for Windows activitations will be ignored.
 
 
        Office2010
-              The  argument  has the form ePID [ / HwId ]. Always use ePID and
-              HwId for Office 2010 activations. If  specified,  Randomization‐
+              The argument has the form ePID [ / HwId ]. Always use  ePID  and
+              HwId  for  Office 2010 activations. If specified, Randomization‐
               Level for Office 2010 activitations will be ignored.
 
 
        Office2013
-              The  argument  has the form ePID [ / HwId ]. Always use ePID and
-              HwId for Office 2013 activations. If  specified,  Randomization‐
+              The argument has the form ePID [ / HwId ]. Always use  ePID  and
+              HwId  for  Office 2013 activations. If specified, Randomization‐
               Level for Office 2013 activitations will be ignored.
 
 
        Office2016
-              The  argument  has the form ePID [ / HwId ]. Always use ePID and
-              HwId for Office 2016 activations. If  specified,  Randomization‐
+              The argument has the form ePID [ / HwId ]. Always use  ePID  and
+              HwId  for  Office 2016 activations. If specified, Randomization‐
               Level for Office 2016 activitations will be ignored.
 
 
 VALID EPIDS
-       The  ePID is currently a comment only. You can specify any string up to
-       63 bytes. In Windows 7 Microsoft has blacklisted few (  <  10  )  ePIDs
-       that  were  used  in KMSv5 versions of the "Ratiborus Virtual Machine".
-       Microsoft has given up on blacklisting when KMS emulators  appeared  in
+       The ePID is currently a comment only. You can specify any string up  to
+       63  bytes.  In  Windows  7 Microsoft has blacklisted few ( < 10 ) ePIDs
+       that were used in KMSv5 versions of the  "Ratiborus  Virtual  Machine".
+       Microsoft  has  given up on blacklisting when KMS emulators appeared in
        the wild.
 
        Even if you can use "Activated by cool hacker guys" as an ePID, you may
        wish to use ePIDs that cannot be detected as non-MS ePIDs. If you don't
-       know  how  these  "valid"  ePIDs look like exactly, do not use GUIDS in
-       vlmcsd.ini. vlmcsd  provides  internal  mechanisms  to  generate  valid
+       know how these "valid" ePIDs look like exactly, do  not  use  GUIDS  in
+       vlmcsd.ini.  vlmcsd  provides  internal  mechanisms  to  generate valid
        ePIDs.
 
        If you use non-ASCII characters in your ePID (you shouldn't do anyway),
-       these must be in UTF-8 format. This is especially  important  when  you
+       these  must  be  in UTF-8 format. This is especially important when you
        run vlmcsd on Windows or cygwin because UTF-8 is not the default encod‐
        ing for most editors.
 
        If you are specifying an optional HWID it follows the same syntax as in
-       the  -H  option in vlmcsd(8) ecxept that you must not enclose a HWID in
+       the -H option in vlmcsd(8) ecxept that you must not enclose a  HWID  in
        quotes even if it contains spaces.
 
 
@@ -391,7 +439,7 @@ AUTHOR
 
 
 CREDITS
-       Thanks  to  CODYQX4,  deagles,  eIcn, mikmik38, nosferati87, qad, Rati‐
+       Thanks to CODYQX4, deagles, eIcn,  mikmik38,  nosferati87,  qad,  Rati‐
        borus, ...
 
 
@@ -400,4 +448,4 @@ SEE ALSO
 
 
 
-Hotbird64                        November 2016                   VLMCSD.INI(5)
+Hotbird64                        December 2016                   VLMCSD.INI(5)

+ 70 - 1
man/vlmcsd.ini.5.html

@@ -1,5 +1,5 @@
 <!-- Creator     : groff version 1.22.3 -->
-<!-- CreationDate: Mon Nov 28 01:28:23 2016 -->
+<!-- CreationDate: Mon Dec  5 18:18:46 2016 -->
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
 <html>
@@ -227,6 +227,75 @@ without activating <br>
 public IP protection levels see <b>vlmcsd</b>(8) command
 line option <b>-o</b>.</p>
 
+<table width="100%" border="0" rules="none" frame="void"
+       cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="11%"></td>
+<td width="4%">
+
+
+<p><b>VPN</b></p></td>
+<td width="7%"></td>
+<td width="78%">
+
+
+<p>Has to be in the form
+<i>vpn-adapter-name</i>[=<i>ipv4-address</i>][/<i>cidr-mask</i>][:<i>dhcp-lease-duration</i>].</p> </td></tr>
+</table>
+
+<p style="margin-left:22%; margin-top: 1em">Enables a
+compatible VPN adapter to create additional local IPv4
+addresses (like 127.0.0.1) that appear as remote IPv4
+addresses to the system. This allows product activation
+using a local instance of vlmcsd. This feature is only
+available in Windows and Cygwin builds of vlmcsd since it is
+not of any use on other operating systems. Compatible VPN
+adapters are Tap-windows version 8.2 or higher (from
+OpenVPN) and the TeamViewer VPN adapter. There is a special
+<i>vpn-adapter-name</i>. A single period (.) instructs
+vlmcsd to use the first available compatible VPN adapter.
+The <i>vpn-adapter-name</i> is <b>not</b> case-sensitive. If
+the <i>vpn-adapter-name</i> contains spaces (e.g. Ethernet
+3), do <b>not</b> enclose it in quotes.</p>
+
+<p style="margin-left:22%; margin-top: 1em">The default
+<i>ipv4-address</i> is 10.10.10.9 and the default
+<i>cidr-mask</i> is 30. If you are using the default values,
+your VPN adapter uses an IPv4 address of 10.10.10.9 and you
+can set your activation client to use the easy to remember
+address 10.10.10.10 (e.g. slmgr /skms 10.10.10.10 or cscript
+ospp.vbs /sethst:10.10.10.10).</p>
+
+<p style="margin-left:22%; margin-top: 1em">The
+<i>dhcp-lease-duration</i> is a number optionally followed
+by s, m, h, d or w to indicate seconds, minutes, hours, days
+or weeks. The default <i>dhcp-lease-duration</i> is 1d (one
+day). It is normally not required to change this value.</p>
+
+<p style="margin-left:22%; margin-top: 1em">It is advised
+not to manually configure your OpenVPN TAP or TeamViewer VPN
+adapter in &quot;Network Connections&quot;. If you set the
+IPv4 configuration manually anyway, the IPv4 address and the
+subnet mask must match the <b>VPN=</b> directive. It is safe
+leave the IPv4 configuration to automatic (DHCP). vlmcsd
+will wait up to four seconds for the DHCP configuration to
+complete before binding to and listenin on any
+interfaces.</p>
+
+<p style="margin-left:22%; margin-top: 1em">You should be
+aware that only one program can use a VPN adapter at a time.
+If you use the TeamViewer VPN adapter for example, you will
+not be able to use the VPN feature of TeamViewer as long as
+vlmcsd is running. The same applies to OpenVPN TAP adapters
+that are in use by other programs (for example OpenVPN,
+QEMU, Ratiborus VM, aiccu, etc.). The best way to avoid
+conflicts is to install Tap-Windows from OpenVPN, cd to
+C:\Program Files\TAP-Windows\bin and run addtap.bat to
+install an additional TAP adapter. Go to &quot;Network
+Connections&quot; and rename the new adapter to
+&quot;vlmcsd&quot; and specify <b>VPN=vlmcsd</b> to use
+it.</p>
+
 <p style="margin-left:11%;"><b>UseNDR64</b></p>
 
 <p style="margin-left:22%;">Can be TRUE or FALSE. Specifies

BIN
man/vlmcsd.ini.5.pdf


+ 160 - 112
man/vlmcsd.ini.5.unix.txt

@@ -123,261 +123,309 @@ KEYWORDS
               line option -o.
 
 
+       VPN    Has  to  be  in  the form vpn-adapter-name[=ipv4-address][/cidr-
+              mask][:dhcp-lease-duration].
+
+              Enables a compatible VPN adapter to create additional local IPv4
+              addresses  (like 127.0.0.1) that appear as remote IPv4 addresses
+              to the system. This allows  product  activation  using  a  local
+              instance  of  vlmcsd.  This feature is only available in Windows
+              and Cygwin builds of vlmcsd since it is not of any use on  other
+              operating  systems. Compatible VPN adapters are Tap-windows ver‐
+              sion 8.2  or  higher  (from  OpenVPN)  and  the  TeamViewer  VPN
+              adapter.  There  is  a special vpn-adapter-name. A single period
+              (.) instructs vlmcsd to use the first available  compatible  VPN
+              adapter. The vpn-adapter-name is not case-sensitive. If the vpn-
+              adapter-name contains spaces (e.g. Ethernet 3), do  not  enclose
+              it in quotes.
+
+              The default ipv4-address is 10.10.10.9 and the default cidr-mask
+              is 30. If you are using the default  values,  your  VPN  adapter
+              uses  an IPv4 address of 10.10.10.9 and you can set your activa‐
+              tion client to use the  easy  to  remember  address  10.10.10.10
+              (e.g.    slmgr    /skms    10.10.10.10   or   cscript   ospp.vbs
+              /sethst:10.10.10.10).
+
+              The dhcp-lease-duration is a number optionally followed by s, m,
+              h,  d  or  w to indicate seconds, minutes, hours, days or weeks.
+              The default dhcp-lease-duration is 1d (one day). It is  normally
+              not required to change this value.
+
+              It  is  advised  not  to  manually configure your OpenVPN TAP or
+              TeamViewer VPN adapter in "Network Connections". If you set  the
+              IPv4  configuration  manually  anyway,  the IPv4 address and the
+              subnet mask must match the VPN= directive. It is safe leave  the
+              IPv4  configuration  to automatic (DHCP). vlmcsd will wait up to
+              four seconds for the DHCP configuration to complete before bind‐
+              ing to and listenin on any interfaces.
+
+              You  should be aware that only one program can use a VPN adapter
+              at a time. If you use the TeamViewer VPN  adapter  for  example,
+              you  will  not  be  able to use the VPN feature of TeamViewer as
+              long as vlmcsd is running.  The  same  applies  to  OpenVPN  TAP
+              adapters that are in use by other programs (for example OpenVPN,
+              QEMU, Ratiborus VM, aiccu, etc.). The best  way  to  avoid  con‐
+              flicts  is to install Tap-Windows from OpenVPN, cd to C:\Program
+              Files\TAP-Windows\bin and run addtap.bat  to  install  an  addi‐
+              tional  TAP  adapter. Go to "Network Connections" and rename the
+              new adapter to "vlmcsd" and specify VPN=vlmcsd to use it.
+
+
        UseNDR64
-              Can  be  TRUE  or  FALSE.  Specifies whether you want to use the
+              Can be TRUE or FALSE. Specifies whether  you  want  to  use  the
               NDR64 transfer syntax. See options -n0 and -n1 in vlmcsd(8). The
               default is TRUE.
 
 
        UseBTFN
-              Can  be  TRUE  or  FALSE. Specifies whether you want to use bind
+              Can be TRUE or FALSE. Specifies whether you  want  to  use  bind
               time feature negotiation in RPC. See options -b0 and -b1 in vlm‐
               csd(8). The default is TRUE.
 
 
        RandomizationLevel
-              The  argument must 0, 1 or 2. This specifies the ePID randomiza‐
-              tion level. See options -r0,  -r1  and  -r2  in  vlmcsd(8).  The
-              default  randomization  level is 1. A RandomizationLevel of 2 is
+              The argument must 0, 1 or 2. This specifies the ePID  randomiza‐
+              tion  level.  See  options  -r0,  -r1  and -r2 in vlmcsd(8). The
+              default randomization level is 1. A RandomizationLevel of  2  is
               not recommended and should be treated as a debugging level.
 
 
        LCID   Use a specific culture id (LCID) even if the ePID is randomized.
-              The  argument  must  be  a number between 1 and 32767. While any
+              The argument must be a number between 1  and  32767.  While  any
               number in that range is valid, you should use an offcial LCID. A
-              list  of  assigned  LCIDs  can  be  found  at http://msdn.micro‐
-              soft.com/en-us/goglobal/bb964664.aspx. On the command  line  you
+              list of  assigned  LCIDs  can  be  found  at  http://msdn.micro‐
+              soft.com/en-us/goglobal/bb964664.aspx.  On  the command line you
               control this setting with option -C.
 
 
        MaxWorkers
               The argument specifies the maximum number of worker processes or
-              threads that will be used to serve activation  requests  concur‐
-              rently.  This  is the same as specifying -m on the command line.
-              Minimum is 1. The maximum is platform specific and is  at  least
-              32767  but  is likely to be greater on most systems. The default
+              threads  that  will be used to serve activation requests concur‐
+              rently. This is the same as specifying -m on the  command  line.
+              Minimum  is  1. The maximum is platform specific and is at least
+              32767 but is likely to be greater on most systems.  The  default
               is no limit.
 
 
        ConnectionTimeout
-              Used to control when the vlmcsd  disconnects  idle  TPC  connec‐
+              Used  to  control  when  the vlmcsd disconnects idle TPC connec‐
               tions. The default is 30 seconds. This is the same setting as -t
               on the command line.
 
 
        DisconnectClientsImmediately
-              Set this to TRUE to disconnect a client after it got an  activa‐
-              tion  response  regardless whether a timeout has occured or not.
-              The default is FALSE.  Setting  this  to  TRUE  is  non-standard
-              behavior.  Use only if you are experiencing DoS or DDoS attacks.
-              On the command line you control this behavior  with  options  -d
+              Set  this to TRUE to disconnect a client after it got an activa‐
+              tion response regardless whether a timeout has occured  or  not.
+              The  default  is  FALSE.  Setting  this  to TRUE is non-standard
+              behavior. Use only if you are experiencing DoS or DDoS  attacks.
+              On  the  command  line you control this behavior with options -d
               and -k.
 
 
        PidFile
-              Write  a  pid  file.  The argument is the full pathname of a pid
-              file. The pid  file  contains  is  single  line  containing  the
-              process  id  of  the  vlmcsd  process.  It  can  be used to stop
-              (SIGTERM) or restart (SIGHUP)  vlmcsd.  This  directive  can  be
+              Write a pid file. The argument is the full  pathname  of  a  pid
+              file.  The  pid  file  contains  is  single  line containing the
+              process id of the  vlmcsd  process.  It  can  be  used  to  stop
+              (SIGTERM)  or  restart  (SIGHUP)  vlmcsd.  This directive can be
               overriden using -p on the command line.
 
 
        LogFile
-              Write  a  log  file.  The argument is the full pathname of a log
-              file. On a unixoid OS and with Cygwin you can  use  the  special
-              filename  'syslog'  to  log  to the syslog facility. This is the
+              Write a log file. The argument is the full  pathname  of  a  log
+              file.  On  a  unixoid OS and with Cygwin you can use the special
+              filename 'syslog' to log to the syslog  facility.  This  is  the
               same as specifying -l on the command line.
 
 
        KmsData
-              Use a KMS data file. The argument is the full pathname of a  KMS
-              data  file.  By default vlmcsd only contains the minimum product
-              data that is required to perform all operations  correctly.  You
+              Use  a KMS data file. The argument is the full pathname of a KMS
+              data file. By default vlmcsd only contains the  minimum  product
+              data  that  is required to perform all operations correctly. You
               may use a more complete KMS data file that contains all detailed
-              product names. This is especially useful if you are logging  KMS
+              product  names. This is especially useful if you are logging KMS
               requests. If you don't log, there is no need to load an external
               KMS data file.
 
-              You may use KmsData = - to prevent the default KMS data file  to
+              You  may use KmsData = - to prevent the default KMS data file to
               be loaded.
 
 
        LogDateAndTime
               Can be TRUE or FALSE. The default is TRUE. If set to FALSE, log‐
-              ging output does not include date and time. This  is  useful  if
-              you  log  to  stdout(3)  which  is redirected to another logging
+              ging  output  does  not include date and time. This is useful if
+              you log to stdout(3) which  is  redirected  to  another  logging
               mechanism that already includes date and time in its output, for
-              instance  systemd-journald(8). If you log to syslog(3), LogDate‐
-              AndTime is ignored and date and time will never be  included  in
+              instance systemd-journald(8). If you log to syslog(3),  LogDate‐
+              AndTime  is  ignored and date and time will never be included in
               the output sent to syslog(3). Using the command line you control
               this setting with options -T0 and -T1.
 
 
        LogVerbose
-              Set this to either TRUE or FALSE. The default is FALSE.  If  set
+              Set  this  to either TRUE or FALSE. The default is FALSE. If set
               to TRUE, more details of each activation will be logged. You use
-              -v and -q in the command line to control this  setting.  LogVer‐
-              bose  has  an  effect only if you specify a log file or redirect
+              -v  and  -q in the command line to control this setting. LogVer‐
+              bose has an effect only if you specify a log  file  or  redirect
               logging to stdout(3).
 
 
        WhitelistingLevel
-              Can be 0, 1, 2 or 3. The default is  0.  Sets  the  whitelisting
+              Can  be  0,  1,  2 or 3. The default is 0. Sets the whitelisting
               level to determine which products vlmcsd activates or refuses.
 
                    0:  activate  all  products  with  an  unknown,  retail  or
                    beta/preview KMS ID.
-                   1: activate products with a retail or beta/preview  KMS  ID
+                   1:  activate  products with a retail or beta/preview KMS ID
                    but refuse to activate products with an unknown KMS ID.
-                   2:  activate  products  with  an  unknown KMS ID but refuse
+                   2: activate products with an  unknown  KMS  ID  but  refuse
                    products with a retail or beta/preview KMS ID.
-                   3: activate only products with a known volume  license  RTM
+                   3:  activate  only products with a known volume license RTM
                    KMS ID and refuse all others.
 
 
-              The  SKU  ID  is  not  checked. Like a genuine KMS server vlmcsd
-              activates a product that has a random or unknown SKU ID. If  you
-              select  1  or  3, vlmcsd also checks the Application ID for cor‐
-              rectness. If Microsoft introduces a new KMS ID for a  new  prod‐
-              uct,  you cannot activate it if you used 1 or 3 until a new ver‐
+              The SKU ID is not checked. Like  a  genuine  KMS  server  vlmcsd
+              activates  a product that has a random or unknown SKU ID. If you
+              select 1 or 3, vlmcsd also checks the Application  ID  for  cor‐
+              rectness.  If  Microsoft introduces a new KMS ID for a new prod‐
+              uct, you cannot activate it if you used 1 or 3 until a new  ver‐
               sion of vlmcsd is available.
 
 
        CheckClientTime
-              Can be TRUE or FALSE. The default is FALSE. If you set  this  to
-              TRUE  vlmcsd(8)  checks  if the client time differs no more than
-              four hours from the system time. This is useful to prevent  emu‐
+              Can  be  TRUE or FALSE. The default is FALSE. If you set this to
+              TRUE vlmcsd(8) checks if the client time differs  no  more  than
+              four  hours from the system time. This is useful to prevent emu‐
               lator detection. A client that tries to detect an emulator could
-              simply send two subsequent request with  two  time  stamps  that
-              differ  more  than  four hours from each other. If both requests
+              simply  send  two  subsequent  request with two time stamps that
+              differ more than four hours from each other.  If  both  requests
               succeed, the server is an emulator. If you set this to TRUE on a
-              system  with  no reliable time source, activations will fail. It
-              is ok to set the correct system  time  after  you  started  vlm‐
+              system with no reliable time source, activations will  fail.  It
+              is  ok  to  set  the  correct system time after you started vlm‐
               csd(8).
 
 
        MaintainClients
-              Can  be TRUE or FALSE (the default). Disables (FALSE) or enables
+              Can be TRUE or FALSE (the default). Disables (FALSE) or  enables
               (TRUE) maintaining a list of client machine IDs (CMIDs). TRUE is
-              useful  to prevent emulator detection. By maintaing a CMID list,
-              vlmcsd(8) reports current active clients exactly like a  genuine
+              useful to prevent emulator detection. By maintaing a CMID  list,
+              vlmcsd(8)  reports current active clients exactly like a genuine
               KMS emulator. This includes bug compatibility to the extent that
-              you can permanently kill a genuine KMS emulator  by  sending  an
+              you  can  permanently  kill a genuine KMS emulator by sending an
               "overcharge request" with a required client count of 376 or more
-              and then request activation for 671 clients.  vlmcsd(8)  can  be
-              reset  from  this  condition by restarting it. If FALSE is used,
+              and  then  request  activation for 671 clients. vlmcsd(8) can be
+              reset from this condition by restarting it. If  FALSE  is  used,
               vlmcsd(8) reports current active clients as good as possible. If
-              no  client  sends an "overcharge request", it is not possible to
-              detect vlmcsd(8) as an emulator with  MaintainClients  =  FALSE.
-              Maintaining  clients requires the allocation of a buffer that is
-              about 50 kB in size. On hardware with few memory  resources  use
+              no client sends an "overcharge request", it is not  possible  to
+              detect  vlmcsd(8)  as  an emulator with MaintainClients = FALSE.
+              Maintaining clients requires the allocation of a buffer that  is
+              about  50  kB in size. On hardware with few memory resources use
               it only if you really need it.
 
-              If  you  start vlmcsd(8) from an internet superserver, this set‐
-              ting cannot be used. Since vlmcsd(8) exits  after  each  activa‐
+              If you start vlmcsd(8) from an internet superserver,  this  set‐
+              ting  cannot  be  used. Since vlmcsd(8) exits after each activa‐
               tion, it cannot maintain any state in memory.
 
 
        StartEmpty
-              This  setting  is  ignored  if you do not also specify Maintain‐
-              Clients = TRUE. If you specify FALSE  (the  default),  vlmcsd(8)
-              starts  up  as  a  fully  "charged" KMS server. Clients activate
-              immediately. StartEmpty = TRUE lets you start up vlmcsd(8)  with
+              This setting is ignored if you do  not  also  specify  Maintain‐
+              Clients  =  TRUE.  If you specify FALSE (the default), vlmcsd(8)
+              starts up as a fully  "charged"  KMS  server.  Clients  activate
+              immediately.  StartEmpty = TRUE lets you start up vlmcsd(8) with
               an empty CMID list. Activation will start when the required min‐
-              imum clients (25 for Windows Client OSses, 5 for Windows  Server
-              OSses  and  Office) have registered with the KMS server. As long
+              imum  clients (25 for Windows Client OSses, 5 for Windows Server
+              OSses and Office) have registered with the KMS server.  As  long
               as the minimum client count has not been reached, clients end up
               in HRESULT 0xC004F038 "The count reported by your Key Management
               Service (KMS) is insufficient. Please contact your system admin‐
-              istrator".  You  may use vlmcs(1) or another KMS client emulator
-              to "charge" vlmcsd(8). Setting this parameter to TRUE  does  not
-              improve  emulator  detection prevention. It's primary purpose is
-              to help developers of KMS  clients  to  test  "charging"  a  KMS
+              istrator". You may use vlmcs(1) or another KMS  client  emulator
+              to  "charge"  vlmcsd(8). Setting this parameter to TRUE does not
+              improve emulator detection prevention. It's primary  purpose  is
+              to  help  developers  of  KMS  clients  to test "charging" a KMS
               server.
 
 
        ActivationInterval
-              This  is the same as specifying -A on the command line. See vlm‐
+              This is the same as specifying -A on the command line. See  vlm‐
               csd(8) for details. The default is 2 hours. Example: Activation‐
               Interval = 1h
 
 
        RenewalInterval
-              This  is the same as specifying -R on the command line. See vlm‐
-              csd(8) for details. The default is 7 days.  Example:  RenewalIn‐
+              This is the same as specifying -R on the command line. See  vlm‐
+              csd(8)  for  details. The default is 7 days. Example: RenewalIn‐
               terval = 3d. Please note that the KMS client decides itself when
               to renew activation. Even though vlmcsd sends the renewal inter‐
-              val  you specify, it is no more than some kind of recommendation
-              to the client. Older KMS clients did follow  the  recommendation
+              val you specify, it is no more than some kind of  recommendation
+              to  the  client. Older KMS clients did follow the recommendation
               from a KMS server or emulator. Newer clients do not.
 
 
-       User   Run  vlmcsd  as  another, preferrably less privileged, user. The
-              argument can be a user name or a numeric user id. You must  have
-              the  required  privileges  (capabilities on Linux) to change the
-              security context of a process without providing any  credentials
-              (a  password in most cases). On most unixoid OSses 'root' is the
+       User   Run vlmcsd as another, preferrably less  privileged,  user.  The
+              argument  can be a user name or a numeric user id. You must have
+              the required privileges (capabilities on Linux)  to  change  the
+              security  context of a process without providing any credentials
+              (a password in most cases). On most unixoid OSses 'root' is  the
               only user who has these privileges in the default configuration.
-              This  setting  is not available in the native Windows version of
-              vlmcsd. See -u in vlmcsd(8). This setting cannot be  changed  on
+              This setting is not available in the native Windows  version  of
+              vlmcsd.  See  -u in vlmcsd(8). This setting cannot be changed on
               the fly by sending SIGHUP to vlmcsd.
 
 
-       Group  Run  vlmcsd  as another, preferrably less privileged, group. The
-              argument can be a group name or a numeric  group  id.  You  must
-              have  the  required privileges (capabilities on Linux) to change
-              the security context of a process without providing any  creden‐
-              tials  (a  password in most cases). On most unixoid OSses 'root'
+       Group  Run vlmcsd as another, preferrably less privileged,  group.  The
+              argument  can  be  a  group name or a numeric group id. You must
+              have the required privileges (capabilities on Linux)  to  change
+              the  security context of a process without providing any creden‐
+              tials (a password in most cases). On most unixoid  OSses  'root'
               is the only user who has these privileges in the default config‐
-              uration.  This  setting  is  not available in the native Windows
-              version of vlmcsd. See -g in vlmcsd(8). This setting  cannot  be
+              uration. This setting is not available  in  the  native  Windows
+              version  of  vlmcsd. See -g in vlmcsd(8). This setting cannot be
               changed on the fly by sending SIGHUP to vlmcsd.
 
 
        Windows
-              The  argument  has the form ePID [ / HwId ]. Always use ePID and
-              HwId for Windows activations. If  specified,  RandomizationLevel
+              The argument has the form ePID [ / HwId ]. Always use  ePID  and
+              HwId  for  Windows activations. If specified, RandomizationLevel
               for Windows activitations will be ignored.
 
 
        Office2010
-              The  argument  has the form ePID [ / HwId ]. Always use ePID and
-              HwId for Office 2010 activations. If  specified,  Randomization‐
+              The argument has the form ePID [ / HwId ]. Always use  ePID  and
+              HwId  for  Office 2010 activations. If specified, Randomization‐
               Level for Office 2010 activitations will be ignored.
 
 
        Office2013
-              The  argument  has the form ePID [ / HwId ]. Always use ePID and
-              HwId for Office 2013 activations. If  specified,  Randomization‐
+              The argument has the form ePID [ / HwId ]. Always use  ePID  and
+              HwId  for  Office 2013 activations. If specified, Randomization‐
               Level for Office 2013 activitations will be ignored.
 
 
        Office2016
-              The  argument  has the form ePID [ / HwId ]. Always use ePID and
-              HwId for Office 2016 activations. If  specified,  Randomization‐
+              The argument has the form ePID [ / HwId ]. Always use  ePID  and
+              HwId  for  Office 2016 activations. If specified, Randomization‐
               Level for Office 2016 activitations will be ignored.
 
 
 VALID EPIDS
-       The  ePID is currently a comment only. You can specify any string up to
-       63 bytes. In Windows 7 Microsoft has blacklisted few (  <  10  )  ePIDs
-       that  were  used  in KMSv5 versions of the "Ratiborus Virtual Machine".
-       Microsoft has given up on blacklisting when KMS emulators  appeared  in
+       The ePID is currently a comment only. You can specify any string up  to
+       63  bytes.  In  Windows  7 Microsoft has blacklisted few ( < 10 ) ePIDs
+       that were used in KMSv5 versions of the  "Ratiborus  Virtual  Machine".
+       Microsoft  has  given up on blacklisting when KMS emulators appeared in
        the wild.
 
        Even if you can use "Activated by cool hacker guys" as an ePID, you may
        wish to use ePIDs that cannot be detected as non-MS ePIDs. If you don't
-       know  how  these  "valid"  ePIDs look like exactly, do not use GUIDS in
-       vlmcsd.ini. vlmcsd  provides  internal  mechanisms  to  generate  valid
+       know how these "valid" ePIDs look like exactly, do  not  use  GUIDS  in
+       vlmcsd.ini.  vlmcsd  provides  internal  mechanisms  to  generate valid
        ePIDs.
 
        If you use non-ASCII characters in your ePID (you shouldn't do anyway),
-       these must be in UTF-8 format. This is especially  important  when  you
+       these  must  be  in UTF-8 format. This is especially important when you
        run vlmcsd on Windows or cygwin because UTF-8 is not the default encod‐
        ing for most editors.
 
        If you are specifying an optional HWID it follows the same syntax as in
-       the  -H  option in vlmcsd(8) ecxept that you must not enclose a HWID in
+       the -H option in vlmcsd(8) ecxept that you must not enclose a  HWID  in
        quotes even if it contains spaces.
 
 
@@ -391,7 +439,7 @@ AUTHOR
 
 
 CREDITS
-       Thanks  to  CODYQX4,  deagles,  eIcn, mikmik38, nosferati87, qad, Rati‐
+       Thanks to CODYQX4, deagles, eIcn,  mikmik38,  nosferati87,  qad,  Rati‐
        borus, ...
 
 
@@ -400,4 +448,4 @@ SEE ALSO
 
 
 
-Hotbird64                        November 2016                   VLMCSD.INI(5)
+Hotbird64                        December 2016                   VLMCSD.INI(5)

+ 1 - 1
man/vlmcsdmulti.1.html

@@ -1,5 +1,5 @@
 <!-- Creator     : groff version 1.22.3 -->
-<!-- CreationDate: Mon Nov 28 01:28:23 2016 -->
+<!-- CreationDate: Mon Dec  5 18:18:46 2016 -->
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
 <html>

BIN
man/vlmcsdmulti.1.pdf


+ 9 - 3
src/GNUmakefile

@@ -192,6 +192,12 @@ ifneq ($(NOLIBS),1)
   endif
 endif 
 
+ifneq ($(NOLIBS),1)
+  ifeq ($(CYGWIN),1)
+    BASELDFLAGS += -liphlpapi
+  endif
+endif 
+
 ifneq ($(NO_DNS),1)
   ifneq ($(ANDROID),1)
   ifneq ($(NOLRESOLV),1)
@@ -441,9 +447,9 @@ endif
 endif
 
 ifeq "$(WIN)" "1"
-	VLMCSD_SRCS += ntservice.c
-	MULTI_SRCS += ntservice.c
-	../build/MULTI_OBJS += ntservice.o
+	VLMCSD_SRCS += ntservice.c wintap.c
+	MULTI_SRCS += ntservice.c wintap.c
+	MULTI_OBJS += ../build/ntservice.o ../build/wintap.o
 endif
 
 ifeq ($(CRYPTO), openssl_with_aes)

+ 34 - 5
src/helpers.c

@@ -230,6 +230,35 @@ int_fast8_t string2UuidLE(const char *const restrict input, GUID *const restrict
 }
 
 
+__pure DWORD timeSpanString2Seconds(const char *const restrict argument)
+{
+	char *unitId;
+
+	long long val = vlmcsd_strtoll(argument, &unitId, 10);
+
+	switch (toupper((int)*unitId))
+	{
+	case 'W':
+		val *= 7;
+	case 'D':
+		val *= 24;
+	case 'H':
+		val *= 60;
+	case 0:
+	case 'M':
+		val *= 60;
+	case 'S':
+		break;
+	default:
+		return 0;
+	}
+
+	if (*unitId && unitId[1]) return 0;
+	if (val < 1) val = 1;
+	return (DWORD)(val & UINT_MAX);
+}
+
+
 #if !IS_LIBRARY
 //Checks a command line argument if it is numeric and between min and max. Returns the numeric value or exits on error
 __pure unsigned int getOptionArgumentInt(const char o, const unsigned int min, const unsigned int max)
@@ -261,7 +290,7 @@ void optReset(void)
 }
 #endif // !IS_LIBRARY
 
-#if defined(_WIN32) || defined(USE_MSRPC)
+#if _WIN32 || __CYGWIN__
 
 // Returns a static message buffer containing text for a given Win32 error. Not thread safe (same as strerror)
 char* win_strerror(const int message)
@@ -273,7 +302,7 @@ char* win_strerror(const int message)
 	return buffer;
 }
 
-#endif // defined(_WIN32) || defined(USE_MSRPC)
+#endif // _WIN32 || __CYGWIN__
 
 
 /*
@@ -493,11 +522,11 @@ void getExeName()
 #ifdef _WIN32
 static void getDefaultDataFile()
 {
-	char fileName[512];
+	char fileName[MAX_PATH];
 	getExeName();
-	strcpy(fileName, fn_exe);
+	strncpy(fileName, fn_exe, MAX_PATH);
 	PathRemoveFileSpec(fileName);
-	strncat(fileName, "\\vlmcsd.kmd", 512);
+	strncat(fileName, "\\vlmcsd.kmd", MAX_PATH);
 	fn_data = vlmcsd_strdup(fileName);
 }
 #else // !_WIN32

+ 2 - 0
src/helpers.h

@@ -20,6 +20,8 @@
 BOOL stringToInt(const char *const szValue, const unsigned int min, const unsigned int max, unsigned int *const value);
 unsigned int getOptionArgumentInt(const char o, const unsigned int min, const unsigned int max);
 void optReset(void);
+__pure DWORD timeSpanString2Seconds(const char *const restrict argument);
+#define timeSpanString2Minutes(x) (timeSpanString2Seconds(x) / 60)
 char* win_strerror(const int message);
 int ucs2_to_utf8_char (const WCHAR ucs2_le, char *utf8);
 size_t utf8_to_ucs2(WCHAR* const ucs2_le, const char* const utf8, const size_t maxucs2, const size_t maxutf8);

+ 30 - 30
src/kmsdata.c

@@ -763,36 +763,36 @@ uint8_t DefaultKmsData[] =
 
 uint8_t DefaultKmsData[] =
 {
-	0x4B, 0x4D, 0x44, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0xC0, 0xE3, 0x12, 0x1C,
-	0xBF, 0x6A, 0xA6, 0x1F, 0x32, 0x00, 0x00, 0x00, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x60, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0xDC, 0x0B, 0x7F, 0x6A, 0xFE, 0x0C, 0x0A, 0x00, 0x00, 0x00,
-	0x74, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x80, 0x8E, 0xF2, 0x0D,
-	0xFF, 0x3F, 0x42, 0x0F, 0x0A, 0x00, 0x00, 0x00, 0xA6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xCE, 0x00, 0x00, 0x00, 0x40, 0x17, 0x0C, 0x1A, 0xBF, 0xC8, 0x5B, 0x1B, 0x0A, 0x00, 0x00, 0x00,
-	0x46, 0xF9, 0x5A, 0xE8, 0x25, 0x2E, 0xB7, 0x47, 0x83, 0xE1, 0xBE, 0xBC, 0xEB, 0xEA, 0xC6, 0x11,
-	0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00,
-	0xBF, 0xF1, 0xA6, 0xE6, 0x40, 0x9D, 0xC3, 0x40, 0xAA, 0x9F, 0xC7, 0x7B, 0xA2, 0x15, 0x78, 0xC0,
-	0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00,
-	0x68, 0x79, 0x4C, 0xAA, 0xDA, 0xB9, 0x80, 0x46, 0x92, 0xB6, 0xAC, 0xB2, 0x5E, 0x2F, 0x86, 0x6C,
-	0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x01, 0x02, 0x00,
-	0x1B, 0xF6, 0xB5, 0x85, 0x0B, 0x32, 0xE3, 0x4B, 0x81, 0x4A, 0xB7, 0x6B, 0x2B, 0xFA, 0xFC, 0x82,
-	0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00,
-	0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x32, 0x30, 0x36, 0x2D, 0x34, 0x37, 0x31, 0x2D,
-	0x31, 0x30, 0x34, 0x33, 0x39, 0x35, 0x2D, 0x30, 0x33, 0x2D, 0x31, 0x30, 0x33, 0x33, 0x2D, 0x31,
-	0x34, 0x33, 0x39, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x32, 0x39, 0x33, 0x32, 0x30, 0x31,
-	0x36, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x30, 0x39, 0x36, 0x2D, 0x31, 0x39,
-	0x39, 0x2D, 0x31, 0x39, 0x34, 0x38, 0x39, 0x33, 0x2D, 0x30, 0x33, 0x2D, 0x31, 0x30, 0x33, 0x33,
-	0x2D, 0x31, 0x34, 0x33, 0x39, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x32, 0x39, 0x33, 0x32,
-	0x30, 0x31, 0x36, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x32, 0x30, 0x36, 0x2D,
-	0x32, 0x33, 0x34, 0x2D, 0x31, 0x30, 0x39, 0x34, 0x38, 0x33, 0x2D, 0x30, 0x33, 0x2D, 0x31, 0x30,
-	0x33, 0x33, 0x2D, 0x31, 0x34, 0x33, 0x39, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x32, 0x39,
-	0x33, 0x32, 0x30, 0x31, 0x36, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x32, 0x30,
-	0x36, 0x2D, 0x34, 0x33, 0x37, 0x2D, 0x31, 0x38, 0x34, 0x37, 0x33, 0x34, 0x2D, 0x30, 0x33, 0x2D,
-	0x31, 0x30, 0x33, 0x33, 0x2D, 0x31, 0x34, 0x33, 0x39, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D,
-	0x32, 0x39, 0x33, 0x32, 0x30, 0x31, 0x36, 0x00, 0x55, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x00,
+	0x4B, 0x4D, 0x44, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0xC0, 0xE3, 0x12, 0x1C,
+	0xBF, 0x6A, 0xA6, 0x1F, 0x32, 0x00, 0x00, 0x00, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x60, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0xDC, 0x0B, 0x7F, 0x6A, 0xFE, 0x0C, 0x0A, 0x00, 0x00, 0x00,
+	0x74, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x80, 0x8E, 0xF2, 0x0D,
+	0xFF, 0x3F, 0x42, 0x0F, 0x0A, 0x00, 0x00, 0x00, 0xA6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xCE, 0x00, 0x00, 0x00, 0x40, 0x17, 0x0C, 0x1A, 0xBF, 0xC8, 0x5B, 0x1B, 0x0A, 0x00, 0x00, 0x00,
+	0x46, 0xF9, 0x5A, 0xE8, 0x25, 0x2E, 0xB7, 0x47, 0x83, 0xE1, 0xBE, 0xBC, 0xEB, 0xEA, 0xC6, 0x11,
+	0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00,
+	0xBF, 0xF1, 0xA6, 0xE6, 0x40, 0x9D, 0xC3, 0x40, 0xAA, 0x9F, 0xC7, 0x7B, 0xA2, 0x15, 0x78, 0xC0,
+	0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00,
+	0x68, 0x79, 0x4C, 0xAA, 0xDA, 0xB9, 0x80, 0x46, 0x92, 0xB6, 0xAC, 0xB2, 0x5E, 0x2F, 0x86, 0x6C,
+	0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x01, 0x02, 0x00,
+	0x1B, 0xF6, 0xB5, 0x85, 0x0B, 0x32, 0xE3, 0x4B, 0x81, 0x4A, 0xB7, 0x6B, 0x2B, 0xFA, 0xFC, 0x82,
+	0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00,
+	0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x32, 0x30, 0x36, 0x2D, 0x34, 0x37, 0x31, 0x2D,
+	0x31, 0x30, 0x34, 0x33, 0x39, 0x35, 0x2D, 0x30, 0x33, 0x2D, 0x31, 0x30, 0x33, 0x33, 0x2D, 0x31,
+	0x34, 0x33, 0x39, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x32, 0x39, 0x33, 0x32, 0x30, 0x31,
+	0x36, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x30, 0x39, 0x36, 0x2D, 0x31, 0x39,
+	0x39, 0x2D, 0x31, 0x39, 0x34, 0x38, 0x39, 0x33, 0x2D, 0x30, 0x33, 0x2D, 0x31, 0x30, 0x33, 0x33,
+	0x2D, 0x31, 0x34, 0x33, 0x39, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x32, 0x39, 0x33, 0x32,
+	0x30, 0x31, 0x36, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x32, 0x30, 0x36, 0x2D,
+	0x32, 0x33, 0x34, 0x2D, 0x31, 0x30, 0x39, 0x34, 0x38, 0x33, 0x2D, 0x30, 0x33, 0x2D, 0x31, 0x30,
+	0x33, 0x33, 0x2D, 0x31, 0x34, 0x33, 0x39, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x32, 0x39,
+	0x33, 0x32, 0x30, 0x31, 0x36, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x32, 0x30,
+	0x36, 0x2D, 0x34, 0x33, 0x37, 0x2D, 0x31, 0x38, 0x34, 0x37, 0x33, 0x34, 0x2D, 0x30, 0x33, 0x2D,
+	0x31, 0x30, 0x33, 0x33, 0x2D, 0x31, 0x34, 0x33, 0x39, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D,
+	0x32, 0x39, 0x33, 0x32, 0x30, 0x31, 0x36, 0x00, 0x55, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x00,
 };
 
 #else // !defined(NO_STRICT_MODES)

+ 4 - 0
src/output.c

@@ -643,6 +643,10 @@ void printServerFlags()
 		" SUPPORT_WINE"
 #		endif // (_WIN32 || __CYGWIN__) && (!defined(USE_MSRPC) || defined(SUPPORT_WINE))
 
+#		if (_WIN32 || __CYGWIN__) && defined(NO_TAP)
+		" NO_TAP"
+#		endif // (_WIN32 || __CYGWIN__) && defined(NO_TAP)
+
 #		if !HAVE_FREEBIND
 		" NO_FREEBIND"
 #		endif //!HAVE_FREEBIND

+ 77 - 0
src/tap-windows.h

@@ -0,0 +1,77 @@
+/*
+ *  TAP-Windows -- A kernel driver to provide virtual tap
+ *                 device functionality on Windows.
+ *
+ *  This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
+ *
+ *  This source code is Copyright (C) 2002-2014 OpenVPN Technologies, Inc.,
+ *  and is released under the GPL version 2 (see below). This particular file
+ *  (tap-windows.h) is also licensed using the MIT license (see COPYRIGHT.MIT).
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __TAP_WIN_H
+#define __TAP_WIN_H
+
+/*
+ * =============
+ * TAP IOCTLs
+ * =============
+ */
+
+#define TAP_WIN_CONTROL_CODE(request,method) \
+  CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
+
+/* Present in 8.1 */
+
+#define TAP_WIN_IOCTL_GET_MAC               TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED)
+#define TAP_WIN_IOCTL_GET_VERSION           TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED)
+#define TAP_WIN_IOCTL_GET_MTU               TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED)
+#define TAP_WIN_IOCTL_GET_INFO              TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED)
+#define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED)
+#define TAP_WIN_IOCTL_SET_MEDIA_STATUS      TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED)
+#define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ      TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED)
+#define TAP_WIN_IOCTL_GET_LOG_LINE          TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED)
+#define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT   TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED)
+
+/* Added in 8.2 */
+
+/* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */
+#define TAP_WIN_IOCTL_CONFIG_TUN            TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED)
+
+/*
+ * =================
+ * Registry keys
+ * =================
+ */
+
+#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+
+#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+
+/*
+ * ======================
+ * Filesystem prefixes
+ * ======================
+ */
+
+#define USERMODEDEVICEDIR "\\\\.\\Global\\"
+#define SYSDEVICEDIR      "\\Device\\"
+#define USERDEVICEDIR     "\\DosDevices\\Global\\"
+#define TAP_WIN_SUFFIX    ".tap"
+
+#endif // __TAP_WIN_H
+
+

+ 4 - 0
src/types.h

@@ -227,6 +227,10 @@ typedef struct __packed
 
 #if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(NO_SOCKETS)
 #define _NTSERVICE
+#else
+#ifndef NO_TAP
+#define NO_TAP
+#endif
 #endif
 
 #if (defined(__CYGWIN__) || defined(_WIN32) || defined(NO_SOCKETS)) && !defined(NO_SIGHUP)

+ 1 - 1
src/vlmcs.c

@@ -854,7 +854,7 @@ int SendActivationRequest(const RpcCtx sock, RESPONSE *baseResponse, REQUEST *ba
 	else
 		request = CreateRequestV6(&requestSize, baseRequest);
 
-	if (!(status = rpcSendRequest(sock, request, requestSize, &response, &responseSize)))
+	if (!((status = rpcSendRequest(sock, request, requestSize, &response, &responseSize))))
 	{
 		if (LE16(((RESPONSE*)(response))->MajorVer) == 4)
 		{

+ 50 - 48
src/vlmcsd.c

@@ -80,7 +80,11 @@
 #include "ntservice.h"
 #include "helpers.h"
 
-static const char* const optstring = "N:B:m:t:w:0:3:6:H:A:R:u:g:L:p:i:P:l:r:U:W:C:c:F:o:T:K:E:M:j:SseDdVvqkZ";
+#ifndef NO_TAP
+#include "wintap.h"
+#endif
+
+static const char* const optstring = "N:B:m:t:w:0:3:6:H:A:R:u:g:L:p:i:P:l:r:U:W:C:c:F:O:o:T:K:E:M:j:SseDdVvqkZ";
 
 #if !defined(NO_SOCKETS) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
 static uint_fast8_t maxsockets = 0;
@@ -105,6 +109,10 @@ static const char *fn_ini = INI_FILE;
 static const char *fn_ini = NULL;
 #endif // !INI_FILE
 
+#ifndef NO_TAP
+char* tapArgument = NULL;
+#endif // NO_TAP
+
 static const char* IniFileErrorMessage = "";
 char* IniFileErrorBuffer = NULL;
 #define INIFILE_ERROR_BUFFERSIZE 256
@@ -115,6 +123,9 @@ static IniFileParameter_t IniFileParameterList[] =
 		{ "Office2010", INI_PARAM_OFFICE2010 },
 		{ "Office2013", INI_PARAM_OFFICE2013 },
 		{ "Office2016", INI_PARAM_OFFICE2016 },
+#	ifndef NO_TAP
+		{ "VPN", INI_PARAM_VPN },
+#   endif // NO_TAP
 #	ifndef NO_EXTERNAL_DATA
 		{ "KmsData", INI_PARAM_DATA_FILE },
 #	endif // NO_EXTERNAL_DATA
@@ -281,6 +292,9 @@ static __noreturn void usage()
 #		endif // USE_MSRPC
 #		endif // !HAVE_GETIFADDR
 #		endif // !defined(NO_PRIVATE_IP_DETECT)
+#		ifndef NO_TAP
+		"  -O <v>[=<a>][/<c>]\tuse VPN adapter <v> with IPv4 address <a> and CIDR <c>\n"
+#		endif
 #		ifndef NO_SOCKETS
 #		if !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
 		"  -L <address>[:<port>]\tlisten on IP address <address> with optional <port>\n"
@@ -368,43 +382,8 @@ static __noreturn void usage()
 
 
 #ifndef NO_CUSTOM_INTERVALS
-
-// Convert time span strings (e.g. "2h", "5w") to minutes
-__pure static DWORD timeSpanString2Minutes(const char *const restrict argument)
-{
-	char *unitId;
-
-	long long val = vlmcsd_strtoll(argument, &unitId, 10);
-
-	switch (toupper((int)*unitId))
-	{
-	case 0:
-	case 'M':
-		break;
-	case 'H':
-		val *= 60;
-		break;
-	case 'D':
-		val *= 60 * 24;
-		break;
-	case 'W':
-		val *= 60 * 24 * 7;
-		break;
-	case 'S':
-		val /= 60;
-		break;
-	default:
-		return 0;
-	}
-
-	if (val < 1) val = 1;
-	if (val > UINT_MAX) val = UINT_MAX;
-
-	return (DWORD)val;
-}
-
-
 #ifndef NO_INI_FILE
+
 __pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restrict argument)
 {
 	DWORD val = timeSpanString2Minutes(argument);
@@ -417,12 +396,13 @@ __pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restr
 	*result = val;
 	return TRUE;
 }
+
 #endif // NO_INI_FILE
 
 
 __pure static DWORD getTimeSpanFromCommandLine(const char *const restrict optarg, const char optchar)
 {
-	long long val = timeSpanString2Minutes(optarg);
+	DWORD val = timeSpanString2Minutes(optarg);
 
 	if (!val)
 	{
@@ -430,7 +410,7 @@ __pure static DWORD getTimeSpanFromCommandLine(const char *const restrict optarg
 		exit(VLMCSD_EINVAL);
 	}
 
-	return (DWORD)val;
+	return val;
 }
 
 #endif // NO_CUSTOM_INTERVALS
@@ -569,6 +549,14 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
 		setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2016);
 		break;
 
+#	ifndef NO_TAP
+
+	case INI_PARAM_VPN:
+		tapArgument = (char*)vlmcsd_strdup(iniarg);
+		break;
+
+#	endif // NO_TAP
+
 #	if !defined(NO_USER_SWITCH) && !_WIN32
 
 	case INI_PARAM_GID:
@@ -1078,6 +1066,15 @@ static void parseGeneralArguments() {
 		break;
 #	endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
 
+#	ifndef NO_TAP
+
+	case 'O':
+		ignoreIniFileParameter(INI_PARAM_VPN);
+		tapArgument = getCommandLineArg(optarg);
+		break;
+
+#	endif // NO_TAP
+
 #	ifndef NO_CL_PIDS
 
 	case 'w':
@@ -1413,16 +1410,16 @@ static void writePidFile()
 
 	if (fn_pid && !InetdMode)
 	{
-		FILE *_f = fopen(fn_pid, "w");
+		FILE *file = fopen(fn_pid, "w");
 
-		if (_f)
+		if (file)
 		{
 #			if _MSC_VER
-			fprintf(_f, "%u", (unsigned int)GetCurrentProcessId());
+			fprintf(file, "%u", (unsigned int)GetCurrentProcessId());
 #			else
-			fprintf(_f, "%u", (unsigned int)getpid());
+			fprintf(file, "%u", (unsigned int)getpid());
 #			endif
-			fclose(_f);
+			fclose(file);
 		}
 
 #		ifndef NO_LOG
@@ -1647,10 +1644,6 @@ int setupListeningSockets()
 
 int server_main(int argc, CARGV argv)
 {
-#	if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
-	KmsResponseParameters = (KmsResponseParam_t*)vlmcsd_malloc(sizeof(KmsResponseParam_t) * MIN_CSVLK);
-	memset(KmsResponseParameters, 0, sizeof(KmsResponseParam_t) * MIN_CSVLK);
-#	endif // !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
 	global_argc = argc;
 	global_argv = argv;
 
@@ -1672,6 +1665,11 @@ int server_main(int argc, CARGV argv)
 
 int newmain()
 {
+#	if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
+	KmsResponseParameters = (KmsResponseParam_t*)vlmcsd_malloc(sizeof(KmsResponseParam_t) * MIN_CSVLK);
+	memset(KmsResponseParameters, 0, sizeof(KmsResponseParam_t) * MIN_CSVLK);
+#	endif // !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
+
 	// Initialize thread synchronization objects for Windows and Cygwin
 #	ifdef USE_THREADS
 
@@ -1769,6 +1767,10 @@ int newmain()
 		return NtServiceInstallation(installService, ServiceUser, ServicePassword);
 #	endif // _NTSERVICE
 
+#	ifndef NO_TAP
+	if (tapArgument && !InetdMode) startTap(tapArgument);
+#	endif // NO_TAP
+
 #	if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
 	if (!InetdMode)
 	{

+ 1 - 0
src/vlmcsd.h

@@ -57,6 +57,7 @@ int server_main(int argc, CARGV argv);
 #define INI_PARAM_MAINTAIN_CLIENTS 26
 #define INI_PARAM_START_EMPTY 27
 #define INI_PARAM_DATA_FILE 28
+#define INI_PARAM_VPN 29
 
 #define INI_FILE_PASS_1 1
 #define INI_FILE_PASS_2 2

+ 367 - 0
src/wintap.c

@@ -0,0 +1,367 @@
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#ifndef CONFIG
+#define CONFIG "config.h"
+#endif // CONFIG
+#include CONFIG
+#include "helpers.h"
+#include "wintap.h"
+
+#ifndef NO_TAP
+
+#include "types.h"
+#include "endian.h"
+#include "output.h"
+#include "tap-windows.h"
+#include <iphlpapi.h>
+
+static char* szIpAddress = "10.10.10.9";
+static char* szMask = "30";
+static char* szTapName;
+static char *ActiveTapName, *AdapterClass;
+static char* szLeaseDuration = "1d";
+static uint32_t IpAddress, Mask, Network, Broadcast, DhcpServer; // These are host-endian (=little-endian) for easier calculations
+static uint32_t Mtu;
+static uint_fast8_t Cidr;
+static HANDLE TapHandle;
+static TapDriverVersion_t DriverVersion;
+static IpPacket_t* IpPacket;
+static uint32_t DhcpLeaseDuration;
+
+
+static BOOL isAddressAssigned()
+{
+	PMIB_IPADDRTABLE pIPAddrTable;
+	DWORD dwSize = 0;
+	BOOL result = FALSE;
+
+	pIPAddrTable = (PMIB_IPADDRTABLE)vlmcsd_malloc(sizeof(MIB_IPADDRTABLE));
+	DWORD status = GetIpAddrTable(pIPAddrTable, &dwSize, 0);
+	free(pIPAddrTable);
+
+	if (status != ERROR_INSUFFICIENT_BUFFER) return FALSE;
+	pIPAddrTable = (MIB_IPADDRTABLE *)vlmcsd_malloc(dwSize);
+
+	if (GetIpAddrTable(pIPAddrTable, &dwSize, 0))
+	{
+		free(pIPAddrTable);
+		return FALSE;
+	}
+
+	PMIB_IPADDRROW row;
+	for (row = pIPAddrTable->table; row < pIPAddrTable->table + pIPAddrTable->dwNumEntries; row++)
+	{
+		if (
+			row->dwAddr == BE32(IpAddress) &&
+			!(row->wType & (MIB_IPADDR_DELETED | MIB_IPADDR_DISCONNECTED | MIB_IPADDR_TRANSIENT))
+			)
+		{
+			result = TRUE;
+			break;
+		}
+	}
+
+	free(pIPAddrTable);
+	return result;
+}
+
+
+static void parseTapArgument(char* argument)
+{
+	char* equalsignPosition = strchr(argument, (int)'=');
+	char* slashPosition = strchr(argument, (int)'/');
+	char* colonPosition = strchr(argument, (int)':');
+
+	szTapName = argument;
+
+	if (equalsignPosition)
+	{
+		*equalsignPosition = 0;
+		szIpAddress = equalsignPosition + 1;
+	}
+
+	if (slashPosition)
+	{
+		*slashPosition = 0;
+		szMask = slashPosition + 1;
+	}
+
+	if (colonPosition)
+	{
+		*colonPosition = 0;
+		szLeaseDuration = colonPosition + 1;
+	}
+
+	IpAddress = BE32(inet_addr(szIpAddress));
+
+	if (IpAddress == BE32(INADDR_NONE))
+	{
+		printerrorf("Fatal: %s is not a valid IPv4 address\n", szIpAddress);
+		exit(VLMCSD_EINVAL);
+	}
+
+	char* next;
+	Cidr = (uint8_t)strtol(szMask, &next, 10);
+
+	if (*next || Cidr < 8 || Cidr > 30)
+	{
+		printerrorf("Fatal: /%s is not a valid CIDR mask between /8 and /30\n", szMask);
+		exit(VLMCSD_EINVAL);
+	}
+
+	if (!((DhcpLeaseDuration = timeSpanString2Seconds(szLeaseDuration))))
+	{
+		printerrorf("Fatal: No valid time span specified in option -%c.\n", 'O');
+		exit(VLMCSD_EINVAL);
+	}
+
+	Mask = (uint32_t)~(UINT_MAX >> Cidr);
+	Network = IpAddress & Mask;
+	Broadcast = IpAddress | ~Mask;
+	DhcpServer = IpAddress + 1;
+
+	if (IpAddress <= Network || IpAddress + 1 >= Broadcast)
+	{
+		uint32_t lowerIpBE = BE32(Network + 1);
+		uint32_t upperIpBE = BE32(Broadcast - 2);
+		const char* szLower = vlmcsd_strdup(inet_ntoa(*(struct in_addr*)&lowerIpBE));
+		const char* szUpper = vlmcsd_strdup(inet_ntoa(*(struct in_addr*)&upperIpBE));
+
+		printerrorf("Fatal: For this subnet the IPv4 address must be ");
+
+		if (lowerIpBE == upperIpBE)
+		{
+			printerrorf("%s\n", szLower);
+		}
+		else
+		{
+			printerrorf("between %s and %s\n", szLower, szUpper);
+		}
+
+		exit(VLMCSD_EINVAL);
+	}
+}
+
+
+__noreturn static void WinErrorExit(DWORD error)
+{
+	printerrorf("Registry read error: %s\n", win_strerror((int)error));
+	exit(error);
+}
+
+
+static HANDLE OpenTapHandle()
+{
+	HANDLE handle = INVALID_HANDLE_VALUE;
+	HKEY regAdapterKey;
+	DWORD regResult;
+	if ((regResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &regAdapterKey)) != ERROR_SUCCESS)
+	{
+		WinErrorExit(regResult);
+	}
+
+	char subkeyName[TAP_REGISTRY_DATA_SIZE];
+	DWORD i, subKeySize = sizeof(subkeyName);
+
+	for (i = 0; (regResult = RegEnumKeyEx(regAdapterKey, i, subkeyName, &subKeySize, NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS; i++)
+	{
+		HKEY regSubKey;
+		DWORD type, regDataSize;
+		char regData[TAP_REGISTRY_DATA_SIZE];
+
+		if (regResult) WinErrorExit(regResult);
+
+		if ((regResult = RegOpenKeyEx(regAdapterKey, subkeyName, 0, KEY_READ | KEY_WOW64_64KEY, &regSubKey)) == ERROR_SUCCESS)
+		{
+			regDataSize = sizeof(regData);
+
+			if (RegQueryValueEx(regSubKey, "ComponentId", NULL, &type, (LPBYTE)regData, &regDataSize) == ERROR_SUCCESS)
+			{
+				if (
+					type == REG_SZ &&
+					(
+						!strncmp(regData, "tap0801", sizeof(regData)) ||
+						!strncmp(regData, "tap0901", sizeof(regData)) ||
+						!strncmp(regData, "TEAMVIEWERVPN", sizeof(regData))
+						)
+					)
+				{
+					AdapterClass = vlmcsd_strdup(regData);
+					regDataSize = sizeof(regData);
+
+					if (RegQueryValueEx(regSubKey, "NetCfgInstanceId", NULL, &type, (LPBYTE)regData, &regDataSize) == ERROR_SUCCESS && type == REG_SZ)
+					{
+						HKEY connectionKey;
+						char connectionKeyName[TAP_REGISTRY_DATA_SIZE];
+
+						strncpy(connectionKeyName, NETWORK_CONNECTIONS_KEY "\\", sizeof(connectionKeyName));
+						strncat(connectionKeyName, regData, sizeof(connectionKeyName));
+						strncat(connectionKeyName, "\\Connection", sizeof(connectionKeyName));
+
+						if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, connectionKeyName, 0, KEY_READ | KEY_WOW64_64KEY, &connectionKey) == ERROR_SUCCESS)
+						{
+							char deviceName[TAP_REGISTRY_DATA_SIZE];
+							regDataSize = sizeof(deviceName);
+
+							if (RegQueryValueEx(connectionKey, "Name", NULL, &type, (LPBYTE)deviceName, &regDataSize) == ERROR_SUCCESS && type == REG_SZ)
+							{
+								if (!strcmp(szTapName, ".") || !strncasecmp(szTapName, deviceName, sizeof(deviceName)))
+								{
+									ActiveTapName = vlmcsd_strdup(deviceName);
+									strncpy(deviceName, USERMODEDEVICEDIR, sizeof(deviceName));
+									strncat(deviceName, regData, sizeof(deviceName));
+									strncat(deviceName, strcmp(AdapterClass, "TEAMVIEWERVPN") ? TAP_WIN_SUFFIX : ".dgt", sizeof(deviceName));
+									handle = CreateFile(deviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
+								}
+							}
+						}
+
+						RegCloseKey(connectionKey);
+					}
+
+					if (handle == INVALID_HANDLE_VALUE) free(AdapterClass);
+				}
+			}
+		}
+
+		RegCloseKey(regSubKey);
+		subKeySize = sizeof(subkeyName);
+		if (handle != INVALID_HANDLE_VALUE) break;
+	}
+
+	RegCloseKey(regAdapterKey);
+
+	if (handle == INVALID_HANDLE_VALUE)
+	{
+		printerrorf("Fatal: No compatible VPN adapter");
+
+		if (!strcmp(szTapName, "."))
+		{
+			printerrorf("s");
+		}
+		else
+		{
+			printerrorf(" with name \"%s\"", szTapName);
+		}
+
+		printerrorf(" available for use\n");
+		exit(ERROR_DEVICE_NOT_AVAILABLE);
+	}
+
+	return handle;
+}
+
+
+static int DevCtl(DWORD code, void* data, DWORD len)
+{
+	if (!DeviceIoControl(TapHandle, code, data, len, data, len, &len, NULL))
+	{
+		DWORD error = GetLastError();
+		printerrorf("Fatal: VPN adapter error: %s\n", win_strerror(error));
+		exit(error);
+	}
+
+	return len;
+}
+
+
+static DWORD WINAPI TapMirror(LPVOID data)
+{
+	while (TRUE)
+	{
+		DWORD bytesRead, bytesWritten;
+		if (!ReadFile(TapHandle, IpPacket, Mtu, &bytesRead, NULL)) break;
+
+		uint32_t temp = IpPacket->ip_src;
+		IpPacket->ip_src = IpPacket->ip_dst;
+		IpPacket->ip_dst = temp;
+
+		if (!WriteFile(TapHandle, IpPacket, bytesRead, &bytesWritten, NULL)) break;
+
+#		if !defined(NO_LOG) && defined(_PEDANTIC)
+		if (bytesRead != bytesWritten) logger("Warning: VPN device \"%s\": %u bytes could not be written\n", ActiveTapName, bytesRead - bytesWritten);
+#		endif // !defined(NO_LOG) && defined(_PEDANTIC)
+	}
+
+	DWORD error = GetLastError();
+
+#	ifndef NO_LOG
+	logger("Warning: VPN thread for device \"%s\" exiting: %s\n", ActiveTapName, win_strerror(error));
+#	endif // NO_LOG
+
+	free(ActiveTapName);
+	CloseHandle(TapHandle);
+	return error;
+}
+
+
+void startTap(char* const argument)
+{
+	if (!strcmp(argument, "-")) return;
+	parseTapArgument(argument);
+
+	TapHandle = OpenTapHandle();
+
+	// Get MTU and driver version
+	DevCtl(TAP_WIN_IOCTL_GET_MTU, &Mtu, sizeof(Mtu));
+	DevCtl(TAP_WIN_IOCTL_GET_VERSION, &DriverVersion, sizeof(DriverVersion));
+
+	// Configure TUN mode
+	TapConfigTun_t tapTunCfg;
+	tapTunCfg.Address.s_addr = BE32(IpAddress);
+	tapTunCfg.Network.s_addr = BE32(Network);
+	tapTunCfg.Mask.s_addr = BE32(Mask);
+	DevCtl(TAP_WIN_IOCTL_CONFIG_TUN, &tapTunCfg, sizeof(tapTunCfg));
+
+	// Setup the drivers internal DHCP server
+	TapConfigDhcp_t tapDhcpCfg;
+	tapDhcpCfg.Address.s_addr = BE32(IpAddress);
+	tapDhcpCfg.Mask.s_addr = BE32(Mask);
+	tapDhcpCfg.DhcpServer.s_addr = BE32(IpAddress + 1);
+	tapDhcpCfg.LeaseDuration = DhcpLeaseDuration;
+	DevCtl(TAP_WIN_IOCTL_CONFIG_DHCP_MASQ, &tapDhcpCfg, sizeof(tapDhcpCfg));
+
+	// Connect the virtual network cable
+	BOOL isCableConnected = TRUE;
+	DevCtl(TAP_WIN_IOCTL_SET_MEDIA_STATUS, &isCableConnected, sizeof(isCableConnected));
+
+	// Allocate buffer and start mirror thread
+	IpPacket = (IpPacket_t*)vlmcsd_malloc(Mtu);
+	HANDLE threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TapMirror, NULL, 0, NULL);
+
+	if (!threadHandle)
+	{
+		DWORD error = GetLastError();
+		printerrorf("Fatal: Unable to start VPN thread: %s\n", win_strerror(error));
+		exit(error);
+	}
+
+	CloseHandle(threadHandle);
+
+#	ifndef NO_LOG
+	logger("%s %u.%u.%u device \"%s\" started\n", AdapterClass, DriverVersion.Major, DriverVersion.Minor, DriverVersion.Build, ActiveTapName);
+#	endif // NO_LOG
+
+	DWORD i;
+	BOOL isAssigned;
+
+	// Wait up to 4 seconds until the IP address is up and running
+	// so vlmcsd can actually bind to and listen on it
+	for (i = 0; !((isAssigned = isAddressAssigned())) && i < 20; i++) Sleep(200);
+
+	if (!isAssigned)
+	{
+		printerrorf("Warning: IPv4 address %s not assigned\n", szIpAddress);
+	}
+	else
+	{
+#		ifndef NO_LOG
+		logger("IPv4 address %s assigned\n", szIpAddress);
+#		endif // NO_LOG
+	}
+}
+
+#endif // NO_TAP
+

+ 50 - 0
src/wintap.h

@@ -0,0 +1,50 @@
+#ifndef __WINTAP_H
+#define __WINTAP_H
+
+#define TAP_REGISTRY_DATA_SIZE 256
+
+// Network-Endian (= Big-Endian)
+typedef struct TapConfigTun
+{
+	struct in_addr Address;
+	struct in_addr  Network;
+	struct in_addr  Mask;
+} TapConfigTun_t, *PTapConfigTun_t;
+
+// Network-Endian (= Big-Endian), except LeaseDuration
+typedef struct TapConfigDhcp
+{
+	struct in_addr  Address;
+	struct in_addr  Mask;
+	struct in_addr  DhcpServer;
+	uint32_t  LeaseDuration; // Host-Endian (=Little-Endian). Anything else is Big-Endian
+} TapConfigDhcp_t, *PTapConfigDhcp_t;
+
+typedef struct TapDriverVersion
+{
+	uint32_t Major;
+	uint32_t Minor;
+	uint32_t Build;
+	uint32_t Revision;
+} TapDriverVersion_t, *PTapDriverVersion_t;
+
+// Network-Endian (= Big-Endian)
+typedef struct IpPacket {
+	uint8_t	 ip_hl : 4,		/* header length */
+			 ip_v : 4;			/* version */
+	uint8_t	 ip_tos;			/* type of service */
+	int16_t	 ip_len;			/* total length */
+	uint16_t ip_id;			/* identification */
+	int16_t	 ip_off;			/* fragment offset field */
+	uint8_t	 ip_ttl;			/* time to live */
+	uint8_t	 ip_p;			/* protocol */
+	uint16_t ip_sum;			/* checksum */
+	uint32_t ip_src, ip_dst;	/* source and dest address */
+	uint8_t  payload[0];
+} IpPacket_t, *PIpPacket_t;
+
+void startTap(char* const argument);
+
+#endif //__WINTAP_H
+
+