mirror of
				https://github.com/Wind4/vlmcsd.git
				synced 2025-11-04 11:52:16 +01:00 
			
		
		
		
	vlmcsd-1113-2020-03-28-Hotbird64
This commit is contained in:
		@@ -6,7 +6,7 @@
 | 
			
		||||
#include "endian.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)  \
 | 
			
		||||
	&& defined(BS16) && defined(BS32) && defined(BS64)
 | 
			
		||||
	&& defined(BS16) && defined(BS32) && defined(BS64) && !defined(NO_COMPILER_UAA)
 | 
			
		||||
 | 
			
		||||
#else // ! defined(__BYTE_ORDER)
 | 
			
		||||
 | 
			
		||||
@@ -136,8 +136,12 @@ unsigned short GET_UAA16LE(void *p, unsigned int i)
 | 
			
		||||
		(unsigned short)_p[ 0 ] |
 | 
			
		||||
		(unsigned short)_p[ 1 ] << 8;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)  \
 | 
			
		||||
	&& defined(BS16) && defined(BS32) && defined(BS64)
 | 
			
		||||
#else
 | 
			
		||||
unsigned short BE16(unsigned short x)
 | 
			
		||||
{
 | 
			
		||||
	return GET_UAA16BE(&x, 0);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										88
									
								
								src/endian.h
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								src/endian.h
									
									
									
									
									
								
							@@ -9,17 +9,17 @@
 | 
			
		||||
//
 | 
			
		||||
// Unaligned access
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if !defined(NO_COMPILER_UAA)
 | 
			
		||||
#define UAA16(p, i) (((PACKED16*)p)->val[i])
 | 
			
		||||
#define UAA32(p, i) (((PACKED32*)p)->val[i])
 | 
			
		||||
#define UAA64(p, i) (((PACKED64*)p)->val[i])
 | 
			
		||||
 | 
			
		||||
#define UA64(p)  UAA64(p, 0)
 | 
			
		||||
#define UA32(p)  UAA32(p, 0)
 | 
			
		||||
#define UA16(p)  UAA16(p, 0)
 | 
			
		||||
#endif 
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//Byteswap: Use compiler support if available
 | 
			
		||||
//
 | 
			
		||||
#ifndef NO_COMPILER_UAA
 | 
			
		||||
#ifdef __has_builtin // Clang supports this
 | 
			
		||||
 | 
			
		||||
#if __has_builtin(__builtin_bswap16)
 | 
			
		||||
@@ -56,6 +56,7 @@
 | 
			
		||||
#endif // GNU C > 4.7
 | 
			
		||||
#endif // __GNUC__ > 4
 | 
			
		||||
#endif // __GNUC__
 | 
			
		||||
#endif // NO_COMPILER_UAA
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Byteorder
 | 
			
		||||
@@ -198,6 +199,10 @@
 | 
			
		||||
#define __BE64(x)  BS64(x)
 | 
			
		||||
#define __LE64(x)  (x)
 | 
			
		||||
 | 
			
		||||
#define PUT_UA16(p, v) PUT_UA16LE(p, v)
 | 
			
		||||
#define PUT_UA32(p, v) PUT_UA32LE(p, v)
 | 
			
		||||
#define PUT_UA64(p, v) PUT_UA64LE(p, v)
 | 
			
		||||
 | 
			
		||||
#else // __BYTE_ORDER == __BIG_ENDIAN
 | 
			
		||||
 | 
			
		||||
#define __BE16(x)  (x)
 | 
			
		||||
@@ -207,8 +212,38 @@
 | 
			
		||||
#define __BE64(x)  (x)
 | 
			
		||||
#define __LE64(x)  BS64(x)
 | 
			
		||||
 | 
			
		||||
#define PUT_UA16(p, v) PUT_UA16BE(p, v)
 | 
			
		||||
#define PUT_UA32(p, v) PUT_UA32BE(p, v)
 | 
			
		||||
#define PUT_UA64(p, v) PUT_UA64BE(p, v)
 | 
			
		||||
 | 
			
		||||
#endif // __BYTE_ORDER
 | 
			
		||||
 | 
			
		||||
#define BE16(x)  __BE16(x)
 | 
			
		||||
#define LE16(x)  __LE16(x)
 | 
			
		||||
#define BE32(x)  __BE32(x)
 | 
			
		||||
#define LE32(x)  __LE32(x)
 | 
			
		||||
#define BE64(x)  __BE64(x)
 | 
			
		||||
#define LE64(x)  __LE64(x)
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
extern unsigned short BE16(unsigned short x);
 | 
			
		||||
 | 
			
		||||
extern unsigned short LE16(unsigned short x);
 | 
			
		||||
 | 
			
		||||
extern unsigned int BE32(unsigned int x);
 | 
			
		||||
 | 
			
		||||
extern unsigned int LE32(unsigned int x);
 | 
			
		||||
 | 
			
		||||
extern unsigned long long BE64(unsigned long long x);
 | 
			
		||||
 | 
			
		||||
extern unsigned long long LE64(unsigned long long x);
 | 
			
		||||
 | 
			
		||||
#endif // defined(__BYTE_ORDER)
 | 
			
		||||
 | 
			
		||||
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)  \
 | 
			
		||||
	&& defined(BS16) && defined(BS32) && defined(BS64) &&!defined(NO_COMPILER_UAA)
 | 
			
		||||
 | 
			
		||||
#define PUT_UAA64BE(p, v, i)  ( UAA64(p, i) = __BE64(v) )
 | 
			
		||||
#define PUT_UAA32BE(p, v, i)  ( UAA32(p, i) = __BE32(v) )
 | 
			
		||||
#define PUT_UAA16BE(p, v, i)  ( UAA16(p, i) = __BE16(v) )
 | 
			
		||||
@@ -225,57 +260,38 @@
 | 
			
		||||
#define GET_UAA32LE(p, i)  __LE32(UAA32(p, i))
 | 
			
		||||
#define GET_UAA16LE(p, i)  __LE16(UAA16(p, i))
 | 
			
		||||
 | 
			
		||||
#define BE16(x)  __BE16(x)
 | 
			
		||||
#define LE16(x)  __LE16(x)
 | 
			
		||||
#define BE32(x)  __BE32(x)
 | 
			
		||||
#define LE32(x)  __LE32(x)
 | 
			
		||||
#define BE64(x)  __BE64(x)
 | 
			
		||||
#define LE64(x)  __LE64(x)
 | 
			
		||||
 | 
			
		||||
#else // ! defined(__BYTE_ORDER)
 | 
			
		||||
 | 
			
		||||
extern void PUT_UAA64BE(void *p, unsigned long long v, unsigned int i);
 | 
			
		||||
extern void PUT_UAA64BE(void* p, unsigned long long v, unsigned int i);
 | 
			
		||||
 | 
			
		||||
extern void PUT_UAA32BE(void *p, unsigned int v, unsigned int i);
 | 
			
		||||
extern void PUT_UAA32BE(void* p, unsigned int v, unsigned int i);
 | 
			
		||||
 | 
			
		||||
extern void PUT_UAA16BE(void *p, unsigned short v, unsigned int i);
 | 
			
		||||
extern void PUT_UAA16BE(void* p, unsigned short v, unsigned int i);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern void PUT_UAA64LE(void *p, unsigned long long v, unsigned int i);
 | 
			
		||||
extern void PUT_UAA64LE(void* p, unsigned long long v, unsigned int i);
 | 
			
		||||
 | 
			
		||||
extern void PUT_UAA32LE(void *p, unsigned int v, unsigned int i);
 | 
			
		||||
extern void PUT_UAA32LE(void* p, unsigned int v, unsigned int i);
 | 
			
		||||
 | 
			
		||||
extern void PUT_UAA16LE(void *p, unsigned short v, unsigned int i);
 | 
			
		||||
extern void PUT_UAA16LE(void* p, unsigned short v, unsigned int i);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern unsigned long long GET_UAA64BE(void *p, unsigned int i);
 | 
			
		||||
extern unsigned long long GET_UAA64BE(void* p, unsigned int i);
 | 
			
		||||
 | 
			
		||||
extern unsigned int GET_UAA32BE(void *p, unsigned int i);
 | 
			
		||||
extern unsigned int GET_UAA32BE(void* p, unsigned int i);
 | 
			
		||||
 | 
			
		||||
extern unsigned short GET_UAA16BE(void *p, unsigned int i);
 | 
			
		||||
extern unsigned short GET_UAA16BE(void* p, unsigned int i);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern unsigned long long GET_UAA64LE(void *p, unsigned int i);
 | 
			
		||||
extern unsigned long long GET_UAA64LE(void* p, unsigned int i);
 | 
			
		||||
 | 
			
		||||
extern unsigned int GET_UAA32LE(void *p, unsigned int i);
 | 
			
		||||
extern unsigned int GET_UAA32LE(void* p, unsigned int i);
 | 
			
		||||
 | 
			
		||||
extern unsigned short GET_UAA16LE(void *p, unsigned int i);
 | 
			
		||||
extern unsigned short GET_UAA16LE(void* p, unsigned int i);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern unsigned short BE16(unsigned short x);
 | 
			
		||||
 | 
			
		||||
extern unsigned short LE16(unsigned short x);
 | 
			
		||||
 | 
			
		||||
extern unsigned int BE32(unsigned int x);
 | 
			
		||||
 | 
			
		||||
extern unsigned int LE32(unsigned int x);
 | 
			
		||||
 | 
			
		||||
extern unsigned long long BE64(unsigned long long x);
 | 
			
		||||
 | 
			
		||||
extern unsigned long long LE64(unsigned long long x);
 | 
			
		||||
 | 
			
		||||
#endif // defined(__BYTE_ORDER)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define PUT_UA64BE(p, v)  PUT_UAA64BE(p, v, 0)
 | 
			
		||||
#define PUT_UA32BE(p, v)  PUT_UAA32BE(p, v, 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -434,14 +434,14 @@ __pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument)
 | 
			
		||||
#ifndef NO_EXTERNAL_DATA
 | 
			
		||||
__noreturn static void dataFileReadError()
 | 
			
		||||
{
 | 
			
		||||
	int error = errno;
 | 
			
		||||
	const int error = errno;
 | 
			
		||||
	errorout("Fatal: Could not read %s: %s\n", fn_data, strerror(error));
 | 
			
		||||
	exit(error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__noreturn static void dataFileFormatError()
 | 
			
		||||
{
 | 
			
		||||
	errorout("Fatal: %s is not a KMS data file\n", fn_data);
 | 
			
		||||
	errorout("Fatal: %s is not a KMS data file version 2.x\n", fn_data);
 | 
			
		||||
	exit(VLMCSD_EINVAL);
 | 
			
		||||
}
 | 
			
		||||
#endif // NO_EXTERNAL_DATA
 | 
			
		||||
@@ -526,7 +526,7 @@ static void getDefaultDataFile()
 | 
			
		||||
	getExeName();
 | 
			
		||||
	strncpy(fileName, fn_exe, MAX_PATH);
 | 
			
		||||
	PathRemoveFileSpec(fileName);
 | 
			
		||||
	strncat(fileName, "\\vlmcsd.kmd", MAX_PATH);
 | 
			
		||||
	strncat(fileName, "\\vlmcsd.kmd", MAX_PATH - 11);
 | 
			
		||||
	fn_data = vlmcsd_strdup(fileName);
 | 
			
		||||
}
 | 
			
		||||
#else // !_WIN32
 | 
			
		||||
@@ -588,12 +588,12 @@ void loadKmsData()
 | 
			
		||||
			KmsData = (PVlmcsdHeader_t)vlmcsd_malloc(size);
 | 
			
		||||
			if (fseek(file, 0, SEEK_SET)) dataFileReadError();
 | 
			
		||||
 | 
			
		||||
			size_t bytesRead = fread(KmsData, 1, size, file);
 | 
			
		||||
			const size_t bytesRead = fread(KmsData, 1, size, file);
 | 
			
		||||
			if ((long)bytesRead != size) dataFileReadError();
 | 
			
		||||
			fclose(file);
 | 
			
		||||
 | 
			
		||||
#			if !defined(NO_LOG) && !defined(NO_SOCKETS)
 | 
			
		||||
			if (!InetdMode) logger("Read KMS data file version %u.%u %s\n", (unsigned int)KmsData->MajorVer, (unsigned int)KmsData->MinorVer, fn_data);
 | 
			
		||||
			if (!InetdMode) logger("Read KMS data file version %u.%u %s\n", (unsigned int)LE16(KmsData->MajorVer), (unsigned int)LE16(KmsData->MinorVer), fn_data);
 | 
			
		||||
#			endif // NO_LOG
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -610,6 +610,7 @@ void loadKmsData()
 | 
			
		||||
	KmsData->AppItemCount = LE32(KmsData->AppItemCount);
 | 
			
		||||
	KmsData->KmsItemCount = LE32(KmsData->KmsItemCount);
 | 
			
		||||
	KmsData->SkuItemCount = LE32(KmsData->SkuItemCount);
 | 
			
		||||
	KmsData->HostBuildCount = LE32(KmsData->HostBuildCount);
 | 
			
		||||
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
 | 
			
		||||
@@ -625,6 +626,7 @@ void loadKmsData()
 | 
			
		||||
	{
 | 
			
		||||
		PCsvlkData_t csvlkData = &KmsData->CsvlkData[i];
 | 
			
		||||
		csvlkData->EPid = (char*)KmsData + LE64(csvlkData->EPidOffset);
 | 
			
		||||
		csvlkData->ReleaseDate = LE64(csvlkData->ReleaseDate);
 | 
			
		||||
#		ifndef UNSAFE_DATA_LOAD
 | 
			
		||||
		if (csvlkData->EPid > (char*)KmsData + size) dataFileFormatError();
 | 
			
		||||
#		endif // UNSAFE_DATA_LOAD
 | 
			
		||||
@@ -636,12 +638,25 @@ void loadKmsData()
 | 
			
		||||
#		endif // NO_RANDOM_EPID
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < (uint32_t)KmsData->HostBuildCount; i++)
 | 
			
		||||
	{
 | 
			
		||||
		PHostBuild_t hostBuild = &KmsData->HostBuildList[i];
 | 
			
		||||
		hostBuild->BuildNumber = LE32(hostBuild->BuildNumber);
 | 
			
		||||
		hostBuild->Flags = LE32(hostBuild->Flags);
 | 
			
		||||
		hostBuild->PlatformId = LE32(hostBuild->PlatformId);
 | 
			
		||||
		hostBuild->ReleaseDate = LE64(hostBuild->ReleaseDate);
 | 
			
		||||
		hostBuild->DisplayName = (char*)KmsData + LE64(hostBuild->DisplayNameOffset);
 | 
			
		||||
#		ifndef UNSAFE_DATA_LOAD
 | 
			
		||||
		if (hostBuild->DisplayName > (char*)KmsData + size) dataFileFormatError();
 | 
			
		||||
#		endif // UNSAFE_DATA_LOAD
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const uint32_t totalItemCount = KmsData->AppItemCount + KmsData->KmsItemCount + KmsData->SkuItemCount;
 | 
			
		||||
 | 
			
		||||
#	ifndef NO_EXTERNAL_DATA
 | 
			
		||||
	if (
 | 
			
		||||
		memcmp(KmsData->Magic, "KMD", sizeof(KmsData->Magic)) ||
 | 
			
		||||
		KmsData->MajorVer != 1
 | 
			
		||||
		KmsData->MajorVer != 2
 | 
			
		||||
#		ifndef UNSAFE_DATA_LOAD
 | 
			
		||||
		||
 | 
			
		||||
		sizeof(VlmcsdHeader_t) + totalItemCount * sizeof(VlmcsdData_t) >= ((uint64_t)size)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										209
									
								
								src/kms.c
									
									
									
									
									
								
							
							
						
						
									
										209
									
								
								src/kms.c
									
									
									
									
									
								
							@@ -57,16 +57,23 @@ int32_t getProductIndex(const GUID* guid, const PVlmcsdData_t list, const int32_
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (name) *name = "Unknown";
 | 
			
		||||
	if (ePid) *ePid = KmsData->CsvlkData[EPID_INDEX_WINDOWS].EPid;
 | 
			
		||||
	if (name) *name = (char*)"Unknown";
 | 
			
		||||
	if (ePid) *ePid = KmsData->CsvlkData->EPid;
 | 
			
		||||
	return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
 | 
			
		||||
const char* getNextString(const char* s)
 | 
			
		||||
{
 | 
			
		||||
	return s + strlen(s) + 1;
 | 
			
		||||
}
 | 
			
		||||
#endif //!defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
 | 
			
		||||
 | 
			
		||||
#endif // IS_LIBRARY
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef NO_RANDOM_EPID
 | 
			
		||||
static const uint16_t HostBuilds[] = { 6002, 7601, 9200, 9600, 14393, 17763 };
 | 
			
		||||
//static const uint16_t HostBuilds[] = { 6002, 7601, 9200, 9600, 14393, 17763 };
 | 
			
		||||
 | 
			
		||||
// Valid language identifiers to be used in the ePID
 | 
			
		||||
static const uint16_t LcidList[] = {
 | 
			
		||||
@@ -80,14 +87,38 @@ static const uint16_t LcidList[] = {
 | 
			
		||||
	17418, 18442, 19466, 20490, 1089, 1053, 2077, 1114, 1097, 1092, 1098, 1054, 1074, 1058, 1056, 1091, 2115, 1066, 1106, 1076, 1077
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
uint16_t getPlatformId(uint16_t hostBuild)
 | 
			
		||||
int32_t getPlatformId(int32_t hostBuild)
 | 
			
		||||
{
 | 
			
		||||
	if (hostBuild < 9000) return 55041;
 | 
			
		||||
	if (hostBuild <= 9500) return 5426;
 | 
			
		||||
	if (hostBuild <= 10000) return 6401;
 | 
			
		||||
	return 3612;
 | 
			
		||||
	int32_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < KmsData->HostBuildCount; i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (KmsData->HostBuildList[i].BuildNumber <= hostBuild)
 | 
			
		||||
		{
 | 
			
		||||
			return KmsData->HostBuildList[i].PlatformId;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return KmsData->HostBuildList[KmsData->HostBuildCount - 1].PlatformId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
time_t getReleaseDate(int32_t hostBuild)
 | 
			
		||||
{
 | 
			
		||||
	int32_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = KmsData->HostBuildCount - 1; i >= 0; i--)
 | 
			
		||||
	{
 | 
			
		||||
		if (KmsData->HostBuildList[i].BuildNumber >= hostBuild)
 | 
			
		||||
		{
 | 
			
		||||
			return (time_t)KmsData->HostBuildList[i].ReleaseDate;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (time_t)KmsData->HostBuildList->ReleaseDate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef _PEDANTIC
 | 
			
		||||
uint16_t IsValidLcid(const uint16_t lcid)
 | 
			
		||||
{
 | 
			
		||||
@@ -102,13 +133,13 @@ uint16_t IsValidLcid(const uint16_t lcid)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint16_t IsValidHostBuild(const uint16_t hostBuild)
 | 
			
		||||
uint32_t IsValidHostBuild(const int32_t hostBuild)
 | 
			
		||||
{
 | 
			
		||||
	const uint16_t *hostOS;
 | 
			
		||||
	PHostBuild_t hostOS;
 | 
			
		||||
 | 
			
		||||
	for (hostOS = HostBuilds; hostOS < HostBuilds + vlmcsd_countof(HostBuilds); hostOS++)
 | 
			
		||||
	for (hostOS = KmsData->HostBuildList; hostOS < KmsData->HostBuildList + KmsData->HostBuildCount; hostOS++)
 | 
			
		||||
	{
 | 
			
		||||
		if (hostBuild == *hostOS) return hostBuild;
 | 
			
		||||
		if (hostBuild == hostOS->BuildNumber) return hostBuild;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
@@ -119,7 +150,7 @@ uint16_t IsValidHostBuild(const uint16_t hostBuild)
 | 
			
		||||
 | 
			
		||||
// Unix time is seconds from 1970-01-01. Should be 64 bits to avoid year 2038 overflow bug.
 | 
			
		||||
// FILETIME is 100 nanoseconds from 1601-01-01. Must be 64 bits.
 | 
			
		||||
void getUnixTimeAsFileTime(FILETIME *const ts)
 | 
			
		||||
void getUnixTimeAsFileTime(FILETIME* ts)
 | 
			
		||||
{
 | 
			
		||||
	const int64_t unixtime = (int64_t)time(NULL);
 | 
			
		||||
	int64_t *filetime = (int64_t*)ts;
 | 
			
		||||
@@ -127,7 +158,7 @@ void getUnixTimeAsFileTime(FILETIME *const ts)
 | 
			
		||||
	PUT_UA64LE(filetime, (unixtime + 11644473600LL) * 10000000LL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__pure int64_t fileTimeToUnixTime(const FILETIME *const ts)
 | 
			
		||||
__pure int64_t fileTimeToUnixTime(FILETIME* ts)
 | 
			
		||||
{
 | 
			
		||||
	return GET_UA64LE(ts) / 10000000LL - 11644473600LL;
 | 
			
		||||
}
 | 
			
		||||
@@ -255,19 +286,18 @@ static uint8_t getRandomServerType()
 | 
			
		||||
{
 | 
			
		||||
#	if defined(USE_MSRPC) || defined(SIMPLE_RPC)
 | 
			
		||||
 | 
			
		||||
	return rand() % vlmcsd_countof(HostBuilds);
 | 
			
		||||
	return rand() % KmsData->HostBuildCount;
 | 
			
		||||
 | 
			
		||||
#	else // !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
 | 
			
		||||
	if (!UseServerRpcBTFN)
 | 
			
		||||
	while (TRUE)
 | 
			
		||||
	{
 | 
			
		||||
		// This isn't possible at all, e.g. KMS host on XP
 | 
			
		||||
		return rand() % (int)vlmcsd_countof(HostBuilds);
 | 
			
		||||
		const uint32_t buildIndex = rand() % KmsData->HostBuildCount;
 | 
			
		||||
 | 
			
		||||
		if (!(KmsData->HostBuildList[buildIndex].Flags & UseNdr64) == !UseServerRpcNDR64)
 | 
			
		||||
		{
 | 
			
		||||
			return (uint8_t)buildIndex;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// return 9200/9600/14393/17763 if NDR64 is in use, otherwise 6002/7601
 | 
			
		||||
	if (UseServerRpcNDR64) return rand() % ((int)vlmcsd_countof(HostBuilds) - 2) + 2;
 | 
			
		||||
	return rand() % 2;
 | 
			
		||||
 | 
			
		||||
#	endif // !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -275,13 +305,13 @@ static uint8_t getRandomServerType()
 | 
			
		||||
/*
 | 
			
		||||
 * Generates a random ePID
 | 
			
		||||
 */
 | 
			
		||||
static void generateRandomPid(const int index, char *const szPid, int16_t lang, uint16_t hostBuild)
 | 
			
		||||
static void generateRandomPid(const int index, char *const szPid, int16_t lang, int32_t hostBuild)
 | 
			
		||||
{
 | 
			
		||||
	char numberBuffer[12];
 | 
			
		||||
 | 
			
		||||
	if (!hostBuild)
 | 
			
		||||
	{
 | 
			
		||||
		hostBuild = HostBuilds[getRandomServerType()];
 | 
			
		||||
		hostBuild = KmsData->HostBuildList[getRandomServerType()].BuildNumber;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -290,7 +320,7 @@ static void generateRandomPid(const int index, char *const szPid, int16_t lang,
 | 
			
		||||
 | 
			
		||||
	//if (index > 3) index = 0;
 | 
			
		||||
 | 
			
		||||
	const PCsvlkData_t csvlkData = &KmsData->CsvlkData[index];
 | 
			
		||||
	PCsvlkData_t csvlkData = &KmsData->CsvlkData[index];
 | 
			
		||||
	strcat(szPid, itoc(numberBuffer, csvlkData->GroupId, 5));
 | 
			
		||||
	strcat(szPid, "-");
 | 
			
		||||
 | 
			
		||||
@@ -307,7 +337,8 @@ static void generateRandomPid(const int index, char *const szPid, int16_t lang,
 | 
			
		||||
	strcat(szPid, itoc(numberBuffer, hostBuild, 0));
 | 
			
		||||
	strcat(szPid, ".0000-");
 | 
			
		||||
 | 
			
		||||
#	define minTime ((time_t)1538490811) /* Release Date Win 2019 */
 | 
			
		||||
	const time_t hostBuildReleaseDate = getReleaseDate(hostBuild);
 | 
			
		||||
	const time_t minTime = csvlkData->ReleaseDate < hostBuildReleaseDate ? hostBuildReleaseDate : csvlkData->ReleaseDate;
 | 
			
		||||
 | 
			
		||||
	time_t maxTime;
 | 
			
		||||
	time(&maxTime);
 | 
			
		||||
@@ -343,11 +374,33 @@ void randomPidInit()
 | 
			
		||||
 | 
			
		||||
		char Epid[PID_BUFFER_SIZE];
 | 
			
		||||
 | 
			
		||||
		if (!HostBuild)
 | 
			
		||||
		{
 | 
			
		||||
			uint8_t index;
 | 
			
		||||
 | 
			
		||||
#if defined(USE_MSRPC) || defined(SIMPLE_RPC)
 | 
			
		||||
			index = getRandomServerType();
 | 
			
		||||
#else // !(defined(USE_MSRPC) || defined(SIMPLE_RPC))
 | 
			
		||||
			if (IsNDR64Defined)
 | 
			
		||||
			{
 | 
			
		||||
				index = getRandomServerType();
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				index = (uint8_t)(rand() % KmsData->HostBuildCount);
 | 
			
		||||
				UseServerRpcNDR64 = !!(KmsData->HostBuildList[index].Flags & UseNdr64);
 | 
			
		||||
			}
 | 
			
		||||
#endif // !(defined(USE_MSRPC) || defined(SIMPLE_RPC))
 | 
			
		||||
 | 
			
		||||
			HostBuild = (uint16_t)KmsData->HostBuildList[index].BuildNumber;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		generateRandomPid(i, Epid, lang, HostBuild);
 | 
			
		||||
		KmsResponseParameters[i].Epid = (const char*)vlmcsd_strdup(Epid);
 | 
			
		||||
 | 
			
		||||
#ifndef NO_LOG
 | 
			
		||||
		KmsResponseParameters[i].EpidSource = "randomized at program start";
 | 
			
		||||
		KmsResponseParameters[i].IsRandom = TRUE;
 | 
			
		||||
#endif // NO_LOG
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -364,7 +417,7 @@ static int32_t getProductIndexFromAllLists(const GUID* guid, char** productName)
 | 
			
		||||
/*
 | 
			
		||||
 * Logs a Request
 | 
			
		||||
 */
 | 
			
		||||
static void logRequest(const REQUEST *const baseRequest)
 | 
			
		||||
static void logRequest(REQUEST* baseRequest)
 | 
			
		||||
{
 | 
			
		||||
#ifndef NO_VERBOSE_LOG
 | 
			
		||||
	if (logverbose)
 | 
			
		||||
@@ -376,7 +429,7 @@ static void logRequest(const REQUEST *const baseRequest)
 | 
			
		||||
#endif // NO_VERBOSE_LOG
 | 
			
		||||
 | 
			
		||||
	char *productName;
 | 
			
		||||
	char clientname[64];
 | 
			
		||||
	char clientName[64];
 | 
			
		||||
 | 
			
		||||
	int32_t index = getProductIndexFromAllLists(&baseRequest->ActID, &productName);
 | 
			
		||||
	if (index < 0) index = getProductIndexFromAllLists(&baseRequest->KMSID, &productName);
 | 
			
		||||
@@ -388,8 +441,8 @@ static void logRequest(const REQUEST *const baseRequest)
 | 
			
		||||
		uuid2StringLE(&baseRequest->ActID, productName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ucs2_to_utf8(baseRequest->WorkstationName, clientname, 64, 64);
 | 
			
		||||
	logger("KMS v%i.%i request from %s for %s\n", LE16(baseRequest->MajorVer), LE16(baseRequest->MinorVer), clientname, productName);
 | 
			
		||||
	ucs2_to_utf8(baseRequest->WorkstationName, clientName, 64, 64);
 | 
			
		||||
	logger("KMS v%i.%i request from %s for %s\n", LE16(baseRequest->MajorVer), LE16(baseRequest->MinorVer), clientName, productName);
 | 
			
		||||
}
 | 
			
		||||
#endif // NO_LOG
 | 
			
		||||
 | 
			
		||||
@@ -493,7 +546,7 @@ static void CheckRequest(const REQUEST *const Request)
 | 
			
		||||
/*
 | 
			
		||||
 * Logs the Response
 | 
			
		||||
 */
 | 
			
		||||
static void logResponse(const RESPONSE *const baseResponse, const BYTE *const hwId, const char *const EpidSource)
 | 
			
		||||
static void logResponse(RESPONSE* baseResponse, const BYTE *const hwId, const char *const EpidSource)
 | 
			
		||||
{
 | 
			
		||||
	char utf8pid[PID_BUFFER_SIZE * 3];
 | 
			
		||||
	ucs2_to_utf8(baseResponse->KmsPID, utf8pid, PID_BUFFER_SIZE, PID_BUFFER_SIZE * 3);
 | 
			
		||||
@@ -525,7 +578,7 @@ long long int llabs(long long int j);
 | 
			
		||||
 * Creates the unencrypted base response
 | 
			
		||||
 */
 | 
			
		||||
#ifndef IS_LIBRARY
 | 
			
		||||
static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr_unused)
 | 
			
		||||
static HRESULT __stdcall CreateResponseBaseCallback(REQUEST* baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr_unused)
 | 
			
		||||
{
 | 
			
		||||
	const char* EpidSource;
 | 
			
		||||
#ifndef NO_LOG
 | 
			
		||||
@@ -539,7 +592,7 @@ static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseReq
 | 
			
		||||
	const DWORD minClients = LE32(baseRequest->N_Policy);
 | 
			
		||||
	const DWORD required_clients = minClients < 1 ? 1 : minClients << 1;
 | 
			
		||||
 | 
			
		||||
	int32_t index = getProductIndex(&baseRequest->KMSID, KmsData->KmsItemList, KmsData->KmsItemCount, NULL, &ePid);
 | 
			
		||||
	const int32_t index = getProductIndex(&baseRequest->KMSID, KmsData->KmsItemList, KmsData->KmsItemCount, NULL, &ePid);
 | 
			
		||||
 | 
			
		||||
#	ifndef NO_STRICT_MODES
 | 
			
		||||
 | 
			
		||||
@@ -554,7 +607,7 @@ static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseReq
 | 
			
		||||
 | 
			
		||||
	if (CheckClientTime)
 | 
			
		||||
	{
 | 
			
		||||
		const time_t requestTime = (time_t)fileTimeToUnixTime(&baseRequest->ClientTime);
 | 
			
		||||
		time_t requestTime = (time_t)fileTimeToUnixTime(&baseRequest->ClientTime);
 | 
			
		||||
 | 
			
		||||
		if (llabs(requestTime - time(NULL)) > 60 * 60 * 4)
 | 
			
		||||
		{
 | 
			
		||||
@@ -705,21 +758,21 @@ void get16RandomBytes(void* ptr)
 | 
			
		||||
/*
 | 
			
		||||
 * Creates v4 response
 | 
			
		||||
 */
 | 
			
		||||
size_t CreateResponseV4(REQUEST_V4 *const request_v4, BYTE *const responseBuffer, const char* const ipstr)
 | 
			
		||||
size_t CreateResponseV4(REQUEST_V4 *const request_v4, BYTE *const responseBuffer, const char* const ipString)
 | 
			
		||||
{
 | 
			
		||||
	RESPONSE_V4* Response = (RESPONSE_V4*)responseBuffer;
 | 
			
		||||
	RESPONSE_V4* response = (RESPONSE_V4*)responseBuffer;
 | 
			
		||||
 | 
			
		||||
	HRESULT hResult;
 | 
			
		||||
	if (FAILED(hResult = CreateResponseBase(&request_v4->RequestBase, &Response->ResponseBase, NULL, ipstr))) return hResult;
 | 
			
		||||
	if (FAILED(hResult = CreateResponseBase(&request_v4->RequestBase, &response->ResponseBase, NULL, ipString))) return hResult;
 | 
			
		||||
 | 
			
		||||
	const DWORD pidSize = LE32(Response->ResponseBase.PIDSize);
 | 
			
		||||
	const DWORD pidSize = LE32(response->ResponseBase.PIDSize);
 | 
			
		||||
	BYTE* postEpidPtr = responseBuffer + V4_PRE_EPID_SIZE + pidSize;
 | 
			
		||||
	memmove(postEpidPtr, &Response->ResponseBase.CMID, V4_POST_EPID_SIZE);
 | 
			
		||||
	memmove(postEpidPtr, &response->ResponseBase.CMID, V4_POST_EPID_SIZE);
 | 
			
		||||
 | 
			
		||||
	const size_t encryptSize = V4_PRE_EPID_SIZE + V4_POST_EPID_SIZE + pidSize;
 | 
			
		||||
	AesCmacV4(responseBuffer, encryptSize, responseBuffer + encryptSize);
 | 
			
		||||
 | 
			
		||||
	return encryptSize + sizeof(Response->MAC);
 | 
			
		||||
	return encryptSize + sizeof(response->MAC);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -736,7 +789,7 @@ __pure static uint64_t TimestampInterval(void *ts)
 | 
			
		||||
/*
 | 
			
		||||
 * Creates the HMAC for v6
 | 
			
		||||
 */
 | 
			
		||||
static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptSize, int_fast8_t tolerance)
 | 
			
		||||
static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptSize, const int_fast8_t tolerance)
 | 
			
		||||
{
 | 
			
		||||
	BYTE hash[32];
 | 
			
		||||
	const uint8_t halfHashSize = sizeof(hash) >> 1;
 | 
			
		||||
@@ -746,7 +799,7 @@ static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptS
 | 
			
		||||
	FILETIME* ft = (FILETIME*)(responseEnd - V6_POST_EPID_SIZE + sizeof(((RESPONSE*)0)->CMID));
 | 
			
		||||
 | 
			
		||||
	// Generate a time slot that changes every 4.11 hours.
 | 
			
		||||
	// Request and repsonse time must match +/- 1 slot.
 | 
			
		||||
	// Request and response time must match +/- 1 slot.
 | 
			
		||||
	// When generating a response tolerance must be 0.
 | 
			
		||||
	// If verifying the hash, try tolerance -1, 0 and +1. One of them must match.
 | 
			
		||||
 | 
			
		||||
@@ -775,7 +828,7 @@ static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptS
 | 
			
		||||
/*
 | 
			
		||||
 * Creates v5 or v6 response
 | 
			
		||||
 */
 | 
			
		||||
size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuffer, const char* const ipstr)
 | 
			
		||||
size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuffer, const char* const ipString)
 | 
			
		||||
{
 | 
			
		||||
	// The response will be created in a fixed sized struct to
 | 
			
		||||
	// avoid unaligned access macros and packed structs on RISC systems
 | 
			
		||||
@@ -784,15 +837,15 @@ size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuf
 | 
			
		||||
	// The fixed sized struct with 64 WCHARs for the ePID will be converted
 | 
			
		||||
	// to a variable sized struct later and requires unaligned access macros.
 | 
			
		||||
 | 
			
		||||
	RESPONSE_V6* Response = (RESPONSE_V6*)responseBuffer;
 | 
			
		||||
	RESPONSE* baseResponse = &Response->ResponseBase;
 | 
			
		||||
	RESPONSE_V6* response = (RESPONSE_V6*)responseBuffer;
 | 
			
		||||
	RESPONSE* baseResponse = &response->ResponseBase;
 | 
			
		||||
 | 
			
		||||
#ifdef _DEBUG
 | 
			
		||||
	// ReSharper disable once CppEntityNeverUsed
 | 
			
		||||
	// ReSharper disable once CppDeclaratorNeverUsed
 | 
			
		||||
	RESPONSE_V6_DEBUG* xxx_unused = (RESPONSE_V6_DEBUG*)responseBuffer;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	static const BYTE DefaultHwid[8] = { HWID };
 | 
			
		||||
	static const BYTE DefaultHwId[8] = { HWID };
 | 
			
		||||
	const int_fast8_t v6 = LE16(request_v6->MajorVer) > 5;
 | 
			
		||||
	AesCtx aesCtx;
 | 
			
		||||
 | 
			
		||||
@@ -800,35 +853,35 @@ size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuf
 | 
			
		||||
	AesDecryptCbc(&aesCtx, NULL, request_v6->IV, V6_DECRYPT_SIZE);
 | 
			
		||||
 | 
			
		||||
	// get random salt and SHA256 it
 | 
			
		||||
	get16RandomBytes(Response->RandomXoredIVs);
 | 
			
		||||
	Sha256(Response->RandomXoredIVs, sizeof(Response->RandomXoredIVs), Response->Hash);
 | 
			
		||||
	get16RandomBytes(response->RandomXoredIVs);
 | 
			
		||||
	Sha256(response->RandomXoredIVs, sizeof(response->RandomXoredIVs), response->Hash);
 | 
			
		||||
 | 
			
		||||
	if (v6) // V6 specific stuff
 | 
			
		||||
	{
 | 
			
		||||
		// In v6 a random IV is generated
 | 
			
		||||
		Response->Version = request_v6->Version;
 | 
			
		||||
		get16RandomBytes(Response->IV);
 | 
			
		||||
		response->Version = request_v6->Version;
 | 
			
		||||
		get16RandomBytes(response->IV);
 | 
			
		||||
 | 
			
		||||
		// pre-fill with default HwId (not required for v5)
 | 
			
		||||
		memcpy(Response->HwId, DefaultHwid, sizeof(Response->HwId));
 | 
			
		||||
		memcpy(response->HwId, DefaultHwId, sizeof(response->HwId));
 | 
			
		||||
 | 
			
		||||
		// Just copy decrypted request IV (using Null IV) here. Note this is identical
 | 
			
		||||
		// to XORing non-decrypted request and reponse IVs
 | 
			
		||||
		memcpy(Response->XoredIVs, request_v6->IV, sizeof(Response->XoredIVs));
 | 
			
		||||
		// to XORing non-decrypted request and response IVs
 | 
			
		||||
		memcpy(response->XoredIVs, request_v6->IV, sizeof(response->XoredIVs));
 | 
			
		||||
	}
 | 
			
		||||
	else // V5 specific stuff
 | 
			
		||||
	{
 | 
			
		||||
		// In v5 IVs of request and response must be identical (MS client checks this)
 | 
			
		||||
		// The following memcpy copies Version and IVs at once
 | 
			
		||||
		memcpy(Response, request_v6, V6_UNENCRYPTED_SIZE);
 | 
			
		||||
		memcpy(response, request_v6, V6_UNENCRYPTED_SIZE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Xor Random bytes with decrypted request IV
 | 
			
		||||
	XorBlock(request_v6->IV, Response->RandomXoredIVs);
 | 
			
		||||
	XorBlock(request_v6->IV, response->RandomXoredIVs);
 | 
			
		||||
 | 
			
		||||
	// Get the base response
 | 
			
		||||
	HRESULT hResult;
 | 
			
		||||
	if (FAILED(hResult = CreateResponseBase(&request_v6->RequestBase, baseResponse, Response->HwId, ipstr))) return hResult;
 | 
			
		||||
	if (FAILED(hResult = CreateResponseBase(&request_v6->RequestBase, baseResponse, response->HwId, ipString))) return hResult;
 | 
			
		||||
 | 
			
		||||
	// Convert the fixed sized struct into variable sized
 | 
			
		||||
	const DWORD pidSize = LE32(baseResponse->PIDSize);
 | 
			
		||||
@@ -840,17 +893,17 @@ size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuf
 | 
			
		||||
	// number of bytes to encrypt
 | 
			
		||||
	size_t encryptSize =
 | 
			
		||||
		V6_PRE_EPID_SIZE
 | 
			
		||||
		- sizeof(Response->Version)
 | 
			
		||||
		- sizeof(response->Version)
 | 
			
		||||
		+ pidSize
 | 
			
		||||
		+ post_epid_size;
 | 
			
		||||
 | 
			
		||||
	//AesDecryptBlock(&aesCtx, Response->IV);
 | 
			
		||||
	if (v6 && !CreateV6Hmac(Response->IV, encryptSize, 0)) return 0;
 | 
			
		||||
	if (v6 && !CreateV6Hmac(response->IV, encryptSize, 0)) return 0;
 | 
			
		||||
 | 
			
		||||
	// Padding auto handled by encryption func
 | 
			
		||||
	AesEncryptCbc(&aesCtx, NULL, Response->IV, &encryptSize);
 | 
			
		||||
	AesEncryptCbc(&aesCtx, NULL, response->IV, &encryptSize);
 | 
			
		||||
 | 
			
		||||
	return encryptSize + sizeof(Response->Version);
 | 
			
		||||
	return encryptSize + sizeof(response->Version);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -895,10 +948,10 @@ BYTE* CreateRequestV6(size_t *size, const REQUEST* requestBase)
 | 
			
		||||
 | 
			
		||||
	// Encrypt KMS Client Request
 | 
			
		||||
	size_t encryptSize = sizeof(request->RequestBase);
 | 
			
		||||
	AesCtx Ctx;
 | 
			
		||||
	int_fast8_t v6 = LE16(request->MajorVer) > 5;
 | 
			
		||||
	AesInitKey(&Ctx, v6 ? AesKeyV6 : AesKeyV5, v6, 16);
 | 
			
		||||
	AesEncryptCbc(&Ctx, request->IV, (BYTE*)(&request->RequestBase), &encryptSize);
 | 
			
		||||
	AesCtx ctx;
 | 
			
		||||
	const int_fast8_t v6 = LE16(request->MajorVer) > 5;
 | 
			
		||||
	AesInitKey(&ctx, v6 ? AesKeyV6 : AesKeyV5, v6, 16);
 | 
			
		||||
	AesEncryptCbc(&ctx, request->IV, (BYTE*)(&request->RequestBase), &encryptSize);
 | 
			
		||||
 | 
			
		||||
	// Return Proper Request Data
 | 
			
		||||
	return (BYTE*)request;
 | 
			
		||||
@@ -1045,11 +1098,11 @@ RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BY
 | 
			
		||||
	// Decrypt KMS Server Response (encrypted part starts after RequestIV)
 | 
			
		||||
	responseSize -= copySize1;
 | 
			
		||||
 | 
			
		||||
	AesCtx Ctx;
 | 
			
		||||
	AesCtx ctx;
 | 
			
		||||
	const int_fast8_t v6 = LE16(((RESPONSE_V6*)response)->MajorVer) > 5;
 | 
			
		||||
 | 
			
		||||
	AesInitKey(&Ctx, v6 ? AesKeyV6 : AesKeyV5, v6, AES_KEY_BYTES);
 | 
			
		||||
	AesDecryptCbc(&Ctx, NULL, response + copySize1, responseSize);
 | 
			
		||||
	AesInitKey(&ctx, v6 ? AesKeyV6 : AesKeyV5, v6, AES_KEY_BYTES);
 | 
			
		||||
	AesDecryptCbc(&ctx, NULL, response + copySize1, responseSize);
 | 
			
		||||
 | 
			
		||||
	// Check padding
 | 
			
		||||
	BYTE* lastPadByte = response + (size_t)result.effectiveResponseSize - 1;
 | 
			
		||||
@@ -1073,7 +1126,7 @@ RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BY
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add size of Version, KmsPIDLen and variable size PID
 | 
			
		||||
	DWORD pidSize = LE32(((RESPONSE_V6*)response)->ResponseBase.PIDSize);
 | 
			
		||||
	const DWORD pidSize = LE32(((RESPONSE_V6*)response)->ResponseBase.PIDSize);
 | 
			
		||||
 | 
			
		||||
	copySize1 +=
 | 
			
		||||
		V6_UNENCRYPTED_SIZE +
 | 
			
		||||
@@ -1097,9 +1150,9 @@ RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BY
 | 
			
		||||
	REQUEST_V6* request_v6 = (REQUEST_V6*)rawRequest;
 | 
			
		||||
	const DWORD decryptSize = sizeof(request_v6->IV) + sizeof(request_v6->RequestBase) + sizeof(request_v6->Pad);
 | 
			
		||||
 | 
			
		||||
	AesDecryptCbc(&Ctx, NULL, request_v6->IV, decryptSize);
 | 
			
		||||
	AesDecryptCbc(&ctx, NULL, request_v6->IV, decryptSize);
 | 
			
		||||
 | 
			
		||||
	// Check that all version informations are the same
 | 
			
		||||
	// Check that all version information is the same
 | 
			
		||||
	result.VersionOK =
 | 
			
		||||
		request_v6->Version == response_v6->ResponseBase.Version &&
 | 
			
		||||
		request_v6->Version == response_v6->Version &&
 | 
			
		||||
@@ -1111,14 +1164,14 @@ RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BY
 | 
			
		||||
	result.ClientMachineIDOK = IsEqualGUID(&response_v6->ResponseBase.CMID, &request_v6->RequestBase.CMID);
 | 
			
		||||
 | 
			
		||||
	// Rebuild Random Key and Sha256 Hash
 | 
			
		||||
	BYTE HashVerify[sizeof(response_v6->Hash)];
 | 
			
		||||
	BYTE RandomKey[sizeof(response_v6->RandomXoredIVs)];
 | 
			
		||||
	BYTE hashVerify[sizeof(response_v6->Hash)];
 | 
			
		||||
	BYTE randomKey[sizeof(response_v6->RandomXoredIVs)];
 | 
			
		||||
 | 
			
		||||
	memcpy(RandomKey, request_v6->IV, sizeof(RandomKey));
 | 
			
		||||
	XorBlock(response_v6->RandomXoredIVs, RandomKey);
 | 
			
		||||
	Sha256(RandomKey, sizeof(RandomKey), HashVerify);
 | 
			
		||||
	memcpy(randomKey, request_v6->IV, sizeof(randomKey));
 | 
			
		||||
	XorBlock(response_v6->RandomXoredIVs, randomKey);
 | 
			
		||||
	Sha256(randomKey, sizeof(randomKey), hashVerify);
 | 
			
		||||
 | 
			
		||||
	result.HashOK = !memcmp(response_v6->Hash, HashVerify, sizeof(HashVerify));
 | 
			
		||||
	result.HashOK = !memcmp(response_v6->Hash, hashVerify, sizeof(hashVerify));
 | 
			
		||||
 | 
			
		||||
	// size before encryption (padding not included)
 | 
			
		||||
	result.correctResponseSize =
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								src/kms.h
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								src/kms.h
									
									
									
									
									
								
							@@ -228,6 +228,14 @@ typedef union
 | 
			
		||||
 | 
			
		||||
typedef BYTE hwid_t[8];
 | 
			
		||||
 | 
			
		||||
typedef enum 
 | 
			
		||||
{
 | 
			
		||||
	None = 0,
 | 
			
		||||
	UseNdr64 = 1 << 0,
 | 
			
		||||
	UseForEpid = 1 << 1,
 | 
			
		||||
	MayBeServer = 1 << 2,
 | 
			
		||||
} HostBuildFlag;
 | 
			
		||||
 | 
			
		||||
typedef struct CsvlkData
 | 
			
		||||
{
 | 
			
		||||
	union
 | 
			
		||||
@@ -236,6 +244,7 @@ typedef struct CsvlkData
 | 
			
		||||
		char* EPid;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	int64_t ReleaseDate;
 | 
			
		||||
	uint32_t GroupId;
 | 
			
		||||
	uint32_t MinKeyId;
 | 
			
		||||
	uint32_t MaxKeyId;
 | 
			
		||||
@@ -280,6 +289,22 @@ typedef struct
 | 
			
		||||
 | 
			
		||||
#define KMS_OPTIONS_USENDR64 1 << 0
 | 
			
		||||
 | 
			
		||||
typedef struct HostBuild
 | 
			
		||||
{
 | 
			
		||||
	union
 | 
			
		||||
	{
 | 
			
		||||
		uint64_t DisplayNameOffset;
 | 
			
		||||
		char* DisplayName;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	int64_t ReleaseDate;
 | 
			
		||||
	int32_t BuildNumber;
 | 
			
		||||
	int32_t PlatformId;
 | 
			
		||||
	HostBuildFlag Flags;
 | 
			
		||||
	uint8_t reserved[4];
 | 
			
		||||
 | 
			
		||||
} HostBuild_t, *PHostBuild_t;
 | 
			
		||||
 | 
			
		||||
typedef struct VlmcsdHeader
 | 
			
		||||
{
 | 
			
		||||
	BYTE Magic[4];
 | 
			
		||||
@@ -290,19 +315,21 @@ typedef struct VlmcsdHeader
 | 
			
		||||
 | 
			
		||||
	union
 | 
			
		||||
	{
 | 
			
		||||
		int32_t Counts[3];
 | 
			
		||||
		int32_t Counts[5];
 | 
			
		||||
 | 
			
		||||
		struct
 | 
			
		||||
		{
 | 
			
		||||
			int32_t AppItemCount;
 | 
			
		||||
			int32_t KmsItemCount;
 | 
			
		||||
			int32_t SkuItemCount;
 | 
			
		||||
			int32_t HostBuildCount;
 | 
			
		||||
			int32_t reserved2Counts;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	union
 | 
			
		||||
	{
 | 
			
		||||
		DataPointer_t Datapointers[3];
 | 
			
		||||
		DataPointer_t Datapointers[5];
 | 
			
		||||
 | 
			
		||||
		struct
 | 
			
		||||
		{
 | 
			
		||||
@@ -324,19 +351,31 @@ typedef struct VlmcsdHeader
 | 
			
		||||
				PVlmcsdData_t SkuItemList;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			union
 | 
			
		||||
			{
 | 
			
		||||
				uint64_t HostBuildOffset;
 | 
			
		||||
				PHostBuild_t HostBuildList;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			union
 | 
			
		||||
			{
 | 
			
		||||
				uint64_t Reserved2Offset;
 | 
			
		||||
				void* Reserved2List;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			CsvlkData_t CsvlkData[1];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
} VlmcsdHeader_t, *PVlmcsdHeader_t;
 | 
			
		||||
 | 
			
		||||
#define EPID_INDEX_WINDOWS 0
 | 
			
		||||
#define EPID_INDEX_OFFICE2010 1
 | 
			
		||||
#define EPID_INDEX_OFFICE2013 2
 | 
			
		||||
#define EPID_INDEX_OFFICE2016 3
 | 
			
		||||
#define EPID_INDEX_WINCHINAGOV 4
 | 
			
		||||
//#define EPID_INDEX_WINDOWS 0
 | 
			
		||||
//#define EPID_INDEX_OFFICE2010 1
 | 
			
		||||
//#define EPID_INDEX_OFFICE2013 2
 | 
			
		||||
//#define EPID_INDEX_OFFICE2016 3
 | 
			
		||||
//#define EPID_INDEX_WINCHINAGOV 4
 | 
			
		||||
 | 
			
		||||
typedef HRESULT(__stdcall *RequestCallback_t)(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr);
 | 
			
		||||
typedef HRESULT(__stdcall *RequestCallback_t)(REQUEST* baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr);
 | 
			
		||||
 | 
			
		||||
size_t CreateResponseV4(REQUEST_V4 *const Request, BYTE *const response_data, const char* const ipstr);
 | 
			
		||||
size_t CreateResponseV6(REQUEST_V6 *restrict Request, BYTE *const response_data, const char* const ipstr);
 | 
			
		||||
@@ -344,13 +383,16 @@ BYTE *CreateRequestV4(size_t *size, const REQUEST* requestBase);
 | 
			
		||||
BYTE *CreateRequestV6(size_t *size, const REQUEST* requestBase);
 | 
			
		||||
void randomPidInit();
 | 
			
		||||
void get16RandomBytes(void* ptr);
 | 
			
		||||
RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* Response_v6, int responseSize, BYTE* const response, const BYTE* const request, BYTE* hwid);
 | 
			
		||||
RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* Response_v4, const int responseSize, BYTE* const response, const BYTE* const request);
 | 
			
		||||
void getUnixTimeAsFileTime(FILETIME *const ts);
 | 
			
		||||
__pure int64_t fileTimeToUnixTime(const FILETIME *const ts);
 | 
			
		||||
RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BYTE* const response, const BYTE* const rawRequest, BYTE* hwid);
 | 
			
		||||
RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* response_v4, const int responseSize, BYTE* const rawResponse, const BYTE* const rawRequest);
 | 
			
		||||
void getUnixTimeAsFileTime(FILETIME* ts);
 | 
			
		||||
__pure int64_t fileTimeToUnixTime(FILETIME* ts);
 | 
			
		||||
 | 
			
		||||
#ifndef IS_LIBRARY
 | 
			
		||||
int32_t getProductIndex(const GUID* guid, const PVlmcsdData_t list, const int32_t count, char** name, char** ePid);
 | 
			
		||||
#if !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
 | 
			
		||||
const char* getNextString(const char* s);
 | 
			
		||||
#endif  // !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
 | 
			
		||||
#endif // IS_LIBRARY
 | 
			
		||||
 | 
			
		||||
#ifndef NO_STRICT_MODES
 | 
			
		||||
@@ -362,7 +404,7 @@ extern RequestCallback_t CreateResponseBase;
 | 
			
		||||
 | 
			
		||||
#ifdef _PEDANTIC
 | 
			
		||||
uint16_t IsValidLcid(const uint16_t lcid);
 | 
			
		||||
uint16_t IsValidHostBuild(const uint16_t hostBuild);
 | 
			
		||||
uint32_t IsValidHostBuild(const int32_t hostBuild);
 | 
			
		||||
#endif // _PEDANTIC
 | 
			
		||||
 | 
			
		||||
#endif // __kms_h
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1853
									
								
								src/kmsdata-full.c
									
									
									
									
									
								
							
							
						
						
									
										1853
									
								
								src/kmsdata-full.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2195
									
								
								src/kmsdata.c
									
									
									
									
									
								
							
							
						
						
									
										2195
									
								
								src/kmsdata.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -171,7 +171,7 @@ RpcStatus closeRpc(const RpcCtx handle)
 | 
			
		||||
 | 
			
		||||
#if !MULTI_CALL_BINARY
 | 
			
		||||
// Memory allocation function for RPC.
 | 
			
		||||
void *__RPC_USER midl_user_allocate(SIZE_T len)
 | 
			
		||||
void *__RPC_USER midl_user_allocate(size_t len)
 | 
			
		||||
{
 | 
			
		||||
	return vlmcsd_malloc(len);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -294,7 +294,7 @@ int ProcessActivationRequest(handle_t IDL_handle, int requestSize, unsigned char
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Memory allocation function for RPC.
 | 
			
		||||
void *__RPC_USER midl_user_allocate(SIZE_T len)
 | 
			
		||||
void *__RPC_USER midl_user_allocate(size_t len)
 | 
			
		||||
{
 | 
			
		||||
	return vlmcsd_malloc(len);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -247,7 +247,7 @@ ns_name_unpack_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src
 | 
			
		||||
 *	Root domain returns as "." not "".
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
ns_name_uncompress_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
 | 
			
		||||
ns_name_uncompress_vlmcsd(uint8_t *msg, uint8_t *eom, uint8_t *src,
 | 
			
		||||
		   char *dst, size_t dstsiz)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t tmp[NS_MAXCDNAME];
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
#define NS_NAME_H_
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
ns_name_uncompress_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
 | 
			
		||||
ns_name_uncompress_vlmcsd(uint8_t *msg, uint8_t *eom, uint8_t *src,
 | 
			
		||||
		   char *dst, size_t dstsiz);
 | 
			
		||||
 | 
			
		||||
#endif /* NS_NAME_H_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -57,9 +57,9 @@
 | 
			
		||||
static void	setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int dn_skipname_vlmcsd(const unsigned char *s, const unsigned char *end)
 | 
			
		||||
static int dn_skipname_vlmcsd(unsigned char *s, unsigned char *end)
 | 
			
		||||
{
 | 
			
		||||
	const unsigned char *p;
 | 
			
		||||
	unsigned char *p;
 | 
			
		||||
	for (p=s; p<end; p++)
 | 
			
		||||
		if (!*p) return p-s+1;
 | 
			
		||||
		else if (*p>=192)
 | 
			
		||||
@@ -69,8 +69,8 @@ static int dn_skipname_vlmcsd(const unsigned char *s, const unsigned char *end)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
ns_skiprr_vlmcsd(const uint8_t *ptr, const uint8_t *eom, ns_sect_vlmcsd section, int count) {
 | 
			
		||||
	const uint8_t *optr = ptr;
 | 
			
		||||
ns_skiprr_vlmcsd(uint8_t *ptr, uint8_t *eom, ns_sect_vlmcsd section, int count) {
 | 
			
		||||
	uint8_t *optr = ptr;
 | 
			
		||||
 | 
			
		||||
	for ((void)NULL; count > 0; count--) {
 | 
			
		||||
		int b, rdlength;
 | 
			
		||||
@@ -93,8 +93,8 @@ ns_skiprr_vlmcsd(const uint8_t *ptr, const uint8_t *eom, ns_sect_vlmcsd section,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
ns_initparse_vlmcsd(const uint8_t *msg, int msglen, ns_msg_vlmcsd *handle) {
 | 
			
		||||
	const uint8_t *eom = msg + msglen;
 | 
			
		||||
ns_initparse_vlmcsd(uint8_t *msg, int msglen, ns_msg_vlmcsd *handle) {
 | 
			
		||||
	uint8_t *eom = msg + msglen;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	memset(handle, 0x5e, sizeof *handle);
 | 
			
		||||
 
 | 
			
		||||
@@ -46,12 +46,12 @@ typedef enum __ns_sect_vlmcsd {
 | 
			
		||||
} ns_sect_vlmcsd;
 | 
			
		||||
 | 
			
		||||
typedef struct __ns_msg_vlmcsd {
 | 
			
		||||
	const uint8_t	*_msg, *_eom;
 | 
			
		||||
	uint8_t	*_msg, *_eom;
 | 
			
		||||
	uint16_t	_id, _flags, _counts[ns_s_max_vlmcsd];
 | 
			
		||||
	const uint8_t	*_sections[ns_s_max_vlmcsd];
 | 
			
		||||
	uint8_t	*_sections[ns_s_max_vlmcsd];
 | 
			
		||||
	ns_sect_vlmcsd		_sect;
 | 
			
		||||
	int		_rrnum;
 | 
			
		||||
	const uint8_t	*_msg_ptr;
 | 
			
		||||
	uint8_t	*_msg_ptr;
 | 
			
		||||
} ns_msg_vlmcsd;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -61,10 +61,10 @@ typedef	struct __ns_rr_vlmcsd {
 | 
			
		||||
	uint16_t	rr_class;
 | 
			
		||||
	uint32_t	ttl;
 | 
			
		||||
	uint16_t	rdlength;
 | 
			
		||||
	const uint8_t *	rdata;
 | 
			
		||||
	uint8_t *	rdata;
 | 
			
		||||
} ns_rr_vlmcsd;
 | 
			
		||||
 | 
			
		||||
int ns_initparse_vlmcsd(const uint8_t *msg, int msglen, ns_msg_vlmcsd *handle);
 | 
			
		||||
int ns_initparse_vlmcsd(uint8_t *msg, int msglen, ns_msg_vlmcsd *handle);
 | 
			
		||||
 | 
			
		||||
int ns_parserr_vlmcsd(ns_msg_vlmcsd *handle, ns_sect_vlmcsd section, int rrnum, ns_rr_vlmcsd *rr);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -180,7 +180,7 @@ void uuid2StringLE(const GUID *const guid, char *const string)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(NO_VERBOSE_LOG) && !defined(NO_LOG)
 | 
			
		||||
void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p)
 | 
			
		||||
void logRequestVerbose(REQUEST* Request, const PRINTFUNC p)
 | 
			
		||||
{
 | 
			
		||||
	char guidBuffer[GUID_STRING_LENGTH + 1];
 | 
			
		||||
	char WorkstationBuffer[3 * WORKSTATION_NAME_BUFFER];
 | 
			
		||||
@@ -222,7 +222,7 @@ void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p)
 | 
			
		||||
	p("N count policy (minimum clients): %u\n", (uint32_t)LE32(Request->N_Policy));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, const RESPONSE *const response, const PRINTFUNC p)
 | 
			
		||||
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, RESPONSE* response, const PRINTFUNC p)
 | 
			
		||||
{
 | 
			
		||||
	char guidBuffer[GUID_STRING_LENGTH + 1];
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,8 @@ typedef int (*PRINTFUNC)(const char *const fmt, ...);
 | 
			
		||||
 | 
			
		||||
int printerrorf(const char *const fmt, ...);
 | 
			
		||||
int errorout(const char* fmt, ...);
 | 
			
		||||
void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p);
 | 
			
		||||
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, const RESPONSE *const response, const PRINTFUNC p);
 | 
			
		||||
void logRequestVerbose(REQUEST* Request, const PRINTFUNC p);
 | 
			
		||||
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, RESPONSE* response, const PRINTFUNC p);
 | 
			
		||||
 | 
			
		||||
#ifndef NO_VERSION_INFORMATION
 | 
			
		||||
void printPlatform();
 | 
			
		||||
 
 | 
			
		||||
@@ -325,7 +325,7 @@ static int rpcRequest(const RPC_REQUEST64 *const Request, RPC_RESPONSE64 *const
 | 
			
		||||
#	endif // !SIMPLE_RPC
 | 
			
		||||
 | 
			
		||||
	pRpcReturnCode = ((BYTE*)&Response->Ndr) + len;
 | 
			
		||||
	UA32(pRpcReturnCode) = ResponseSize < 0 ? LE32(ResponseSize) : 0;
 | 
			
		||||
	PUT_UA32LE(pRpcReturnCode, ResponseSize < 0 ? ResponseSize : 0);
 | 
			
		||||
	len += sizeof(DWORD);
 | 
			
		||||
 | 
			
		||||
	// Pad zeros to 32-bit align (seems not neccassary but Windows RPC does it this way)
 | 
			
		||||
@@ -371,7 +371,7 @@ static void CheckRpcBindRequest(const RPC_BIND_REQUEST *const Request, const uns
 | 
			
		||||
 | 
			
		||||
		if (ctxItem->InterfaceVerMajor != LE16(1) || ctxItem->InterfaceVerMinor != 0)
 | 
			
		||||
			logger("Warning: Interface version is %u.%u but should be 1.0.\n",
 | 
			
		||||
				(unsigned int)LE16(ctxItem->InterfaceVerMajor),
 | 
			
		||||
			(unsigned int)LE16(ctxItem->InterfaceVerMajor),
 | 
			
		||||
				(unsigned int)LE16(ctxItem->InterfaceVerMinor)
 | 
			
		||||
			);
 | 
			
		||||
 | 
			
		||||
@@ -494,7 +494,7 @@ static int rpcBind(const RPC_BIND_REQUEST *const Request, RPC_BIND_RESPONSE* Res
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < numCtxItems; i++)
 | 
			
		||||
	{
 | 
			
		||||
		struct CtxResults* result = Response->Results+i;
 | 
			
		||||
		struct CtxResults* result = Response->Results + i;
 | 
			
		||||
		const GUID* ctxTransferSyntax = &Request->CtxItems[i].TransferSyntax;
 | 
			
		||||
 | 
			
		||||
#		ifndef SIMPLE_RPC
 | 
			
		||||
@@ -970,7 +970,8 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const kmsRequest, const
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pReturnCode = (DWORD*)(*kmsResponse + *responseSize + pad);
 | 
			
		||||
		status = LE32(UA32(pReturnCode));
 | 
			
		||||
		status = GET_UA32LE(pReturnCode);
 | 
			
		||||
		//status = LE32(UA32(pReturnCode));
 | 
			
		||||
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,7 @@ typedef struct
 | 
			
		||||
	const BYTE* HwId;
 | 
			
		||||
	#ifndef NO_LOG
 | 
			
		||||
	const char* EpidSource;
 | 
			
		||||
	uint8_t IsRandom;
 | 
			
		||||
	#endif // NO_LOG
 | 
			
		||||
} KmsResponseParam_t, *PKmsResponseParam_t;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										99
									
								
								src/vlmcs.c
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								src/vlmcs.c
									
									
									
									
									
								
							@@ -52,8 +52,6 @@
 | 
			
		||||
#define VLMCS_OPTION_GRAB_INI 1
 | 
			
		||||
#define VLMCS_OPTION_NO_GRAB_INI 2
 | 
			
		||||
 | 
			
		||||
//#define kmsVersionMinor 0 // Currently constant. May change in future KMS versions
 | 
			
		||||
 | 
			
		||||
#ifndef IS_LIBRARY
 | 
			
		||||
 | 
			
		||||
// Function Prototypes
 | 
			
		||||
@@ -83,24 +81,19 @@ static int AddressFamily = 0;
 | 
			
		||||
static int_fast8_t incompatibleOptions = 0;
 | 
			
		||||
static const char* fn_ini_client = NULL;
 | 
			
		||||
//static int_fast16_t kmsVersionMinor = 0;
 | 
			
		||||
static const char* ePidGroup[] = { "Windows", "Office2010", "Office2013", "Office2016" };
 | 
			
		||||
//static const char* ePidGroup[] = { "Windows", "Office2010", "Office2013", "Office2016" };
 | 
			
		||||
static int32_t ActiveProductIndex = 0;
 | 
			
		||||
static int32_t NCountPolicy = 0;
 | 
			
		||||
static GUID AppGuid, KmsGuid, SkuGuid;
 | 
			
		||||
static uint16_t MinorVersion = 0;
 | 
			
		||||
static uint16_t MajorVersion;
 | 
			
		||||
 | 
			
		||||
//#if !MULTI_CALL_BINARY
 | 
			
		||||
//uint8_t DefaultKmsData[]={0};
 | 
			
		||||
//__pure size_t getDefaultKmsDataSize() { return (size_t)0; }
 | 
			
		||||
//#endif // !MULTI_CALL_BINARY
 | 
			
		||||
 | 
			
		||||
#ifndef NO_DNS
 | 
			
		||||
static int_fast8_t NoSrvRecordPriority = FALSE;
 | 
			
		||||
#endif // NO_DNS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef char iniFileEpidLines[4][256];
 | 
			
		||||
//typedef char iniFileEpidLines[4][256];
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
@@ -943,7 +936,6 @@ static void displayRequestError(RpcCtx *const s, const int status, const int cur
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void newIniBackupFile(const char* const restrict fname)
 | 
			
		||||
{
 | 
			
		||||
	FILE *restrict f = fopen(fname, "wb");
 | 
			
		||||
@@ -965,9 +957,9 @@ static void newIniBackupFile(const char* const restrict fname)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void updateIniFile(iniFileEpidLines* const restrict lines)
 | 
			
		||||
static void updateIniFile(char*** restrict lines)
 | 
			
		||||
{
 | 
			
		||||
	int_fast8_t lineWritten[vlmcsd_countof(*lines)];
 | 
			
		||||
	int_fast8_t* lineWritten = (int_fast8_t*)malloc(KmsData->CsvlkCount * sizeof(int_fast8_t));
 | 
			
		||||
#	if !_MSC_VER
 | 
			
		||||
	struct stat statbuf;
 | 
			
		||||
#	endif
 | 
			
		||||
@@ -975,7 +967,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
 | 
			
		||||
	int_fast8_t iniFileExistedBefore = TRUE;
 | 
			
		||||
	unsigned int lineNumber;
 | 
			
		||||
 | 
			
		||||
	memset(lineWritten, FALSE, sizeof(lineWritten));
 | 
			
		||||
	memset(lineWritten, FALSE, KmsData->CsvlkCount * sizeof(int_fast8_t));
 | 
			
		||||
 | 
			
		||||
	char* restrict fn_bak = (char*)vlmcsd_malloc(strlen(fn_ini_client) + 2);
 | 
			
		||||
 | 
			
		||||
@@ -1009,7 +1001,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
 | 
			
		||||
		vlmcsd_unlink(fn_bak); // Required for Windows. Most Unix systems don't need it.
 | 
			
		||||
		if (rename(fn_ini_client, fn_bak))
 | 
			
		||||
		{
 | 
			
		||||
			int error = errno;
 | 
			
		||||
			const int error = errno;
 | 
			
		||||
			errorout("Fatal: Cannot create %s: %s\n", fn_bak, strerror(error));
 | 
			
		||||
			exit(error);
 | 
			
		||||
		}
 | 
			
		||||
@@ -1023,7 +1015,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
 | 
			
		||||
 | 
			
		||||
	if (!in)
 | 
			
		||||
	{
 | 
			
		||||
		int error = errno;
 | 
			
		||||
		const int error = errno;
 | 
			
		||||
		errorout("Fatal: Cannot open %s: %s\n", fn_bak, strerror(error));
 | 
			
		||||
		exit(error);
 | 
			
		||||
	}
 | 
			
		||||
@@ -1032,7 +1024,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
 | 
			
		||||
 | 
			
		||||
	if (!out)
 | 
			
		||||
	{
 | 
			
		||||
		int error = errno;
 | 
			
		||||
		const int error = errno;
 | 
			
		||||
		errorout("Fatal: Cannot create %s: %s\n", fn_ini_client, strerror(error));
 | 
			
		||||
		exit(error);
 | 
			
		||||
	}
 | 
			
		||||
@@ -1041,9 +1033,9 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
 | 
			
		||||
 | 
			
		||||
	for (lineNumber = 1; fgets(sourceLine, sizeof(sourceLine), in); lineNumber++)
 | 
			
		||||
	{
 | 
			
		||||
		for (i = 0; i < vlmcsd_countof(*lines); i++)
 | 
			
		||||
		for (i = 0; i < KmsData->CsvlkCount; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (*(*lines)[i] && !strncasecmp(sourceLine, (*lines)[i], strlen(ePidGroup[i])))
 | 
			
		||||
			if (*(*lines)[i] && !strncasecmp(sourceLine, (*lines)[i], strlen(getNextString((KmsData->CsvlkData[i].EPid)))))
 | 
			
		||||
			{
 | 
			
		||||
				if (lineWritten[i]) break;
 | 
			
		||||
 | 
			
		||||
@@ -1054,7 +1046,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (i >= vlmcsd_countof(*lines))
 | 
			
		||||
		if (i >= KmsData->CsvlkCount)
 | 
			
		||||
		{
 | 
			
		||||
			fprintf(out, "%s", sourceLine);
 | 
			
		||||
		}
 | 
			
		||||
@@ -1069,7 +1061,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
 | 
			
		||||
 | 
			
		||||
	fclose(in);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < vlmcsd_countof(*lines); i++)
 | 
			
		||||
	for (i = 0; i < KmsData->CsvlkCount; i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (!lineWritten[i] && *(*lines)[i])
 | 
			
		||||
		{
 | 
			
		||||
@@ -1080,7 +1072,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
 | 
			
		||||
 | 
			
		||||
	if (fclose(out))
 | 
			
		||||
	{
 | 
			
		||||
		int error = errno;
 | 
			
		||||
		const int error = errno;
 | 
			
		||||
		errorout("Fatal: Cannot write to %s: %s\n", fn_ini_client, strerror(error));
 | 
			
		||||
		exit(error);
 | 
			
		||||
	}
 | 
			
		||||
@@ -1095,18 +1087,27 @@ static void grabServerData()
 | 
			
		||||
{
 | 
			
		||||
	RpcCtx s = INVALID_RPCCTX;
 | 
			
		||||
	WORD MajorVer = 6;
 | 
			
		||||
	iniFileEpidLines lines;
 | 
			
		||||
 | 
			
		||||
	static char* Licenses[vlmcsd_countof(lines)] =
 | 
			
		||||
	{
 | 
			
		||||
		(char*)"212a64dc-43b1-4d3d-a30c-2fc69d2095c6", // Vista
 | 
			
		||||
		(char*)"e85af946-2e25-47b7-83e1-bebcebeac611", // Office 2010
 | 
			
		||||
		(char*)"e6a6f1bf-9d40-40c3-aa9f-c77ba21578c0", // Office 2013
 | 
			
		||||
		(char*)"85b5f61b-320b-4be3-814a-b76b2bfafc82", // Office 2016
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	uint_fast8_t i;
 | 
			
		||||
	int32_t i;
 | 
			
		||||
	int32_t j;
 | 
			
		||||
 | 
			
		||||
	char** lines = (char**)vlmcsd_malloc(KmsData->CsvlkCount * sizeof(char*));
 | 
			
		||||
	GUID* kmsGuids = (GUID*)vlmcsd_malloc(KmsData->CsvlkCount * sizeof(GUID));
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < KmsData->CsvlkCount; i++)
 | 
			
		||||
	{
 | 
			
		||||
		lines[i] = (char*)vlmcsd_malloc(256);
 | 
			
		||||
		*lines[i] = 0;
 | 
			
		||||
 | 
			
		||||
		for (j = 0; j < KmsData->KmsItemCount; j++)
 | 
			
		||||
		{
 | 
			
		||||
			if (KmsData->KmsItemList[j].EPidIndex == i)
 | 
			
		||||
			{
 | 
			
		||||
				kmsGuids[i] = KmsData->KmsItemList[j].Guid;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RESPONSE response;
 | 
			
		||||
	RESPONSE_RESULT result;
 | 
			
		||||
	REQUEST request;
 | 
			
		||||
@@ -1114,23 +1115,19 @@ static void grabServerData()
 | 
			
		||||
	int status;
 | 
			
		||||
	size_t len;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < vlmcsd_countof(lines); i++) *lines[i] = 0;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < vlmcsd_countof(Licenses) && MajorVer > 3; i++)
 | 
			
		||||
	for (i = 0; i < KmsData->CsvlkCount && MajorVer > 3; i++)
 | 
			
		||||
	{
 | 
			
		||||
		GUID guid;
 | 
			
		||||
		string2UuidLE(Licenses[i], &guid);
 | 
			
		||||
		int32_t kmsIndex = getProductIndex(&guid, KmsData->KmsItemList, KmsData->KmsItemCount, NULL, NULL);
 | 
			
		||||
		const int32_t kmsIndex = getProductIndex(&kmsGuids[i], KmsData->KmsItemList, KmsData->KmsItemCount, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
		if (kmsIndex < 0)
 | 
			
		||||
		{
 | 
			
		||||
			errorout("Warning: KMS GUID %s not in database.\n", Licenses[i]);
 | 
			
		||||
			errorout("Warning: KMS GUID not in database.\n");
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ActiveProductIndex = ~0;
 | 
			
		||||
 | 
			
		||||
		for (j = KmsData->SkuItemCount; j >= 0; j--)
 | 
			
		||||
		for (j = KmsData->SkuItemCount - 1; j >= 0; j--)
 | 
			
		||||
		{
 | 
			
		||||
			if (KmsData->SkuItemList[j].KmsIndex == kmsIndex)
 | 
			
		||||
			{
 | 
			
		||||
@@ -1141,11 +1138,11 @@ static void grabServerData()
 | 
			
		||||
 | 
			
		||||
		if (ActiveProductIndex == ~0)
 | 
			
		||||
		{
 | 
			
		||||
			errorout("Warning: KMS GUID %s not in database.\n", Licenses[i]);
 | 
			
		||||
			errorout("Warning: KMS GUID not in database.\n");
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int32_t appIndex = KmsData->SkuItemList[ActiveProductIndex].AppIndex;
 | 
			
		||||
		const int32_t appIndex = KmsData->SkuItemList[ActiveProductIndex].AppIndex;
 | 
			
		||||
 | 
			
		||||
		NCountPolicy = (uint32_t)KmsData->SkuItemList[ActiveProductIndex].NCountPolicy;
 | 
			
		||||
		memcpy(&SkuGuid, &KmsData->SkuItemList[ActiveProductIndex].Guid, sizeof(GUID));
 | 
			
		||||
@@ -1154,7 +1151,7 @@ static void grabServerData()
 | 
			
		||||
		MajorVersion = (uint16_t)MajorVer;
 | 
			
		||||
 | 
			
		||||
		status = sendRequest(&s, &request, &response, hwid, &result);
 | 
			
		||||
		printf("%-11s", ePidGroup[i]);
 | 
			
		||||
		printf("%-11s", getNextString(KmsData->CsvlkData[i].EPid));
 | 
			
		||||
 | 
			
		||||
		if (status)
 | 
			
		||||
		{
 | 
			
		||||
@@ -1171,7 +1168,7 @@ static void grabServerData()
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		printf("%i of %i", (int)(i + 7 - MajorVer), (int)(10 - MajorVer));
 | 
			
		||||
		printf("%i of %i", (int)(i + 7 - MajorVer), (int)(KmsData->CsvlkCount + 6 - MajorVer));
 | 
			
		||||
		displayResponse(result, &request, &response, hwid);
 | 
			
		||||
 | 
			
		||||
		char ePID[3 * PID_BUFFER_SIZE];
 | 
			
		||||
@@ -1181,16 +1178,16 @@ static void grabServerData()
 | 
			
		||||
			memset(ePID + 3 * PID_BUFFER_SIZE - 3, 0, 3);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		vlmcsd_snprintf(lines[i], sizeof(lines[0]), "%s = %s", ePidGroup[i], ePID);
 | 
			
		||||
		vlmcsd_snprintf(lines[i], 255 - strlen(lines[i]), "%s = %s", getNextString(KmsData->CsvlkData[i].EPid), ePID);
 | 
			
		||||
 | 
			
		||||
		if (response.MajorVer > 5)
 | 
			
		||||
		{
 | 
			
		||||
			len = strlen(lines[i]);
 | 
			
		||||
			vlmcsd_snprintf(lines[i] + len, sizeof(lines[0]) - len, " / %02X %02X %02X %02X %02X %02X %02X %02X", hwid[0], hwid[1], hwid[2], hwid[3], hwid[4], hwid[5], hwid[6], hwid[7]);
 | 
			
		||||
			vlmcsd_snprintf(lines[i] + len, 255 - len, " / %02X %02X %02X %02X %02X %02X %02X %02X", hwid[0], hwid[1], hwid[2], hwid[3], hwid[4], hwid[5], hwid[6], hwid[7]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		len = strlen(lines[i]);
 | 
			
		||||
		vlmcsd_snprintf(lines[i] + len, sizeof(lines[0]) - len, "\n");
 | 
			
		||||
		vlmcsd_snprintf(lines[i] + len, 255 - len, "\n");
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1201,7 +1198,7 @@ static void grabServerData()
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		printf("\n");
 | 
			
		||||
		for (i = 0; i < vlmcsd_countof(lines); i++) printf("%s", lines[i]);
 | 
			
		||||
		for (i = 0; i < KmsData->CsvlkCount; i++) printf("%s", lines[i]);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1212,10 +1209,10 @@ int client_main(int argc, CARGV argv)
 | 
			
		||||
 | 
			
		||||
	// Windows Sockets must be initialized
 | 
			
		||||
 | 
			
		||||
	WSADATA wsadata;
 | 
			
		||||
	WSADATA wsaData;
 | 
			
		||||
	int error;
 | 
			
		||||
 | 
			
		||||
	if ((error = WSAStartup(0x0202, &wsadata)))
 | 
			
		||||
	if ((error = WSAStartup(0x0202, &wsaData)))
 | 
			
		||||
	{
 | 
			
		||||
		errorout("Fatal: Could not initialize Windows sockets (Error: %d).\n", error);
 | 
			
		||||
		return error;
 | 
			
		||||
@@ -1245,7 +1242,7 @@ int client_main(int argc, CARGV argv)
 | 
			
		||||
	else
 | 
			
		||||
		useDefaultHost = TRUE;
 | 
			
		||||
 | 
			
		||||
	int hostportarg = optind;
 | 
			
		||||
	const int hostportarg = optind;
 | 
			
		||||
 | 
			
		||||
	if (optind < argc - 1)
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										189
									
								
								src/vlmcsd.c
									
									
									
									
									
								
							
							
						
						
									
										189
									
								
								src/vlmcsd.c
									
									
									
									
									
								
							@@ -93,21 +93,23 @@ static uint_fast8_t maxsockets = 0;
 | 
			
		||||
 | 
			
		||||
#ifdef _NTSERVICE
 | 
			
		||||
static int_fast8_t installService = 0;
 | 
			
		||||
static const char *restrict ServiceUser = NULL;
 | 
			
		||||
static const char *restrict ServicePassword = "";
 | 
			
		||||
static const char* restrict ServiceUser = NULL;
 | 
			
		||||
static const char* restrict ServicePassword = "";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef NO_PID_FILE
 | 
			
		||||
static const char *fn_pid = NULL;
 | 
			
		||||
static const char* fn_pid = NULL;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef NO_INI_FILE
 | 
			
		||||
#if !defined(NO_INI_FILE) || !defined(NO_CL_PIDS)
 | 
			
		||||
 | 
			
		||||
#ifndef NO_INI_FILE
 | 
			
		||||
#ifdef INI_FILE
 | 
			
		||||
static const char *fn_ini = INI_FILE;
 | 
			
		||||
static const char* fn_ini = INI_FILE;
 | 
			
		||||
#else // !INI_FILE
 | 
			
		||||
static const char *fn_ini = NULL;
 | 
			
		||||
static const char* fn_ini = NULL;
 | 
			
		||||
#endif // !INI_FILE
 | 
			
		||||
#endif // NO_INI_FILE
 | 
			
		||||
 | 
			
		||||
#ifndef NO_TAP
 | 
			
		||||
char* tapArgument = NULL;
 | 
			
		||||
@@ -203,12 +205,12 @@ static int shmid = -1;
 | 
			
		||||
#ifndef NO_USER_SWITCH
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
 | 
			
		||||
static const char *uname = NULL, *gname = NULL;
 | 
			
		||||
static const char* uname = NULL, * gname = NULL;
 | 
			
		||||
static gid_t gid = INVALID_GID;
 | 
			
		||||
static uid_t uid = INVALID_UID;
 | 
			
		||||
 | 
			
		||||
// Get Numeric id of user/group
 | 
			
		||||
static char GetNumericId(gid_t *restrict id, const char *const c)
 | 
			
		||||
static char GetNumericId(gid_t* restrict id, const char* const c)
 | 
			
		||||
{
 | 
			
		||||
	char* endptr;
 | 
			
		||||
	gid_t temp;
 | 
			
		||||
@@ -224,7 +226,7 @@ static char GetNumericId(gid_t *restrict id, const char *const c)
 | 
			
		||||
// Get group id from option argument
 | 
			
		||||
static char GetGid()
 | 
			
		||||
{
 | 
			
		||||
	struct group *g;
 | 
			
		||||
	struct group* g;
 | 
			
		||||
 | 
			
		||||
	if ((g = getgrnam(optarg)))
 | 
			
		||||
		gid = g->gr_gid;
 | 
			
		||||
@@ -238,7 +240,7 @@ static char GetGid()
 | 
			
		||||
// Get user id from option argument
 | 
			
		||||
static char GetUid()
 | 
			
		||||
{
 | 
			
		||||
	struct passwd *u;
 | 
			
		||||
	struct passwd* u;
 | 
			
		||||
 | 
			
		||||
	////PORTABILITY: Assumes uid_t and gid_t are of same size (shouldn't be a problem)
 | 
			
		||||
	if ((u = getpwnam(optarg)))
 | 
			
		||||
@@ -380,9 +382,9 @@ static __noreturn void usage()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef NO_CUSTOM_INTERVALS
 | 
			
		||||
#ifndef NO_INI_FILE
 | 
			
		||||
#if !defined(NO_INI_FILE)
 | 
			
		||||
 | 
			
		||||
__pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restrict argument)
 | 
			
		||||
__pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char* const restrict argument)
 | 
			
		||||
{
 | 
			
		||||
	const DWORD val = timeSpanString2Minutes(argument);
 | 
			
		||||
 | 
			
		||||
@@ -396,10 +398,10 @@ __pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restr
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // NO_INI_FILE
 | 
			
		||||
#endif // !defined(NO_INI_FILE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__pure static DWORD getTimeSpanFromCommandLine(const char *const restrict arg, const char optchar)
 | 
			
		||||
__pure static DWORD getTimeSpanFromCommandLine(const char* const restrict arg, const char optchar)
 | 
			
		||||
{
 | 
			
		||||
	const DWORD val = timeSpanString2Minutes(arg);
 | 
			
		||||
 | 
			
		||||
@@ -424,13 +426,13 @@ static __pure int isControlCharOrSlash(const char c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void iniFileLineNextWord(const char **s)
 | 
			
		||||
static void iniFileLineNextWord(const char** s)
 | 
			
		||||
{
 | 
			
		||||
	while (**s && isspace((int)**s)) (*s)++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static BOOL setHwIdFromIniFileLine(const char **s, const uint32_t index, const uint8_t overwrite)
 | 
			
		||||
static BOOL setHwIdFromIniFileLine(const char** s, const uint32_t index, const uint8_t overwrite)
 | 
			
		||||
{
 | 
			
		||||
	iniFileLineNextWord(s);
 | 
			
		||||
 | 
			
		||||
@@ -438,8 +440,8 @@ static BOOL setHwIdFromIniFileLine(const char **s, const uint32_t index, const u
 | 
			
		||||
	{
 | 
			
		||||
		if (!overwrite && KmsResponseParameters[index].HwId) return TRUE;
 | 
			
		||||
 | 
			
		||||
		BYTE* HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6 *)0)->HwId));
 | 
			
		||||
		hex2bin(HwId, *s + 1, sizeof(((RESPONSE_V6 *)0)->HwId));
 | 
			
		||||
		BYTE* HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6*)0)->HwId));
 | 
			
		||||
		hex2bin(HwId, *s + 1, sizeof(((RESPONSE_V6*)0)->HwId));
 | 
			
		||||
		KmsResponseParameters[index].HwId = HwId;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -447,10 +449,10 @@ static BOOL setHwIdFromIniFileLine(const char **s, const uint32_t index, const u
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static BOOL setEpidFromIniFileLine(const char **s, const uint32_t index, const char *ePidSource, const uint8_t overwrite)
 | 
			
		||||
static BOOL setEpidFromIniFileLine(const char** s, const uint32_t index, const char* ePidSource, const uint8_t overwrite)
 | 
			
		||||
{
 | 
			
		||||
	iniFileLineNextWord(s);
 | 
			
		||||
	const char *savedPosition = *s;
 | 
			
		||||
	const char* savedPosition = *s;
 | 
			
		||||
	uint_fast16_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; !isControlCharOrSlash(**s); i++)
 | 
			
		||||
@@ -478,34 +480,16 @@ static BOOL setEpidFromIniFileLine(const char **s, const uint32_t index, const c
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
#endif // !defined(NO_INI_FILE) || !defined (NO_CL_PIDS)
 | 
			
		||||
 | 
			
		||||
#ifndef NO_INI_FILE
 | 
			
		||||
static void ignoreIniFileParameter(uint_fast8_t iniFileParameterId)
 | 
			
		||||
{
 | 
			
		||||
	uint_fast8_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < vlmcsd_countof(IniFileParameterList); i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (IniFileParameterList[i].Id != iniFileParameterId) continue;
 | 
			
		||||
		IniFileParameterList[i].Id = 0;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#else // NO_INI_FILE
 | 
			
		||||
#define ignoreIniFileParameter(x)
 | 
			
		||||
#endif // NO_INI_FILE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef NO_INI_FILE
 | 
			
		||||
static BOOL getIniFileArgumentBool(int_fast8_t *result, const char *const argument)
 | 
			
		||||
static BOOL getIniFileArgumentBool(int_fast8_t* result, const char* const argument)
 | 
			
		||||
{
 | 
			
		||||
	IniFileErrorMessage = "Argument must be true/on/yes/1 or false/off/no/0";
 | 
			
		||||
	return getArgumentBool(result, argument);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static BOOL getIniFileArgumentInt(unsigned int *result, const char *const argument, const unsigned int min, const unsigned int max)
 | 
			
		||||
static BOOL getIniFileArgumentInt(unsigned int* result, const char* const argument, const unsigned int min, const unsigned int max)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int tempResult;
 | 
			
		||||
 | 
			
		||||
@@ -521,7 +505,7 @@ static BOOL getIniFileArgumentInt(unsigned int *result, const char *const argume
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
 | 
			
		||||
static BOOL setIniFileParameter(uint_fast8_t id, const char* const iniarg)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int result;
 | 
			
		||||
	BOOL success = TRUE;
 | 
			
		||||
@@ -539,7 +523,7 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
 | 
			
		||||
 | 
			
		||||
	case INI_PARAM_GID:
 | 
			
		||||
	{
 | 
			
		||||
		struct group *g;
 | 
			
		||||
		struct group* g;
 | 
			
		||||
		IniFileErrorMessage = "Invalid group id or name";
 | 
			
		||||
		if (!(gname = vlmcsd_strdup(iniarg))) return FALSE;
 | 
			
		||||
 | 
			
		||||
@@ -552,7 +536,7 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
 | 
			
		||||
 | 
			
		||||
	case INI_PARAM_UID:
 | 
			
		||||
	{
 | 
			
		||||
		struct passwd *p;
 | 
			
		||||
		struct passwd* p;
 | 
			
		||||
		IniFileErrorMessage = "Invalid user id or name";
 | 
			
		||||
		if (!(uname = vlmcsd_strdup(iniarg))) return FALSE;
 | 
			
		||||
 | 
			
		||||
@@ -749,9 +733,11 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
 | 
			
		||||
 | 
			
		||||
	return success;
 | 
			
		||||
}
 | 
			
		||||
#endif // !NO_INI_FILE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static BOOL getIniFileArgument(const char **s)
 | 
			
		||||
 | 
			
		||||
static BOOL getIniFileArgument(const char** s)
 | 
			
		||||
{
 | 
			
		||||
	while (!isspace((int)**s) && **s != '=' && **s) (*s)++;
 | 
			
		||||
	iniFileLineNextWord(s);
 | 
			
		||||
@@ -773,18 +759,14 @@ static BOOL getIniFileArgument(const char **s)
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char* GetNextString(char* s)
 | 
			
		||||
{
 | 
			
		||||
	return s + strlen(s) + 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int8_t GetCsvlkIndexFromName(const char *s)
 | 
			
		||||
static int8_t GetCsvlkIndexFromName(const char* s)
 | 
			
		||||
{
 | 
			
		||||
	int8_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < KmsData->CsvlkCount; i++)
 | 
			
		||||
	{
 | 
			
		||||
		const char *csvlkName = GetNextString(KmsData->CsvlkData[i].EPid);
 | 
			
		||||
		const char* csvlkName = getNextString(KmsData->CsvlkData[i].EPid);
 | 
			
		||||
 | 
			
		||||
		if (!strncasecmp(csvlkName, s, strlen(csvlkName)))
 | 
			
		||||
		{
 | 
			
		||||
@@ -795,7 +777,7 @@ static int8_t GetCsvlkIndexFromName(const char *s)
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BOOL handleIniFileEpidParameter(const char *s, uint8_t allowIniFileDirectives, const char *ePidSource)
 | 
			
		||||
static BOOL handleIniFileEpidParameter(const char* s, uint8_t allowIniFileDirectives, const char* ePidSource)
 | 
			
		||||
{
 | 
			
		||||
	int_fast16_t i;
 | 
			
		||||
 | 
			
		||||
@@ -824,7 +806,26 @@ static BOOL handleIniFileEpidParameter(const char *s, uint8_t allowIniFileDirect
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BOOL handleIniFileParameter(const char *s)
 | 
			
		||||
#endif // !defined(NO_INI_FILE) || !defined (NO_CL_PIDS)
 | 
			
		||||
 | 
			
		||||
#ifndef NO_INI_FILE
 | 
			
		||||
static void ignoreIniFileParameter(uint_fast8_t iniFileParameterId)
 | 
			
		||||
{
 | 
			
		||||
	uint_fast8_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < vlmcsd_countof(IniFileParameterList); i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (IniFileParameterList[i].Id != iniFileParameterId) continue;
 | 
			
		||||
		IniFileParameterList[i].Id = 0;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#else // NO_INI_FILE
 | 
			
		||||
#define ignoreIniFileParameter(x)
 | 
			
		||||
#endif // NO_INI_FILE
 | 
			
		||||
 | 
			
		||||
#ifndef NO_INI_FILE
 | 
			
		||||
static BOOL handleIniFileParameter(const char* s)
 | 
			
		||||
{
 | 
			
		||||
	uint_fast8_t i;
 | 
			
		||||
 | 
			
		||||
@@ -843,7 +844,7 @@ static BOOL handleIniFileParameter(const char *s)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if !defined(NO_SOCKETS) && !defined(SIMPLE_SOCKETS) && !defined(USE_MSRPC)
 | 
			
		||||
static BOOL setupListeningSocketsFromIniFile(const char *s)
 | 
			
		||||
static BOOL setupListeningSocketsFromIniFile(const char* s)
 | 
			
		||||
{
 | 
			
		||||
	if (!maxsockets) return TRUE;
 | 
			
		||||
	if (strncasecmp("Listen", s, 6)) return TRUE;
 | 
			
		||||
@@ -859,26 +860,31 @@ static BOOL setupListeningSocketsFromIniFile(const char *s)
 | 
			
		||||
static BOOL readIniFile(const uint_fast8_t pass)
 | 
			
		||||
{
 | 
			
		||||
	char  line[256];
 | 
			
		||||
	const char *s;
 | 
			
		||||
	const char* s;
 | 
			
		||||
	unsigned int lineNumber;
 | 
			
		||||
	uint_fast8_t lineParseError;
 | 
			
		||||
 | 
			
		||||
	FILE *restrict f;
 | 
			
		||||
	FILE* restrict f;
 | 
			
		||||
	BOOL result = TRUE;
 | 
			
		||||
 | 
			
		||||
	if (pass == INI_FILE_PASS_2 && KmsData->MinorVer < 6)
 | 
			
		||||
	{
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	IniFileErrorBuffer = (char*)vlmcsd_malloc(INIFILE_ERROR_BUFFERSIZE);
 | 
			
		||||
 | 
			
		||||
	if (!((f = fopen(fn_ini, "r")))) return FALSE;
 | 
			
		||||
 | 
			
		||||
	for (lineNumber = 1; (s = fgets(line, sizeof(line), f)); lineNumber++)
 | 
			
		||||
	{
 | 
			
		||||
		line[strlen(line) - 1] = 0;
 | 
			
		||||
		size_t i;
 | 
			
		||||
 | 
			
		||||
		for (i = strlen(line); i > 0; i--)
 | 
			
		||||
		{
 | 
			
		||||
			if (line[i - 1] != 0xd && line[i - 1] != 0xa)
 | 
			
		||||
			{
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		line[i] = 0;
 | 
			
		||||
		
 | 
			
		||||
		iniFileLineNextWord(&s);
 | 
			
		||||
		if (*s == ';' || *s == '#' || !*s) continue;
 | 
			
		||||
 | 
			
		||||
@@ -965,7 +971,7 @@ __noreturn static void HangupHandler(const int signal_unused)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	argv_out[argc_in] = argv_out[argc_in + 1] = NULL;
 | 
			
		||||
	if (daemonize_protection) argv_out[argc_in] = (char*) "-Z";
 | 
			
		||||
	if (daemonize_protection) argv_out[argc_in] = (char*)"-Z";
 | 
			
		||||
 | 
			
		||||
	exec_self((char**)argv_out);
 | 
			
		||||
	int error = errno;
 | 
			
		||||
@@ -1084,7 +1090,7 @@ static DWORD daemonizeAndSetSignalAction()
 | 
			
		||||
// Workaround for Cygwin fork problem (only affects cygwin processes that are Windows services)
 | 
			
		||||
// Best is to compile for Cygwin with threads. fork() is slow and unreliable on Cygwin
 | 
			
		||||
#if !defined(NO_INI_FILE) || !defined(NO_LOG) || !defined(NO_CL_PIDS) || !defined(NO_EXTERNAL_DATA)
 | 
			
		||||
__pure static char* getCommandLineArg(char *const restrict arg)
 | 
			
		||||
__pure static char* getCommandLineArg(char* const restrict arg)
 | 
			
		||||
{
 | 
			
		||||
#	if !__CYGWIN__ || defined(USE_THREADS) || defined(NO_SOCKETS)
 | 
			
		||||
	return arg;
 | 
			
		||||
@@ -1325,14 +1331,6 @@ static void parseGeneralArguments() {
 | 
			
		||||
	case 'H':
 | 
			
		||||
		HostBuild = (uint16_t)getOptionArgumentInt((char)o, 0, 0xffff);
 | 
			
		||||
		ignoreIniFileParameter(INI_PARAM_HOST_BUILD);
 | 
			
		||||
 | 
			
		||||
#		ifdef _PEDANTIC
 | 
			
		||||
		if (!IsValidHostBuild(HostBuild))
 | 
			
		||||
		{
 | 
			
		||||
			printerrorf("Warning: %u is not a known released Windows Server build >= 2008.\n");
 | 
			
		||||
		}
 | 
			
		||||
#		endif // _PEDANTIC
 | 
			
		||||
 | 
			
		||||
		break;
 | 
			
		||||
#	endif // NO_RANDOM_PID
 | 
			
		||||
 | 
			
		||||
@@ -1437,7 +1435,7 @@ static void writePidFile()
 | 
			
		||||
 | 
			
		||||
	if (fn_pid && !InetdMode)
 | 
			
		||||
	{
 | 
			
		||||
		FILE *file = fopen(fn_pid, "w");
 | 
			
		||||
		FILE* file = fopen(fn_pid, "w");
 | 
			
		||||
 | 
			
		||||
		if (file)
 | 
			
		||||
		{
 | 
			
		||||
@@ -1455,8 +1453,8 @@ static void writePidFile()
 | 
			
		||||
			logger("Warning: Cannot write pid file '%s'. %s.\n", fn_pid, strerror(errno));
 | 
			
		||||
		}
 | 
			
		||||
#		endif // NO_LOG
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
#define writePidFile()
 | 
			
		||||
#endif // !defined(NO_PID_FILE)
 | 
			
		||||
@@ -1563,8 +1561,8 @@ static void allocateSemaphore(void)
 | 
			
		||||
			{
 | 
			
		||||
				printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(errno));
 | 
			
		||||
				MaxTasks = SEM_VALUE_MAX;
 | 
			
		||||
}
 | 
			
		||||
	}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#		endif // THREADS or CYGWIN
 | 
			
		||||
 | 
			
		||||
@@ -1577,7 +1575,7 @@ static void allocateSemaphore(void)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#		endif // _WIN32
 | 
			
		||||
}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__
 | 
			
		||||
 | 
			
		||||
@@ -1656,7 +1654,7 @@ int setupListeningSockets()
 | 
			
		||||
		if (haveIPv6Stack) addListeningSocket("::");
 | 
			
		||||
		if (haveIPv4Stack) addListeningSocket("0.0.0.0");
 | 
			
		||||
#		endif // !HAVE_GETIFADDR
 | 
			
		||||
}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!numsockets)
 | 
			
		||||
	{
 | 
			
		||||
@@ -1751,7 +1749,7 @@ int newmain()
 | 
			
		||||
#		ifndef NO_LOG
 | 
			
		||||
		logstdout = 0;
 | 
			
		||||
#		endif // !NO_LOG
 | 
			
		||||
}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#	endif // !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
 | 
			
		||||
 | 
			
		||||
@@ -1776,9 +1774,9 @@ int newmain()
 | 
			
		||||
			!IsNDR64Defined
 | 
			
		||||
			)
 | 
			
		||||
	{
 | 
			
		||||
		UseServerRpcNDR64 = !!KmsData->Flags & KMS_OPTIONS_USENDR64;
 | 
			
		||||
		UseServerRpcNDR64 = !!(KmsData->Flags & KMS_OPTIONS_USENDR64);
 | 
			
		||||
#		ifndef NO_RANDOM_EPID
 | 
			
		||||
		if (HostBuild&&RandomizationLevel)
 | 
			
		||||
		if (HostBuild && RandomizationLevel)
 | 
			
		||||
		{
 | 
			
		||||
			UseServerRpcNDR64 = HostBuild > 7601;
 | 
			
		||||
		}
 | 
			
		||||
@@ -1786,13 +1784,6 @@ int newmain()
 | 
			
		||||
	}
 | 
			
		||||
#	endif // !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
 | 
			
		||||
 | 
			
		||||
#	if !defined(NO_INI_FILE) || !defined(NO_CL_PIDS)
 | 
			
		||||
	if (KmsData->MinorVer < 6)
 | 
			
		||||
	{
 | 
			
		||||
		printerrorf("Warning: Need database version 1.6 or greater to set custom ePids\n");
 | 
			
		||||
	}
 | 
			
		||||
#	endif // !defined(NO_INI_FILE) || !defined(NO_CL_PIDS)
 | 
			
		||||
 | 
			
		||||
#	if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
 | 
			
		||||
	KmsResponseParameters = (KmsResponseParam_t*)vlmcsd_malloc(sizeof(KmsResponseParam_t) * KmsData->CsvlkCount);
 | 
			
		||||
	memset(KmsResponseParameters, 0, sizeof(KmsResponseParam_t) * KmsData->CsvlkCount);
 | 
			
		||||
@@ -1805,7 +1796,7 @@ int newmain()
 | 
			
		||||
	for (opterr = 0; (o = getopt(global_argc, (char* const*)global_argv, (const char*)optstring)) > 0; ) switch (o)
 | 
			
		||||
	{
 | 
			
		||||
	case 'a':
 | 
			
		||||
		if (KmsData->MinorVer < 6 || !handleIniFileEpidParameter(optarg, FALSE, "command line"))
 | 
			
		||||
		if (!handleIniFileEpidParameter(optarg, FALSE, "command line"))
 | 
			
		||||
		{
 | 
			
		||||
			usage();
 | 
			
		||||
		}
 | 
			
		||||
@@ -1892,7 +1883,7 @@ int newmain()
 | 
			
		||||
		{
 | 
			
		||||
			printerrorf("Fatal: %s for %s failed: %s\n", "setuid", uname, strerror(errno));
 | 
			
		||||
			return errno;
 | 
			
		||||
	}
 | 
			
		||||
		}
 | 
			
		||||
#	ifndef NO_SIGHUP
 | 
			
		||||
	}
 | 
			
		||||
#	endif // NO_SIGHUP
 | 
			
		||||
@@ -1905,6 +1896,22 @@ int newmain()
 | 
			
		||||
	// the lifetime of the process. So we generate them now
 | 
			
		||||
#	ifndef NO_RANDOM_EPID
 | 
			
		||||
	if (RandomizationLevel == 1) randomPidInit();
 | 
			
		||||
#   if !defined(NO_LOG) && !defined(NO_VERBOSE_LOG)
 | 
			
		||||
	if (logverbose)
 | 
			
		||||
	{
 | 
			
		||||
		int32_t i;
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < KmsData->CsvlkCount; i++)
 | 
			
		||||
		{
 | 
			
		||||
			const CsvlkData_t* const csvlk = KmsData->CsvlkData + i;
 | 
			
		||||
			const char* csvlkIniName = getNextString(csvlk->EPid);
 | 
			
		||||
			const char* csvlkFullName = getNextString(csvlkIniName);
 | 
			
		||||
			csvlkFullName = *csvlkFullName ? csvlkFullName : "unknown";
 | 
			
		||||
			const char* ePid = KmsResponseParameters[i].Epid ? KmsResponseParameters[i].Epid : RandomizationLevel == 2 ? "" : csvlk->EPid;
 | 
			
		||||
			logger("Using CSVLK %s (%s) with %s ePID %s\n", csvlkIniName, csvlkFullName, (RandomizationLevel == 1 && KmsResponseParameters[i].IsRandom) || (RandomizationLevel == 2 && !KmsResponseParameters[i].Epid) ? "random" : "fixed", ePid);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#   endif // !defined(NO_LOG) && !defined(NO_VERBOSE_LOG)
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
#	if !defined(NO_SOCKETS)
 | 
			
		||||
@@ -1950,12 +1957,12 @@ int newmain()
 | 
			
		||||
#if _MSC_VER && !defined(_DEBUG)&& !MULTI_CALL_BINARY
 | 
			
		||||
int __stdcall WinStartUp(void)
 | 
			
		||||
{
 | 
			
		||||
	WCHAR **szArgList;
 | 
			
		||||
	WCHAR** szArgList;
 | 
			
		||||
	int argc;
 | 
			
		||||
	szArgList = CommandLineToArgvW(GetCommandLineW(), &argc);
 | 
			
		||||
 | 
			
		||||
	int i;
 | 
			
		||||
	char **argv = (char**)vlmcsd_malloc(sizeof(char*)*argc);
 | 
			
		||||
	char** argv = (char**)vlmcsd_malloc(sizeof(char*) * argc);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < argc; i++)
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ int server_main(int argc, CARGV argv);
 | 
			
		||||
#define SA_NOCLDWAIT 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef NO_INI_FILE
 | 
			
		||||
#if !defined(NO_INI_FILE) || !defined(NO_CL_PIDS)
 | 
			
		||||
#define INI_PARAM_RANDOMIZATION_LEVEL 1
 | 
			
		||||
#define INI_PARAM_LCID 2
 | 
			
		||||
#define INI_PARAM_LISTEN 3
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								src/wintap.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/wintap.c
									
									
									
									
									
								
							@@ -42,7 +42,7 @@ static BOOL isAddressAssigned()
 | 
			
		||||
	BOOL result = FALSE;
 | 
			
		||||
 | 
			
		||||
	pIPAddrTable = (PMIB_IPADDRTABLE)vlmcsd_malloc(sizeof(MIB_IPADDRTABLE));
 | 
			
		||||
	DWORD status = GetIpAddrTable(pIPAddrTable, &dwSize, 0);
 | 
			
		||||
	const DWORD status = GetIpAddrTable(pIPAddrTable, &dwSize, 0);
 | 
			
		||||
	free(pIPAddrTable);
 | 
			
		||||
 | 
			
		||||
	if (status != ERROR_INSUFFICIENT_BUFFER) return FALSE;
 | 
			
		||||
@@ -74,16 +74,16 @@ static BOOL isAddressAssigned()
 | 
			
		||||
 | 
			
		||||
static void parseTapArgument(char* argument)
 | 
			
		||||
{
 | 
			
		||||
	char* equalsignPosition = strchr(argument, (int)'=');
 | 
			
		||||
	char* equalSignPosition = strchr(argument, (int)'=');
 | 
			
		||||
	char* slashPosition = strchr(argument, (int)'/');
 | 
			
		||||
	char* colonPosition = strchr(argument, (int)':');
 | 
			
		||||
 | 
			
		||||
	szTapName = argument;
 | 
			
		||||
 | 
			
		||||
	if (equalsignPosition)
 | 
			
		||||
	if (equalSignPosition)
 | 
			
		||||
	{
 | 
			
		||||
		*equalsignPosition = 0;
 | 
			
		||||
		szIpAddress = equalsignPosition + 1;
 | 
			
		||||
		*equalSignPosition = 0;
 | 
			
		||||
		szIpAddress = equalSignPosition + 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (slashPosition)
 | 
			
		||||
@@ -166,10 +166,10 @@ static HANDLE OpenTapHandle()
 | 
			
		||||
		WinErrorExit(regResult);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char subkeyName[TAP_REGISTRY_DATA_SIZE];
 | 
			
		||||
	DWORD i, subKeySize = sizeof(subkeyName);
 | 
			
		||||
	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++)
 | 
			
		||||
	for (i = 0; (regResult = RegEnumKeyEx(regAdapterKey, i, subKeyName, &subKeySize, NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS; i++)
 | 
			
		||||
	{
 | 
			
		||||
		HKEY regSubKey;
 | 
			
		||||
		DWORD type, regDataSize;
 | 
			
		||||
@@ -177,7 +177,7 @@ static HANDLE OpenTapHandle()
 | 
			
		||||
 | 
			
		||||
		if (regResult) WinErrorExit(regResult);
 | 
			
		||||
 | 
			
		||||
		if ((regResult = RegOpenKeyEx(regAdapterKey, subkeyName, 0, KEY_READ | KEY_WOW64_64KEY, ®SubKey)) == ERROR_SUCCESS)
 | 
			
		||||
		if ((regResult = RegOpenKeyEx(regAdapterKey, subKeyName, 0, KEY_READ | KEY_WOW64_64KEY, ®SubKey)) == ERROR_SUCCESS)
 | 
			
		||||
		{
 | 
			
		||||
			regDataSize = sizeof(regData);
 | 
			
		||||
 | 
			
		||||
@@ -201,8 +201,8 @@ static HANDLE OpenTapHandle()
 | 
			
		||||
						char connectionKeyName[TAP_REGISTRY_DATA_SIZE];
 | 
			
		||||
 | 
			
		||||
						strncpy(connectionKeyName, NETWORK_CONNECTIONS_KEY "\\", sizeof(connectionKeyName));
 | 
			
		||||
						strncat(connectionKeyName, regData, sizeof(connectionKeyName));
 | 
			
		||||
						strncat(connectionKeyName, "\\Connection", sizeof(connectionKeyName));
 | 
			
		||||
						strncat(connectionKeyName, regData, sizeof(connectionKeyName) - strlen(connectionKeyName) - 1);
 | 
			
		||||
						strncat(connectionKeyName, "\\Connection", sizeof(connectionKeyName) - strlen(connectionKeyName) - 1);
 | 
			
		||||
 | 
			
		||||
						if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, connectionKeyName, 0, KEY_READ | KEY_WOW64_64KEY, &connectionKey) == ERROR_SUCCESS)
 | 
			
		||||
						{
 | 
			
		||||
@@ -215,8 +215,8 @@ static HANDLE OpenTapHandle()
 | 
			
		||||
								{
 | 
			
		||||
									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));
 | 
			
		||||
									strncat(deviceName, regData, sizeof(deviceName) - strlen(deviceName) - 1);
 | 
			
		||||
									strncat(deviceName, strcmp(AdapterClass, "TEAMVIEWERVPN") ? TAP_WIN_SUFFIX : ".dgt", sizeof(deviceName) - strlen(deviceName) - 1);
 | 
			
		||||
									handle = CreateFile(deviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
@@ -231,7 +231,7 @@ static HANDLE OpenTapHandle()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		RegCloseKey(regSubKey);
 | 
			
		||||
		subKeySize = sizeof(subkeyName);
 | 
			
		||||
		subKeySize = sizeof(subKeyName);
 | 
			
		||||
		if (handle != INVALID_HANDLE_VALUE) break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user