vlmcsd-svn1099-2016-10-25-Hotbird64

This commit is contained in:
Wind4
2016-10-31 20:59:15 +08:00
parent 936811ff5c
commit fcbbc40d60
39 changed files with 904 additions and 305 deletions

View File

@ -12,17 +12,17 @@
/*
* ----------------------------------------------------------------------------------------
* Useful customizations. These options are mandatory. You cannot comment them out.
* Feel free to change them to fit your needs.
* ----------------------------------------------------------------------------------------
*/
/*
* ----------------------------------------------------------------------------------------
* Useful customizations. These options are mandatory. You cannot comment them out.
* Feel free to change them to fit your needs.
* ----------------------------------------------------------------------------------------
*/
#ifndef VERSION
/*
* Define your own version identifier here, e.g. '#define VERSION "my vlmcsd based on svn560"'
*/
/*
* Define your own version identifier here, e.g. '#define VERSION "my vlmcsd based on svn560"'
*/
#define VERSION "private build"
@ -31,56 +31,56 @@
/*
* Define default ePIDs and HWID here. Preferrably grab ePIDs and HWID
* from a real KMS server.
*/
/*
* Define default ePIDs and HWID here. Preferrably grab ePIDs and HWID
* from a real KMS server.
*/
#ifndef EPID_WINDOWS
#define EPID_WINDOWS "03612-00206-471-109239-03-1033-14393.0000-2932016"
#define EPID_WINDOWS "03612-00206-471-452343-03-1033-14393.0000-2932016"
#endif
#ifndef EPID_OFFICE2010
#define EPID_OFFICE2010 "03612-00096-199-390352-03-1033-14393.0000-2932016"
#define EPID_OFFICE2010 "03612-00096-199-303490-03-1033-14393.0000-2932016"
#endif
#ifndef EPID_OFFICE2013
#define EPID_OFFICE2013 "03612-00206-234-938378-03-1033-14393.0000-2932016"
#define EPID_OFFICE2013 "03612-00206-234-394838-03-1033-14393.0000-2932016"
#endif
#ifndef EPID_OFFICE2016
#define EPID_OFFICE2016 "03612-00206-437-305903-03-1033-14393.0000-2932016"
#define EPID_OFFICE2016 "03612-00206-437-938923-03-1033-14393.0000-2932016"
#endif
#ifndef HWID // HwId from the Ratiborus VM
#define HWID 0x36, 0x4F, 0x46, 0x3A, 0x88, 0x63, 0xD3, 0x5F
#define HWID 0x3A, 0x1C, 0x04, 0x96, 0x00, 0xB6, 0x00, 0x76
#endif
/*
* Anything below this line is optional. If you want to use any of these options
* uncomment one or more lines starting with "//#define"
*/
/*
* Anything below this line is optional. If you want to use any of these options
* uncomment one or more lines starting with "//#define"
*/
/*
* -------------------------------
* Defaults
* -------------------------------
*/
/*
* -------------------------------
* Defaults
* -------------------------------
*/
#ifndef INI_FILE
/*
* Uncomment and customize the following line if you want vlmcsd to look for an ini file
* at a default location
*/
/*
* Uncomment and customize the following line if you want vlmcsd to look for an ini file
* at a default location
*/
//#define INI_FILE "/etc/vlmcsd.ini"
//#define INI_FILE "/etc/vlmcsd.ini"
#endif // INI_FILE
@ -97,15 +97,15 @@
#ifndef CHILD_HANDLER
/*
* Uncomment the following #define if you are compiling for a platform that does
* not correctly handle the SA_NOCLDWAIT flag when ignoring SIGCHLD, i.e. forked
* processes remain as "zombies" after dying. This option will add a SIGCHLD handler that
* "waits" for a child that has terminated. This is only required for a few
* unixoid OSses.
*/
/*
* Uncomment the following #define if you are compiling for a platform that does
* not correctly handle the SA_NOCLDWAIT flag when ignoring SIGCHLD, i.e. forked
* processes remain as "zombies" after dying. This option will add a SIGCHLD handler that
* "waits" for a child that has terminated. This is only required for a few
* unixoid OSses.
*/
//#define CHILD_HANDLER
//#define CHILD_HANDLER
#endif // CHILD_HANDLER
@ -116,7 +116,7 @@
* not support custom socket send or receive timeouts.
*/
//#define NO_TIMEOUT
//#define NO_TIMEOUT
#endif // NO_TIMEOUT
@ -128,7 +128,7 @@
* detecting KMS servers via DNS.
*/
//#define NO_DNS
//#define NO_DNS
#endif // NO_DNS
@ -140,7 +140,7 @@
* This affects the output of "vlmcsd -x" only. It should be rarely necessary to use this.
*/
//#define TERMINAL_FIXED_WIDTH 80
//#define TERMINAL_FIXED_WIDTH 80
#endif // TERMINAL_FIXED_WIDTH
@ -154,7 +154,7 @@
* you are testing any KMS server or client emulator that may send malformed KMS packets.
*/
//#define _PEDANTIC
//#define _PEDANTIC
#endif // _PEDANTIC
@ -185,7 +185,7 @@
* This option is not used because Windows doesn't support signals.
*/
//#define NO_PROCFS
//#define NO_PROCFS
#endif // NO_PROCFS
@ -208,7 +208,7 @@
* It it safe to try this by yourself. vlmcsd won't compile if your system doesn't support it.
*/
//#define USE_AUXV
//#define USE_AUXV
#endif // USE_AUXV
@ -223,7 +223,7 @@
* This may be necessary for some embedded devices that have OpenSSL without HMAC support.
*/
//#define _OPENSSL_NO_HMAC
//#define _OPENSSL_NO_HMAC
#endif // _OPENSSL_NO_HMAC
@ -238,26 +238,26 @@
#ifndef USE_THREADS
/*
* Do not use fork() but threads to serve your clients.
*
* Unix-like operarting systems:
* You may use this or not. Entirely your choice. Threads do not require explicitly allocating
* a shared memory segment which might be a problem on some systems. Using fork() is more robust
* although the threaded version of vlmcsd is rock solid too.
*
* Some older unixoid OSses may not have pthreads. Do NOT use USE_THREADS and define NO_SIGHUP
* and NO_LIMIT instead to disable use of the pthreads, shared memory and semaphores.
*
* Cygwin:
* It is recommended to use threads since fork() is extremely slow (no copy on write) and somewhat
* unstable.
*
* Windows:
* This option has no effect since fork() is not supported.
*/
/*
* Do not use fork() but threads to serve your clients.
*
* Unix-like operarting systems:
* You may use this or not. Entirely your choice. Threads do not require explicitly allocating
* a shared memory segment which might be a problem on some systems. Using fork() is more robust
* although the threaded version of vlmcsd is rock solid too.
*
* Some older unixoid OSses may not have pthreads. Do NOT use USE_THREADS and define NO_SIGHUP
* and NO_LIMIT instead to disable use of the pthreads, shared memory and semaphores.
*
* Cygwin:
* It is recommended to use threads since fork() is extremely slow (no copy on write) and somewhat
* unstable.
*
* Windows:
* This option has no effect since fork() is not supported.
*/
//#define USE_THREADS
//#define USE_THREADS
#endif // USE_THREADS
@ -278,7 +278,7 @@
* Do not define both _CRYPTO_OPENSSL and _CRYPTO_POLARSSL
*/
//#define _CRYPTO_POLARSSL
//#define _CRYPTO_POLARSSL
#endif // _CRYPTO_POLARSSL
@ -299,7 +299,7 @@
* Do not define both _CRYPTO_OPENSSL and _CRYPTO_POLARSSL
*/
//#define _CRYPTO_OPENSSL
//#define _CRYPTO_OPENSSL
#endif // _CRYPTO_OPENSSL
@ -319,7 +319,7 @@
* Don't use this except for your own research on the internals of OpenSSL.
*/
//#define _USE_AES_FROM_OPENSSL
//#define _USE_AES_FROM_OPENSSL
#endif // _USE_AES_FROM_OPENSSL
@ -335,7 +335,7 @@
* compiled without support for hardware accelerated AES. It's worth a try if _USE_AES_FROM_OPENSSL doesn't work.
*/
//#define _OPENSSL_SOFTWARE
//#define _OPENSSL_SOFTWARE
#endif // _OPENSSL_SOFTWARE
@ -350,12 +350,12 @@
#ifndef INCLUDE_BETAS
/*
* Uncomment the following #define if you want obsolete beta/preview SKUs
* to be included in the extended product list.
*/
/*
* Uncomment the following #define if you want obsolete beta/preview SKUs
* to be included in the extended product list.
*/
//#define INCLUDE_BETAS
//#define INCLUDE_BETAS
#endif
@ -370,13 +370,13 @@
#ifndef NO_FREEBIND
/*
* Do not compile support for FREEBIND (Linux) and IP_BINDANY (FreeBSD). This disables the -F1 command
* line option and you can bind only to (listen on) IP addresses that are currently up and running on
* your system.
*/
/*
* Do not compile support for FREEBIND (Linux) and IP_BINDANY (FreeBSD). This disables the -F1 command
* line option and you can bind only to (listen on) IP addresses that are currently up and running on
* your system.
*/
//#define NO_FREEBIND
//#define NO_FREEBIND
#endif // NO_FREEBIND
@ -394,7 +394,7 @@
*
*/
//#define NO_EXTENDED_PRODUCT_LIST
//#define NO_EXTENDED_PRODUCT_LIST
#endif // NO_EXTENDED_PRODUCT_LIST
@ -409,7 +409,7 @@
* do not save much space by not compiling this list.
*/
//#define NO_BASIC_PRODUCT_LIST
//#define NO_BASIC_PRODUCT_LIST
#endif // NO_BASIC_PRODUCT_LIST
@ -421,7 +421,7 @@
* Removes the -V option from vlmcsd and vlmcs that displays the version information
*/
//#define NO_VERSION_INFORMATION
//#define NO_VERSION_INFORMATION
#endif // NO_VERSION_INFORMATION
@ -434,7 +434,7 @@
* option in the vlmcs client. Disables ini file directive LogVerbose.
*/
//#define NO_VERBOSE_LOG
//#define NO_VERBOSE_LOG
#endif // NO_VERBOSE_LOG
@ -448,7 +448,7 @@
* Implies NO_VERBOSE_LOG, NO_EXTENDED_PRODUCT_LIST and NO_BASIC_PRODUCT_LIST.
*/
//#define NO_LOG
//#define NO_LOG
#endif // NO_LOG
@ -457,26 +457,39 @@
#ifndef NO_STRICT_MODES
/*
* Disables the product whitelisting features. Removes -K0, -K1, -K2 and -K3 from vlmcsd
* command line options and WhitelistingLevel from INI file parameters. vlmcsd always behaves
* as if it was started with -K0.
* Disables emulator detection protection. Removes -M0, -M1, -E0, -E1, -K0, -K1, -K2 and -K3 from
* vlmcsd command line options and WhitelistingLevel from INI file parameters. vlmcsd always behaves
* as if it was started with -K0, -M0.
*/
//#define NO_STRICT_MODES
//#define NO_STRICT_MODES
#endif // NO_STRICT_MODES
#ifndef NO_RANDOM_EPID
#ifndef NO_CLIENT_LIST
/*
* Disables the ability to generate random ePIDs. Useful if you managed to grab ePID/HWID from a
* real KMS server and want to use these. Removes -r from the vlmcsd command line and the ini
* file directive RandomizationLevel (The randomization level will be harcoded to 0).
* Disables the ability to maintain a list of Client Machine IDs (CMIDs). Removes -M0, -M1, -E0 and -E1
* from vlmcsd command line options.
*/
//#define NO_RANDOM_EPID
//#define NO_CLIENT_LIST
#endif // !NO_CLIENT_LIST
#ifndef NO_RANDOM_EPID
/*
* Disables the ability to generate random ePIDs. Useful if you managed to grab ePID/HWID from a
* real KMS server and want to use these. Removes -r from the vlmcsd command line and the ini
* file directive RandomizationLevel (The randomization level will be harcoded to 0).
*/
//#define NO_RANDOM_EPID
#endif // NO_RANDOM_EPID
@ -488,7 +501,7 @@
* Disables the ability to use a configuration file (aka ini file). Removes -i from the command line.
*/
//#define NO_INI_FILE
//#define NO_INI_FILE
#endif // NO_INI_FILE
@ -502,7 +515,7 @@
* the use of -p from the command line and PidFile from the ini file.
*/
//#define NO_PID_FILE
//#define NO_PID_FILE
#endif // NO_PID_FILE
@ -520,7 +533,7 @@
* Cygwin.
*/
//#define NO_USER_SWITCH
//#define NO_USER_SWITCH
#endif // NO_USER_SWITCH
@ -533,7 +546,7 @@
* access to the man files vlmcsd.8 and vlmcs.1
*/
//#define NO_HELP
//#define NO_HELP
#endif // NO_HELP
@ -547,7 +560,7 @@
* -A and -R from the command line as well as ActivationInterval and RenewalInterval in the ini file.
*/
//#define NO_CUSTOM_INTERVALS
//#define NO_CUSTOM_INTERVALS
#endif // NO_CUSTOM_INTERVALS
@ -560,7 +573,7 @@
* Removes -o from the command line.
*/
//#define NO_PRIVATE_IP_DETECT
//#define NO_PRIVATE_IP_DETECT
#endif // NO_PRIVATE_IP_DETECT
@ -574,7 +587,7 @@
* command line. Socket setup is the job of your superserver.
*/
//#define NO_SOCKETS
//#define NO_SOCKETS
#endif // NO_SOCKETS
@ -587,7 +600,7 @@
* Removes -0, -3, -w and -H from the vlmcsd command line.
*/
//#define NO_CL_PIDS
//#define NO_CL_PIDS
#endif // NO_CL_PIDS
@ -606,7 +619,7 @@
* and NO_LIMIT instead to disable use of the pthreads, shared memory and semaphores.
*/
//#define NO_LIMIT
//#define NO_LIMIT
#endif // NO_LIMIT
@ -626,7 +639,7 @@
* This option has no effect on native Windows since Posix signaling is not supported. It can be used with Cygwin.
*/
//#define NO_SIGHUP
//#define NO_SIGHUP
#endif // NO_SIGHUP
@ -640,7 +653,7 @@
* smaller binaries but makes emulator detection easier.
*/
//#define SIMPLE_RPC
//#define SIMPLE_RPC
#endif // !SIMPLE_RPC
@ -652,7 +665,7 @@
* It still supports IPv4 and IPv6.
*/
//#define SIMPLE_SOCKETS
//#define SIMPLE_SOCKETS
#endif // SIMPLE_SOCKETS

View File

@ -390,3 +390,36 @@ __pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument)
return FALSE;
}
#if __ANDROID__ && !defined(USE_THREADS) // Bionic does not wrap these syscalls (intentionally because Google fears, developers don't know how to use it)
#ifdef __NR_shmget
int shmget(key_t key, size_t size, int shmflg)
{
return syscall(__NR_shmget, key, size, shmflg);
}
#endif // __NR_shmget
#ifdef __NR_shmat
void *shmat(int shmid, const void *shmaddr, int shmflg)
{
return (void *)syscall(__NR_shmat, shmid, shmaddr, shmflg);
}
#endif // __NR_shmat
#ifdef __NR_shmdt
int shmdt(const void *shmaddr)
{
return syscall(__NR_shmdt, shmaddr);
}
#endif // __NR_shmdt
#ifdef __NR_shmctl
int shmctl(int shmid, int cmd, /*struct shmid_ds*/void *buf)
{
return syscall(__NR_shmctl, shmid, cmd, buf);
}
#endif // __NR_shmctl
#endif // __ANDROID__ && !defined(USE_THREADS)

View File

@ -9,6 +9,10 @@
#include <stdint.h>
#include "types.h"
#if __ANDROID__
#include <sys/syscall.h>
#endif // __ANDROID__
#define GUID_LE 0
#define GUID_BE 1
#define GUID_SWAP 2
@ -31,5 +35,11 @@ void hex2bin(BYTE *const bin, const char *hex, const size_t maxbin);
__pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument);
__pure int IsEqualGuidLE(const GUID *const restrict first, const GUID *const restrict second);
#if __ANDROID__ && !defined(USE_THREADS) // Bionic does not wrap these syscalls (intentionally because Google fears, developers don't know how to use it)
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, /*struct shmid_ds*/void *buf);
#endif // __ANDROID__ && !defined(USE_THREADS)
#endif // HELPERS_H

198
src/kms.c
View File

@ -13,8 +13,12 @@
#include <ctype.h>
#include <time.h>
#if !defined(_WIN32)
#if !__ANDROID__
#include <sys/shm.h>
#endif // !__ANDROID__
#include <sys/socket.h>
#endif
#include <sys/ipc.h>
#endif // !defined(_WIN32)
#include "output.h"
#include "crypto.h"
@ -306,7 +310,6 @@ const KmsIdList ExtendedProductList[] = {
{ { 0xbb11badf, 0xd8aa, 0x470e, { 0x93, 0x11, 0x20, 0xea, 0xf8, 0x0f, 0xe5, 0xcc, } } /*bb11badf-d8aa-470e-9311-20eaf80fe5cc*/, LOGTEXT("Office Word 2016"), EPID_OFFICE2016, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
};
// necessary because other .c files cannot access _countof()
__pure ProdListIndex_t getExtendedProductListSize(void)
{
@ -425,6 +428,103 @@ const char* getProductNameLE(const GUID *const guid, const KmsIdList *const List
#endif
}
#ifndef NO_STRICT_MODES
#ifndef NO_CLIENT_LIST
static PClientList_t ClientLists;
static BYTE ZeroGuid[16] = { 0 };
#if !defined(_WIN32) && !defined(__CYGWIN__)
pthread_mutex_t* mutex;
#define mutex_size (((sizeof(pthread_mutex_t)+7)>>3)<<3)
#else
CRITICAL_SECTION* mutex;
#define mutex_size (((sizeof(CRITICAL_SECTION)+7)>>3)<<3)
#endif // _WIN32
#ifndef USE_THREADS
static int shmid_clients = -1;
#endif // USE_THREADS
#if !defined(_WIN32) && !defined(__CYGWIN__)
#define lock_client_lists() pthread_mutex_lock(mutex)
#define unlock_client_lists() pthread_mutex_unlock(mutex)
#define mutex_t pthread_mutex_t
#else
#define lock_client_lists() EnterCriticalSection(mutex)
#define unlock_client_lists() LeaveCriticalSection(mutex)
#define mutex_t CRITICAL_SECTION
#endif
void CleanUpClientLists()
{
# ifndef USE_THREADS
shmctl(shmid_clients, IPC_RMID, NULL);
# endif // !USE_THREADS
}
void InitializeClientLists()
{
int_fast8_t i;
int_fast16_t j;
# ifndef USE_THREADS
if (
(shmid_clients = shmget(IPC_PRIVATE, sizeof(ClientList_t) * _countof(AppList) + mutex_size, IPC_CREAT | 0600)) < 0 ||
(mutex = (mutex_t*)shmat(shmid_clients, NULL, 0)) == (mutex_t*)-1
)
{
int errno_save = errno;
printerrorf("Warning: CMID lists disabled. Could not create shared memory: %s\n", vlmcsd_strerror(errno_save));
if (shmid_clients >= 0) shmctl(shmid_clients, IPC_RMID, NULL);
MaintainClients = FALSE;
return;
}
ClientLists = (PClientList_t)((BYTE*)mutex + mutex_size);
# if __CYGWIN__
InitializeCriticalSection(mutex);
# else // !__CYGWIN__
pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(mutex, &mutex_attr);
# endif // !__CYGWIN__
# else // USE_THREADS
ClientLists = (PClientList_t)vlmcsd_malloc(sizeof(ClientList_t) * _countof(AppList));
mutex = (mutex_t*)vlmcsd_malloc(sizeof(mutex_t));
# if !_WIN32 && !__CYGWIN__
pthread_mutex_init(mutex, NULL);
# else //_WIN32 || __CYGWIN__
InitializeCriticalSection(mutex);
# endif //_WIN32 || __CYGWIN__
# endif // USE_THREADS
memset(ClientLists, 0, sizeof(ClientList_t) * _countof(AppList));
if (!StartEmpty)
{
ClientLists[APP_ID_WINDOWS].CurrentCount = 24; ClientLists[APP_ID_WINDOWS].MaxCount = 50;
ClientLists[APP_ID_OFFICE2010].CurrentCount = ClientLists[APP_ID_OFFICE2013].CurrentCount = 4;
ClientLists[APP_ID_OFFICE2010].MaxCount = ClientLists[APP_ID_OFFICE2013].MaxCount = 10;
for (i = 0; i < 3; i++)
{
for (j = 0; j < ClientLists[i].CurrentCount; j++)
{
get16RandomBytes(&ClientLists[i].Guid[j]);
}
}
}
}
#endif // NO_CLIENT_LIST
#endif // !NO_STRICT_MODES
#ifndef NO_RANDOM_EPID
// formats an int with a fixed number of digits with leading zeros (helper for ePID generation)
@ -738,17 +838,29 @@ static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseReq
ProdListIndex_t index;
getProductNameLE(&baseRequest->KMSID, ProductList, _countof(ProductList), &index);
DWORD minClients = LE32(baseRequest->N_Policy);
DWORD required_clients = minClients < 1 ? 1 : minClients << 1;
# ifndef NO_STRICT_MODES
if (required_clients > 2000)
{
# ifndef NO_LOG
logger("Rejecting request with more than 1000 minimum clients (0x8007000D)\n");
# endif
return 0x8007000D;
}
if (CheckClientTime)
{
time_t requestTime = (time_t)fileTimeToUnixTime(&baseRequest->ClientTime);
if (llabs(requestTime - time(NULL)) > 60 * 60 * 4)
{
# ifndef NO_LOG
logger("Client time differs more than 4 hours from system time.\n");
# endif // !NO_LOG
# ifndef NO_LOG
logger("Client time differs more than 4 hours from system time (0xC004F06C)\n");
# endif // !NO_LOG
return 0xC004F06C;
}
@ -762,7 +874,7 @@ static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseReq
if (IsEqualGuidLE(&ProductList[RetailAndBetaProducts[i]].guid, &baseRequest->KMSID))
{
# ifndef NO_LOG
logger("Refusing retail or beta product\n");
logger("Refusing retail or beta product (0xC004F042)\n");
# endif // !NO_LOG
return 0xC004F042;
@ -773,7 +885,7 @@ static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseReq
if ((WhitelistingLevel & 1) && index >= _countof(ProductList))
{
# ifndef NO_LOG
logger("Refusing unknown product\n");
logger("Refusing unknown product (0xC004F042)\n");
# endif // !NO_LOG
return 0xC004F042;
@ -802,16 +914,80 @@ static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseReq
}
# if !defined(NO_STRICT_MODES)
ProdListIndex_t appIndex = index >= _countof(AppList) ? _countof(AppList) - 1 : index;
if ((WhitelistingLevel & 1) && !IsEqualGuidLE(&AppList[appIndex].guid, &baseRequest->AppID))
{
# ifndef NO_LOG
logger("Refusing product with incorrect Application ID\n");
logger("Refusing product with incorrect Application ID (0xC004F042)\n");
# endif // NO_LOG
return 0xC004F042;
}
# ifndef NO_CLIENT_LIST
if (MaintainClients)
{
lock_client_lists();
int_fast16_t i;
int_fast8_t isKnownClient = FALSE;
if (required_clients > (DWORD)ClientLists[appIndex].MaxCount) ClientLists[appIndex].MaxCount = required_clients;
for (i = 0; i < ClientLists[appIndex].MaxCount; i++)
{
if (IsEqualGUID(&ClientLists[appIndex].Guid[i], &baseRequest->CMID))
{
isKnownClient = TRUE;
break;
}
}
if (isKnownClient)
{
baseResponse->Count = LE32(ClientLists[appIndex].CurrentCount);
}
else
{
for (i = 0; i < ClientLists[appIndex].MaxCount; i++)
{
if (IsEqualGUID(ZeroGuid, &ClientLists[appIndex].Guid[i]))
{
if (ClientLists[appIndex].CurrentCount >= MAX_CLIENTS)
{
# ifndef NO_LOG
logger("Rejecting more than 671 clients (0xC004D104)\n");
# endif // !NO_LOG
unlock_client_lists();
return 0xC004D104;
}
baseResponse->Count = LE32(++ClientLists[appIndex].CurrentCount);
memcpy(&ClientLists[appIndex].Guid[i], &baseRequest->CMID, sizeof(GUID));
break;
}
}
if (i >= ClientLists[appIndex].MaxCount)
{
memcpy(&ClientLists[appIndex].Guid[ClientLists[appIndex].CurrentPosition], &baseRequest->CMID, sizeof(GUID));
ClientLists[appIndex].CurrentPosition = (ClientLists[appIndex].CurrentPosition + 1) % (ClientLists[appIndex].MaxCount > MAX_CLIENTS ? MAX_CLIENTS : ClientLists[appIndex].MaxCount);
baseResponse->Count = LE32(ClientLists[appIndex].CurrentCount);
}
}
unlock_client_lists();
}
else
# endif // !NO_CLIENT_LIST
# endif // !defined(NO_STRICT_MODES)
{
DWORD minimum_answer_clients = index > 0 && index < 4 ? 10 : 50;
baseResponse->Count = LE32(required_clients > minimum_answer_clients ? required_clients : minimum_answer_clients);
//if (LE32(baseRequest->N_Policy) > LE32(baseResponse->Count)) baseResponse->Count = LE32(LE32(baseRequest->N_Policy) << 1);
}
getEpid(baseResponse, &EpidSource, index, hwId);
@ -820,15 +996,9 @@ static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseReq
memcpy(&baseResponse->CMID, &baseRequest->CMID, sizeof(GUID));
memcpy(&baseResponse->ClientTime, &baseRequest->ClientTime, sizeof(FILETIME));
DWORD required_clients = LE32(baseRequest->N_Policy) << 1;
DWORD minimum_answer_clients = index > 0 && index < 4 ? 10 : 50;
baseResponse->Count = LE32(required_clients > minimum_answer_clients ? required_clients : minimum_answer_clients);
baseResponse->VLActivationInterval = LE32(VLActivationInterval);
baseResponse->VLRenewalInterval = LE32(VLRenewalInterval);
if (LE32(baseRequest->N_Policy) > LE32(baseResponse->Count)) baseResponse->Count = LE32(LE32(baseRequest->N_Policy) << 1);
#ifndef NO_LOG
logResponse(baseResponse, hwId, EpidSource);
#endif // NO_LOG

View File

@ -54,6 +54,15 @@
#define ActivationInterval VLActivationInterval
#define RenewalInterval VLRenewalInterval
#define MAX_CLIENTS 671
typedef struct
{
GUID Guid[MAX_CLIENTS];
int_fast16_t CurrentCount;
int_fast16_t MaxCount;
int_fast16_t CurrentPosition;
} ClientList_t, *PClientList_t;
typedef struct {
VERSION_INFO;
@ -292,6 +301,11 @@ extern const KmsIdList ProductList[];
extern const KmsIdList AppList[];
extern const KmsIdList ExtendedProductList[];
#ifndef NO_STRICT_MODES
void InitializeClientLists();
void CleanUpClientLists();
#endif // !NO_STRICT_MODES
extern RequestCallback_t CreateResponseBase;
#ifdef _PEDANTIC

View File

@ -835,7 +835,7 @@ static void post_sem(void)
#if !defined(NO_LIMIT) && !__minix__
if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
{
semaphore_post(Semaphore);
semaphore_post(MaxTaskSemaphore);
}
#endif // !defined(NO_LIMIT) && !__minix__
}
@ -846,7 +846,7 @@ static void wait_sem(void)
#if !defined(NO_LIMIT) && !__minix__
if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
{
semaphore_wait(Semaphore);
semaphore_wait(MaxTaskSemaphore);
}
#endif // !defined(NO_LIMIT) && !__minix__
}

View File

@ -74,6 +74,7 @@ static void vlogger(const char *message, va_list args)
// so formatting the output can be concurrent
int len = (int)strlen(mbstr);
//# if !_MSC_VER
vlmcsd_vsnprintf(mbstr + len, sizeof(mbstr) - len, message, args);
//# else
// wvsprintf(mbstr + len, message, args);
@ -630,6 +631,10 @@ void printServerFlags()
" NO_STRICT_MODES"
# endif // NO_STRICT_MODES
# ifdef NO_CLIENT_LIST
" NO_CLIENT_LIST"
# endif // NO_CLIENT_LIST
# if (_WIN32 || __CYGWIN__) && (!defined(USE_MSRPC) || defined(SUPPORT_WINE))
" SUPPORT_WINE"
# endif // (_WIN32 || __CYGWIN__) && (!defined(USE_MSRPC) || defined(SUPPORT_WINE))

View File

@ -108,9 +108,9 @@ static void CheckRpcRequest(const RPC_REQUEST64 *const Request, const unsigned i
}
else
{
if (len > _Versions[kmsMajorVersion].RequestSize + requestSize)
if (len > _Versions[kmsMajorVersion - 4].RequestSize + requestSize)
logger("Warning: %u excess bytes in RPC request.\n",
len - _Versions[kmsMajorVersion].RequestSize
len - (_Versions[kmsMajorVersion - 4].RequestSize + requestSize)
);
}
@ -743,7 +743,7 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const KmsRequest, const
RPC_REQUEST64 *RpcRequest;
RPC_RESPONSE64 _Response;
int status;
int_fast8_t useNdr64 = UseClientRpcNDR64 && firstPacketSent;
int_fast8_t useNdr64 = RpcFlags.HasNDR64 && UseClientRpcNDR64 && firstPacketSent;
size_t size = sizeof(RPC_HEADER) + (useNdr64 ? sizeof(RPC_REQUEST64) : sizeof(RPC_REQUEST)) + requestSize;
size_t responseSize2;

View File

@ -21,6 +21,10 @@ char ErrorMessage[MESSAGE_BUFFER_SIZE];
#ifndef NO_STRICT_MODES
uint32_t WhitelistingLevel = 0;
int_fast8_t CheckClientTime = FALSE;
#ifndef NO_CLIENT_LIST
int_fast8_t MaintainClients = FALSE;
int_fast8_t StartEmpty = FALSE;
#endif // NO_CLIENT_LIST
#endif // !NO_STRICT_MODES
#ifndef USE_MSRPC
@ -95,9 +99,9 @@ int numsockets = 0;
#if !defined(NO_LIMIT) && !__minix__
#ifndef _WIN32 // Posix
sem_t *Semaphore;
sem_t *MaxTaskSemaphore;
#else // _WIN32
HANDLE Semaphore;
HANDLE MaxTaskSemaphore;
#endif // _WIN32
#endif // !defined(NO_LIMIT) && !__minix__

View File

@ -16,9 +16,9 @@
#include <pwd.h>
#include <grp.h>
#include <syslog.h>
#if (!defined(NO_LIMIT) || defined(USE_THREADS)) && !__minix__
#if !__minix__
#include <pthread.h>
#endif // (!defined(NO_LIMIT) || defined(USE_THREADS)) && !__minix__
#endif // !__minix__
#include <fcntl.h>
#include <sys/stat.h>
#if !defined(NO_LIMIT) && !__minix__
@ -104,6 +104,10 @@ extern int_fast8_t InetdMode;
#ifndef NO_STRICT_MODES
extern uint32_t WhitelistingLevel;
extern int_fast8_t CheckClientTime;
#ifndef NO_CLIENT_LIST
extern int_fast8_t MaintainClients;
extern int_fast8_t StartEmpty;
#endif // NO_CLIENT_LIST
#endif // !NO_STRICT_MODES
@ -162,9 +166,9 @@ extern int numsockets;
#if !defined(NO_LIMIT) && !__minix__
#ifndef _WIN32
extern sem_t *Semaphore;
extern sem_t *MaxTaskSemaphore;
#else // _WIN32
extern HANDLE Semaphore;
extern HANDLE MaxTaskSemaphore;
#endif // _WIN32
#endif // !defined(NO_LIMIT) && !__minix__

View File

@ -1,6 +1,10 @@
#ifndef __types_h
#define __types_h
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
@ -22,7 +26,12 @@
#define ANDROID_HELPER1(s) ANDROID_HELPER2(s)
#define ANDROID_HELPER2(s) #s
#if !defined(_WIN32) && !__CYGWIN__
#if !_WIN32 && !__CYGWIN__
#if !__minix__
#include <pthread.h>
#endif // !__minix__
#define __declspec(x) __attribute__((__visibility__("default")))
#endif
@ -45,6 +54,7 @@
#endif // __ANDROID__
#ifndef _WIN32
#include <unistd.h>
#include <netinet/in.h>
#endif // _WIN32
@ -64,9 +74,31 @@
#endif
#if !defined(NO_STRICT_MODES) && defined(NO_BASIC_PRODUCT_LIST)
#define NO_STRICT_MODES
#define NO_STRICT_MODES
#endif // !defined(NO_STRICT_MODES) && defined(NO_BASIC_PRODUCT_LIST)
//#if (__minix__ || defined(NO_SOCKETS)) && !defined(NO_STRICT_MODES)
//#define NO_STRICT_MODES
//#endif // __minix__ && !defined(NO_STRICT_MODES)
#if (defined(NO_STRICT_MODES) || defined(NO_SOCKETS)) && !defined(NO_CLIENT_LIST)
#define NO_CLIENT_LIST
#endif // defined(NO_STRICT_MODES) || defined(NO_SOCKETS) && !defined(NO_CLIENT_LIST)
#if !_WIN32 && !__CYGWIN__
#if !defined(_POSIX_THREADS) || (!defined(_POSIX_THREAD_PROCESS_SHARED) && !defined(USE_THREADS))
#ifndef NO_CLIENT_LIST
#define NO_CLIENT_LIST
#endif // !NO_CLIENT_LIST
#endif // !defined(_POSIX_THREADS) || (!defined(_POSIX_THREAD_PROCESS_SHARED) && !defined(USE_THREADS))
#if !defined(_POSIX_THREADS) && !defined(NO_LIMIT)
#define NO_LIMIT
#endif // !defined(POSIX_THREADS) && !defined(NO_LIMIT)
#endif // !_WIN32 && !__CYGWIN__
#ifndef alloca
#ifdef __GNUC__
#define alloca(x) __builtin_alloca(x)

View File

@ -133,7 +133,7 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>USE_THREADS;_PEDANTIC</PreprocessorDefinitions>
<PreprocessorDefinitions>_PEDANTIC;USE_THREADS</PreprocessorDefinitions>
<ThreadSafeStatics>
</ThreadSafeStatics>
<ExceptionHandling>Disabled</ExceptionHandling>

View File

@ -42,9 +42,7 @@
#include <sys/ipc.h>
#if !__ANDROID__
#include <sys/shm.h>
#else // __ANDROID__
#include <sys/syscall.h>
#endif // __ANDROID__
#endif // !__ANDROID__
#endif // !defined(NO_LIMIT) && !__minix__
#include <sys/wait.h>
@ -69,7 +67,9 @@
#endif
#include "vlmcsd.h"
// ReSharper disable CppUnusedIncludeDirective
#include "endian.h"
// ReSharper restore CppUnusedIncludeDirective
#include "shared_globals.h"
#include "output.h"
#ifndef USE_MSRPC
@ -80,8 +80,7 @@
#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:SseDdVvqkZ";
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:SseDdVvqkZ";
#if !defined(NO_SOCKETS) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
static uint_fast8_t maxsockets = 0;
@ -119,6 +118,10 @@ static IniFileParameter_t IniFileParameterList[] =
# ifndef NO_STRICT_MODES
{ "WhiteListingLevel", INI_PARAM_WHITELISTING_LEVEL },
{ "CheckClientTime", INI_PARAM_CHECK_CLIENT_TIME },
# ifndef NO_CLIENT_LIST
{ "StartEmpty", INI_PARAM_START_EMPTY },
{ "MaintainClients", INI_PARAM_MAINTAIN_CLIENTS },
# endif // NO_CLIENT_LIST
# endif // NO_STRICT_MODES
# ifndef NO_RANDOM_EPID
{ "RandomizationLevel", INI_PARAM_RANDOMIZATION_LEVEL },
@ -180,37 +183,6 @@ static IniFileParameter_t IniFileParameterList[] =
static int shmid = -1;
#endif
#if __ANDROID__ && !defined(USE_THREADS) // Bionic does not wrap these syscalls (willingly because Google fears, developers don't know how to use it)
#ifdef __NR_shmget
static int shmget(key_t key, size_t size, int shmflg)
{
return syscall(__NR_shmget, key, size, shmflg);
}
#endif // __NR_shmget
#ifdef __NR_shmat
static void *shmat(int shmid, const void *shmaddr, int shmflg)
{
return (void *)syscall(__NR_shmat, shmid, shmaddr, shmflg);
}
#endif // __NR_shmat
#ifdef __NR_shmdt
static int shmdt(const void *shmaddr)
{
return syscall(__NR_shmdt, shmaddr);
}
#endif // __NR_shmdt
#ifdef __NR_shmctl
static int shmctl(int shmid, int cmd, /*struct shmid_ds*/void *buf)
{
return syscall(__NR_shmctl, shmid, cmd, buf);
}
#endif // __NR_shmctl
#endif // __ANDROID__ && !defined(USE_THREADS)
#endif // !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
@ -341,6 +313,10 @@ static __noreturn void usage()
# ifndef NO_STRICT_MODES
" -K 0|1|2|3\t\tset whitelisting level for KMS IDs (default -K0)\n"
" -c0, -c1\t\tdisable/enable client time checking (default -c0)\n"
# ifndef NO_CLIENT_LIST
" -M0, -M1\t\tdisable/enable maintaining clients (default -M0)\n"
" -E0, -E1\t\tdisable/enable start with empty client list (default -E0, ignored if -M0)\n"
# endif // !NO_CLIENT_LIST
# endif // !NO_STRICT_MODES
# ifndef USE_MSRPC
# if !defined(NO_TIMEOUT) && !__minix__
@ -674,7 +650,7 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
# endif // NO_PID_FILE
#ifndef NO_STRICT_MODES
# ifndef NO_STRICT_MODES
case INI_PARAM_WHITELISTING_LEVEL:
success = getIniFileArgumentInt(&WhitelistingLevel, iniarg, 0, 3);
@ -684,7 +660,17 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
success = getIniFileArgumentBool(&CheckClientTime, iniarg);
break;
#endif // !NO_STRICT_MODES
# ifndef NO_CLIENT_LIST
case INI_PARAM_MAINTAIN_CLIENTS:
success = getIniFileArgumentBool(&MaintainClients, iniarg);
break;
case INI_PARAM_START_EMPTY:
success = getIniFileArgumentBool(&StartEmpty, iniarg);
break;
# endif // NO_CLIENT_LIST
# endif // !NO_STRICT_MODES
# ifndef NO_LOG
@ -1286,6 +1272,18 @@ static void parseGeneralArguments() {
ignoreIniFileParameter(INI_PARAM_CHECK_CLIENT_TIME);
break;
# ifndef NO_CLIENT_LIST
case 'E':
if (!getArgumentBool(&StartEmpty, optarg)) usage();
ignoreIniFileParameter(INI_PARAM_START_EMPTY);
break;
case 'M':
if (!getArgumentBool(&MaintainClients, optarg)) usage();
ignoreIniFileParameter(INI_PARAM_MAINTAIN_CLIENTS);
break;
# endif // !NO_CLIENT_LIST
# endif // !NO_STRICT_MODES
case 'D':
@ -1458,6 +1456,10 @@ void cleanup()
{
if (!InetdMode)
{
# ifndef NO_CLIENT_LIST
if (MaintainClients) CleanUpClientLists();
# endif // !NO_CLIENT_LIST
# ifndef NO_PID_FILE
if (fn_pid) vlmcsd_unlink(fn_pid);
# endif // NO_PID_FILE
@ -1468,7 +1470,7 @@ void cleanup()
# if !defined(USE_THREADS) && !defined(CYGWIN)
if (shmid >= 0)
{
if (Semaphore != (sem_t*)-1) shmdt(Semaphore);
if (MaxTaskSemaphore != (sem_t*)-1) shmdt(MaxTaskSemaphore);
shmctl(shmid, IPC_RMID, NULL);
}
# endif // !defined(USE_THREADS) && !defined(CYGWIN)
@ -1520,18 +1522,18 @@ static void allocateSemaphore(void)
# if !defined(USE_THREADS) && !defined(CYGWIN)
if ((Semaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED) // fails on many systems
if ((MaxTaskSemaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED) // fails on many systems
{
// We didn't get a named Semaphore (/dev/shm on Linux) so let's try our own shared page
if (
(shmid = shmget(IPC_PRIVATE, sizeof(sem_t), IPC_CREAT | 0600)) < 0 ||
(Semaphore = (sem_t*)shmat(shmid, NULL, 0)) == (sem_t*)-1 ||
sem_init(Semaphore, 1, MaxTasks) < 0
(MaxTaskSemaphore = (sem_t*)shmat(shmid, NULL, 0)) == (sem_t*)-1 ||
sem_init(MaxTaskSemaphore, 1, MaxTasks) < 0
)
{
int errno_save = errno;
if (Semaphore != (sem_t*)-1) shmdt(Semaphore);
if (MaxTaskSemaphore != (sem_t*)-1) shmdt(MaxTaskSemaphore);
if (shmid >= 0) shmctl(shmid, IPC_RMID, NULL);
printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(errno_save));
MaxTasks = SEM_VALUE_MAX;
@ -1540,13 +1542,13 @@ static void allocateSemaphore(void)
# else // THREADS or CYGWIN
Semaphore = (sem_t*)vlmcsd_malloc(sizeof(sem_t));
MaxTaskSemaphore = (sem_t*)vlmcsd_malloc(sizeof(sem_t));
if (sem_init(Semaphore, sharemode, MaxTasks) < 0) // sem_init is not implemented on Darwin (returns ENOSYS)
if (sem_init(MaxTaskSemaphore, sharemode, MaxTasks) < 0) // sem_init is not implemented on Darwin (returns ENOSYS)
{
free(Semaphore);
free(MaxTaskSemaphore);
if ((Semaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED)
if ((MaxTaskSemaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED)
{
printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(errno));
MaxTasks = SEM_VALUE_MAX;
@ -1557,7 +1559,7 @@ static void allocateSemaphore(void)
# else // _WIN32
if (!((Semaphore = CreateSemaphoreA(NULL, MaxTasks, MaxTasks, NULL))))
if (!((MaxTaskSemaphore = CreateSemaphoreA(NULL, MaxTasks, MaxTasks, NULL))))
{
printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(GetLastError()));
MaxTasks = SEM_VALUE_MAX;
@ -1687,9 +1689,9 @@ int newmain()
# ifndef NO_LOG
// Initialize the Critical Section for proper logging
# if _WIN32
# if _WIN32 || __CYGWIN__
InitializeCriticalSection(&logmutex);
# endif // _WIN32
# endif // _WIN32 || __CYGWIN__
# endif // NO_LOG
# endif // USE_THREADS
@ -1729,13 +1731,16 @@ int newmain()
if (S_ISSOCK(statbuf.st_mode))
{
InetdMode = 1;
# ifndef NO_CLIENT_LIST
MaintainClients = FALSE;
# endif // !NO_CLIENT_LIST
nodaemon = 1;
# ifndef SIMPLE_SOCKETS
maxsockets = 0;
# endif // SIMPLE_SOCKETS
# endif // !SIMPLE_SOCKETS
# ifndef NO_LOG
logstdout = 0;
# endif // NO_LOG
# endif // !NO_LOG
}
# endif // !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
@ -1751,6 +1756,10 @@ int newmain()
# endif // NO_INI_FILE
# ifndef NO_CLIENT_LIST
if (MaintainClients) InitializeClientLists();
# endif // !NO_CLIENT_LIST
# if defined(USE_MSRPC) && !defined(NO_PRIVATE_IP_DETECT)
if (PublicIPProtectionLevel)
{

View File

@ -54,6 +54,8 @@ int server_main(int argc, CARGV argv);
#define INI_PARAM_OFFICE2016 23
#define INI_PARAM_WHITELISTING_LEVEL 24
#define INI_PARAM_CHECK_CLIENT_TIME 25
#define INI_PARAM_MAINTAIN_CLIENTS 26
#define INI_PARAM_START_EMPTY 27
#define INI_FILE_PASS_1 1
#define INI_FILE_PASS_2 2