mirror of
https://github.com/Wind4/vlmcsd.git
synced 2025-06-24 04:34:31 +02:00
vlmcsd-1111-2017-06-17-Hotbird64
This commit is contained in:
@ -63,7 +63,7 @@ WCHAR utf8_to_ucs2_char(const unsigned char *input, const unsigned char **end_pt
|
||||
{
|
||||
*end_ptr = input;
|
||||
if (input[0] == 0)
|
||||
return ~0;
|
||||
return (WCHAR)~0;
|
||||
|
||||
if (input[0] < 0x80) {
|
||||
*end_ptr = input + 1;
|
||||
@ -73,7 +73,7 @@ WCHAR utf8_to_ucs2_char(const unsigned char *input, const unsigned char **end_pt
|
||||
if ((input[0] & 0xE0) == 0xE0) {
|
||||
|
||||
if (input[1] == 0 || input[2] == 0)
|
||||
return ~0;
|
||||
return (WCHAR)~0;
|
||||
|
||||
*end_ptr = input + 3;
|
||||
|
||||
@ -85,7 +85,7 @@ WCHAR utf8_to_ucs2_char(const unsigned char *input, const unsigned char **end_pt
|
||||
|
||||
if ((input[0] & 0xC0) == 0xC0) {
|
||||
if (input[1] == 0)
|
||||
return ~0;
|
||||
return (WCHAR)~0;
|
||||
|
||||
*end_ptr = input + 2;
|
||||
|
||||
@ -93,7 +93,7 @@ WCHAR utf8_to_ucs2_char(const unsigned char *input, const unsigned char **end_pt
|
||||
LE16((input[0] & 0x1F) << 6 |
|
||||
(input[1] & 0x3F));
|
||||
}
|
||||
return ~0;
|
||||
return (WCHAR)~0;
|
||||
}
|
||||
|
||||
// Convert one character from UCS2 to UTF-8
|
||||
@ -110,8 +110,8 @@ int ucs2_to_utf8_char(const WCHAR ucs2_le, char *utf8)
|
||||
}
|
||||
|
||||
if (ucs2 >= 0x80 && ucs2 < 0x800) {
|
||||
utf8[0] = (ucs2 >> 6) | 0xC0;
|
||||
utf8[1] = (ucs2 & 0x3F) | 0x80;
|
||||
utf8[0] = (char)((ucs2 >> 6) | 0xC0);
|
||||
utf8[1] = (char)((ucs2 & 0x3F) | 0x80);
|
||||
utf8[2] = '\0';
|
||||
return 2;
|
||||
}
|
||||
@ -596,13 +596,25 @@ void loadKmsData()
|
||||
if (!InetdMode) logger("Read KMS data file %s\n", fn_data);
|
||||
# endif // NO_LOG
|
||||
}
|
||||
|
||||
if (KmsData->CsvlkCount < MIN_CSVLK)
|
||||
{
|
||||
printerrorf("Warning: Legacy database: Some products are missing.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# endif // NO_EXTERNAL_DATA
|
||||
|
||||
# if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
|
||||
KmsResponseParameters = (KmsResponseParam_t*)realloc(KmsResponseParameters, KmsData->CsvlkCount * sizeof(KmsResponseParam_t));
|
||||
if (!KmsResponseParameters) OutOfMemory();
|
||||
memset(KmsResponseParameters + MIN_CSVLK, 0, (KmsData->CsvlkCount - MIN_CSVLK) * sizeof(KmsResponseParam_t));
|
||||
|
||||
if (KmsData->CsvlkCount > MIN_CSVLK)
|
||||
{
|
||||
KmsResponseParameters = (KmsResponseParam_t*)realloc(KmsResponseParameters, KmsData->CsvlkCount * sizeof(KmsResponseParam_t));
|
||||
if (!KmsResponseParameters) OutOfMemory();
|
||||
memset(KmsResponseParameters + MIN_CSVLK, 0, (KmsData->CsvlkCount - MIN_CSVLK) * sizeof(KmsResponseParam_t));
|
||||
}
|
||||
|
||||
# endif // !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
|
||||
|
||||
# ifndef UNSAFE_DATA_LOAD
|
||||
|
28
src/kms.c
28
src/kms.c
@ -91,13 +91,13 @@ static const uint16_t LcidList[] = {
|
||||
|
||||
|
||||
#ifdef _PEDANTIC
|
||||
uint16_t IsValidLcid(const uint16_t Lcid)
|
||||
uint16_t IsValidLcid(const uint16_t lcid)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < vlmcsd_countof(LcidList); i++)
|
||||
{
|
||||
if (Lcid == LcidList[i]) return Lcid;
|
||||
if (lcid == LcidList[i]) return lcid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -297,7 +297,7 @@ static void generateRandomPid(int index, char *const szPid, int serverType, int1
|
||||
|
||||
# define minTime ((time_t)1470175200) /* Release Date Win 2016 */
|
||||
|
||||
time_t maxTime, kmsTime;
|
||||
time_t maxTime;
|
||||
time(&maxTime);
|
||||
|
||||
# ifndef BUILD_TIME
|
||||
@ -307,10 +307,8 @@ static void generateRandomPid(int index, char *const szPid, int serverType, int1
|
||||
if (maxTime < (time_t)BUILD_TIME) // Just in case the system time is < 10/17/2013 1:00 pm
|
||||
maxTime = (time_t)BUILD_TIME;
|
||||
|
||||
kmsTime = (rand32() % (maxTime - minTime)) + minTime;
|
||||
|
||||
struct tm *pidTime;
|
||||
pidTime = gmtime(&kmsTime);
|
||||
time_t kmsTime = (rand32() % (maxTime - minTime)) + minTime;
|
||||
struct tm *pidTime = gmtime(&kmsTime);
|
||||
|
||||
strcat(szPid, itoc(numberBuffer, pidTime->tm_yday, 3));
|
||||
strcat(szPid, itoc(numberBuffer, pidTime->tm_year + 1900, 4));
|
||||
@ -516,7 +514,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)
|
||||
static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr_unused)
|
||||
{
|
||||
const char* EpidSource;
|
||||
#ifndef NO_LOG
|
||||
@ -730,8 +728,7 @@ __pure static uint64_t TimestampInterval(void *ts)
|
||||
static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptSize, int_fast8_t tolerance)
|
||||
{
|
||||
BYTE hash[32];
|
||||
# define halfHashSize (sizeof(hash) >> 1)
|
||||
uint64_t timeSlot;
|
||||
const uint8_t halfHashSize = sizeof(hash) >> 1;
|
||||
BYTE *responseEnd = encrypt_start + encryptSize;
|
||||
|
||||
// This is the time from the response
|
||||
@ -742,7 +739,7 @@ static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptS
|
||||
// When generating a response tolerance must be 0.
|
||||
// If verifying the hash, try tolerance -1, 0 and +1. One of them must match.
|
||||
|
||||
timeSlot = LE64((GET_UA64LE(ft) / TIME_C1 * TIME_C2 + TIME_C3) + (tolerance * TIME_C1));
|
||||
uint64_t timeSlot = LE64((GET_UA64LE(ft) / TIME_C1 * TIME_C2 + TIME_C3) + (tolerance * TIME_C1));
|
||||
|
||||
// The time slot is hashed with SHA256 so it is not so obvious that it is time
|
||||
Sha256((BYTE*)&timeSlot, sizeof(timeSlot), hash);
|
||||
@ -761,7 +758,6 @@ static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptS
|
||||
|
||||
memcpy(responseEnd - sizeof(((RESPONSE_V6*)0)->HMAC), hash + halfHashSize, halfHashSize);
|
||||
return TRUE;
|
||||
# undef halfHashSize
|
||||
}
|
||||
|
||||
|
||||
@ -782,7 +778,7 @@ size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuf
|
||||
|
||||
#ifdef _DEBUG
|
||||
// ReSharper disable once CppEntityNeverUsed
|
||||
RESPONSE_V6_DEBUG* xxx = (RESPONSE_V6_DEBUG*)responseBuffer;
|
||||
RESPONSE_V6_DEBUG* xxx_unused = (RESPONSE_V6_DEBUG*)responseBuffer;
|
||||
#endif
|
||||
|
||||
static const BYTE DefaultHwid[8] = { HWID };
|
||||
@ -955,7 +951,7 @@ RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* response_v4, const int responseSi
|
||||
}
|
||||
|
||||
|
||||
static RESPONSE_RESULT VerifyResponseV6(RESPONSE_RESULT result, const AesCtx* Ctx, RESPONSE_V6* response_v6, REQUEST_V6* request_v6, BYTE* const rawResponse)
|
||||
static RESPONSE_RESULT VerifyResponseV6(RESPONSE_RESULT result, RESPONSE_V6* response_v6, REQUEST_V6* request_v6, BYTE* const rawResponse)
|
||||
{
|
||||
// Check IVs
|
||||
result.IVsOK = !memcmp // In V6 the XoredIV is actually the request IV
|
||||
@ -1029,7 +1025,7 @@ static RESPONSE_RESULT VerifyResponseV5(RESPONSE_RESULT result, REQUEST_V5* requ
|
||||
RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BYTE* const response, const BYTE* const rawRequest, BYTE* hwid)
|
||||
{
|
||||
RESPONSE_RESULT result;
|
||||
result.mask = ~0; // Set all bits in the results mask to 1. Assume success first.
|
||||
result.mask = (DWORD)~0; // Set all bits in the results mask to 1. Assume success first.
|
||||
result.effectiveResponseSize = responseSize;
|
||||
|
||||
int copySize1 =
|
||||
@ -1126,7 +1122,7 @@ RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BY
|
||||
memcpy(hwid, response_v6->HwId, sizeof(response_v6->HwId));
|
||||
|
||||
// Verify the V6 specific part of the response
|
||||
result = VerifyResponseV6(result, &Ctx, response_v6, request_v6, response);
|
||||
result = VerifyResponseV6(result, response_v6, request_v6, response);
|
||||
}
|
||||
else // V5
|
||||
{
|
||||
|
@ -258,12 +258,6 @@ typedef struct VlmcsdData
|
||||
char* Name;
|
||||
};
|
||||
|
||||
//union
|
||||
//{
|
||||
// uint64_t X_EPidOffset;
|
||||
// char* X_EPid;
|
||||
//};
|
||||
|
||||
uint8_t AppIndex;
|
||||
uint8_t KmsIndex;
|
||||
uint8_t ProtocolVersion;
|
||||
@ -337,6 +331,7 @@ typedef struct VlmcsdHeader
|
||||
#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);
|
||||
|
||||
|
1475
src/kmsdata-full.c
1475
src/kmsdata-full.c
File diff suppressed because it is too large
Load Diff
1692
src/kmsdata.c
1692
src/kmsdata.c
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,6 @@ SERVICE_STATUS_HANDLE gSvcStatusHandle;
|
||||
VOID WINAPI ServiceCtrlHandler(DWORD dwCtrl)
|
||||
{
|
||||
// Handle the requested control code.
|
||||
|
||||
switch (dwCtrl)
|
||||
{
|
||||
case SERVICE_CONTROL_STOP:
|
||||
|
@ -406,7 +406,7 @@ static void CheckRpcBindRequest(const RPC_BIND_REQUEST *const Request, const uns
|
||||
/*
|
||||
* Check, if we receive enough bytes to return a valid RPC bind response
|
||||
*/
|
||||
static unsigned int checkRpcBindSize(const RPC_BIND_REQUEST *const Request, const unsigned int RequestSize, WORD* NdrCtx, WORD* Ndr64Ctx)
|
||||
static unsigned int checkRpcBindSize(const RPC_BIND_REQUEST *const Request, const unsigned int RequestSize, WORD* NdrCtx_unused, WORD* Ndr64Ctx_unused)
|
||||
{
|
||||
if (RequestSize < sizeof(RPC_BIND_REQUEST)) return FALSE;
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
||||
#include "types.h"
|
||||
#include "kms.h"
|
||||
|
||||
#define MIN_CSVLK 4
|
||||
#define MIN_CSVLK 5
|
||||
typedef struct
|
||||
{
|
||||
const char* Epid;
|
||||
|
33
src/vlmcsd.c
33
src/vlmcsd.c
@ -84,7 +84,7 @@
|
||||
#include "wintap.h"
|
||||
#endif
|
||||
|
||||
static const char* const optstring = "N:B:m:t:w:0:3:6:H:A:R:u:g:L:p:i:P:l:r:U:W:C:c:F:O:o:x:T:K:E:M:j:SseDdVvqkZ";
|
||||
static const char* const optstring = "N:B:m:t:w:0:3:6:H:A:R:u:G:g:L:p:i:P:l:r:U:W:C:c:F:O:o:x:T:K:E:M:j:SseDdVvqkZ";
|
||||
|
||||
#if !defined(NO_SOCKETS) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
|
||||
static uint_fast8_t maxsockets = 0;
|
||||
@ -123,6 +123,7 @@ static IniFileParameter_t IniFileParameterList[] =
|
||||
{ "Office2010", INI_PARAM_OFFICE2010 },
|
||||
{ "Office2013", INI_PARAM_OFFICE2013 },
|
||||
{ "Office2016", INI_PARAM_OFFICE2016 },
|
||||
{ "WinChinaGov", INI_PARAM_WINCHINAGOV },
|
||||
# ifndef NO_SOCKETS
|
||||
{ "ExitLevel", INI_PARAM_EXIT_LEVEL },
|
||||
# endif // NO_SOCKETS
|
||||
@ -274,6 +275,7 @@ static __noreturn void usage()
|
||||
" -0 <ePID>\t\talways use <ePID> for Office2010\n"
|
||||
" -3 <ePID>\t\talways use <ePID> for Office2013\n"
|
||||
" -6 <ePID>\t\talways use <ePID> for Office2016\n"
|
||||
" -G <ePID>\t\talways use <ePID> for Win China Gov\n"
|
||||
" -H <HwId>\t\talways use hardware Id <HwId>\n"
|
||||
# endif // NO_CL_PIDS
|
||||
# if !defined(_WIN32) && !defined(NO_USER_SWITCH)
|
||||
@ -404,9 +406,9 @@ __pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restr
|
||||
#endif // NO_INI_FILE
|
||||
|
||||
|
||||
__pure static DWORD getTimeSpanFromCommandLine(const char *const restrict optarg, const char optchar)
|
||||
__pure static DWORD getTimeSpanFromCommandLine(const char *const restrict arg, const char optchar)
|
||||
{
|
||||
DWORD val = timeSpanString2Minutes(optarg);
|
||||
DWORD val = timeSpanString2Minutes(arg);
|
||||
|
||||
if (!val)
|
||||
{
|
||||
@ -553,6 +555,11 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
|
||||
setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2016);
|
||||
break;
|
||||
|
||||
case INI_PARAM_WINCHINAGOV:
|
||||
setEpidFromIniFileLine(&s, EPID_INDEX_WINCHINAGOV);
|
||||
setHwIdFromIniFileLine(&s, EPID_INDEX_WINCHINAGOV);
|
||||
break;
|
||||
|
||||
# ifndef NO_TAP
|
||||
|
||||
case INI_PARAM_VPN:
|
||||
@ -1050,14 +1057,14 @@ 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 optarg)
|
||||
__pure static char* getCommandLineArg(char *const restrict arg)
|
||||
{
|
||||
# if !__CYGWIN__ || defined(USE_THREADS) || defined(NO_SOCKETS)
|
||||
return optarg;
|
||||
return arg;
|
||||
# else
|
||||
if (!IsNTService) return optarg;
|
||||
if (!IsNTService) return arg;
|
||||
|
||||
return vlmcsd_strdup(optarg);
|
||||
return vlmcsd_strdup(arg);
|
||||
# endif
|
||||
}
|
||||
#endif // !defined(NO_INI_FILE) || !defined(NO_LOG) || !defined(NO_CL_PIDS) || !defined(NO_EXTERNAL_DATA)
|
||||
@ -1118,6 +1125,13 @@ static void parseGeneralArguments() {
|
||||
# endif // NO_LOG
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
KmsResponseParameters[EPID_INDEX_WINCHINAGOV].Epid = getCommandLineArg(optarg);
|
||||
# ifndef NO_LOG
|
||||
KmsResponseParameters[EPID_INDEX_WINCHINAGOV].EpidSource = "command line";
|
||||
# endif // NO_LOG
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6 *)0)->HwId));
|
||||
hex2bin(HwId, optarg, sizeof(((RESPONSE_V6 *)0)->HwId));
|
||||
@ -1125,6 +1139,7 @@ static void parseGeneralArguments() {
|
||||
KmsResponseParameters[EPID_INDEX_WINDOWS].HwId =
|
||||
KmsResponseParameters[EPID_INDEX_OFFICE2010].HwId =
|
||||
KmsResponseParameters[EPID_INDEX_OFFICE2013].HwId =
|
||||
KmsResponseParameters[EPID_INDEX_WINCHINAGOV].HwId =
|
||||
KmsResponseParameters[EPID_INDEX_OFFICE2016].HwId = HwId;
|
||||
break;
|
||||
|
||||
@ -1146,7 +1161,7 @@ static void parseGeneralArguments() {
|
||||
|
||||
case 'x':
|
||||
ignoreIniFileParameter(INI_PARAM_EXIT_LEVEL);
|
||||
ExitLevel = getOptionArgumentInt((char)o, 0, 1);
|
||||
ExitLevel = (int_fast8_t)getOptionArgumentInt((char)o, 0, 1);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
@ -1581,7 +1596,7 @@ int setupListeningSockets()
|
||||
char** privateIPList = NULL;
|
||||
int numPrivateIPs = 0;
|
||||
if (PublicIPProtectionLevel & 1) getPrivateIPAddresses(&numPrivateIPs, &privateIPList);
|
||||
uint_fast8_t allocsockets = maxsockets ? (maxsockets + numPrivateIPs) : ((PublicIPProtectionLevel & 1) ? numPrivateIPs : 2);
|
||||
uint_fast8_t allocsockets = (uint_fast8_t)(maxsockets ? (maxsockets + numPrivateIPs) : ((PublicIPProtectionLevel & 1) ? numPrivateIPs : 2));
|
||||
# else // !HAVE_GETIFADDR
|
||||
uint_fast8_t allocsockets = maxsockets ? maxsockets : 2;
|
||||
# endif // !HAVE_GETIFADDR
|
||||
|
@ -59,6 +59,7 @@ int server_main(int argc, CARGV argv);
|
||||
#define INI_PARAM_DATA_FILE 28
|
||||
#define INI_PARAM_VPN 29
|
||||
#define INI_PARAM_EXIT_LEVEL 30
|
||||
#define INI_PARAM_WINCHINAGOV 31
|
||||
|
||||
#define INI_FILE_PASS_1 1
|
||||
#define INI_FILE_PASS_2 2
|
||||
|
@ -271,7 +271,7 @@ static int DevCtl(DWORD code, void* data, DWORD len)
|
||||
}
|
||||
|
||||
|
||||
static DWORD WINAPI TapMirror(LPVOID data)
|
||||
static DWORD WINAPI TapMirror(LPVOID data_unused)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
|
Reference in New Issue
Block a user