vlmcsd-1112-2019-10-20-Hotbird64

This commit is contained in:
Rouben
2018-10-23 23:40:18 -04:00
parent 28a50f7bba
commit cd488aeb85
39 changed files with 7175 additions and 3782 deletions

View File

@ -544,7 +544,7 @@ static void getDefaultDataFile()
char* fn_exe_copy = vlmcsd_strdup(fn_exe);
strncpy(fileName, dirname(fn_exe_copy), 512);
free(fn_exe_copy);
strncat(fileName, "/vlmcsd.kmd", 512);
strncat(fileName, "/vlmcsd.kmd", 500);
fn_data = vlmcsd_strdup(fileName);
}
#endif // !_WIN32
@ -593,30 +593,14 @@ void loadKmsData()
fclose(file);
# if !defined(NO_LOG) && !defined(NO_SOCKETS)
if (!InetdMode) logger("Read KMS data file %s\n", fn_data);
if (!InetdMode) logger("Read KMS data file version %u.%u %s\n", (unsigned int)KmsData->MajorVer, (unsigned int)KmsData->MinorVer, 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)
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
if (((BYTE*)KmsData)[size - 1] != 0) dataFileFormatError();
# endif // UNSAFE_DATA_LOAD
@ -652,7 +636,7 @@ void loadKmsData()
# endif // NO_RANDOM_EPID
}
uint32_t totalItemCount = KmsData->AppItemCount + KmsData->KmsItemCount + KmsData->SkuItemCount;
const uint32_t totalItemCount = KmsData->AppItemCount + KmsData->KmsItemCount + KmsData->SkuItemCount;
# ifndef NO_EXTERNAL_DATA
if (

2287
src/kms.c

File diff suppressed because it is too large Load Diff

View File

@ -278,12 +278,15 @@ typedef struct
};
} DataPointer_t;
#define KMS_OPTIONS_USENDR64 1 << 0
typedef struct VlmcsdHeader
{
BYTE Magic[4];
VERSION_INFO;
uint8_t CsvlkCount;
uint8_t Reserved[3];
uint8_t Flags;
uint8_t Reserved[2];
union
{
@ -358,7 +361,8 @@ void CleanUpClientLists();
extern RequestCallback_t CreateResponseBase;
#ifdef _PEDANTIC
uint16_t IsValidLcid(const uint16_t Lcid);
uint16_t IsValidLcid(const uint16_t lcid);
uint16_t IsValidHostBuild(const uint16_t hostBuild);
#endif // _PEDANTIC
#endif // __kms_h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -99,7 +99,7 @@ static int_fast8_t getSocketList(struct addrinfo **saList, const char *const add
{
int status;
char *szHost, *szPort;
size_t len = strlen(addr) + 1;
const size_t len = strlen(addr) + 1;
// Don't alloca too much
if (len > 264) return FALSE;
@ -156,7 +156,7 @@ int_fast8_t isDisconnected(const SOCKET s)
if (!setBlockingEnabled(s, FALSE)) return TRUE;
int n = recv(s, buffer, 1, MSG_PEEK);
const int n = recv(s, buffer, 1, MSG_PEEK);
if (!setBlockingEnabled(s, TRUE)) return TRUE;
if (n == 0) return TRUE;
@ -200,7 +200,7 @@ static int_fast8_t isPrivateIPAddress(struct sockaddr* addr, socklen_t* length)
case AF_INET:
{
uint32_t ipv4addr = BE32(((struct sockaddr_in*)addr)->sin_addr.s_addr);
const uint32_t ipv4addr = BE32(((struct sockaddr_in*)addr)->sin_addr.s_addr);
if
(
@ -244,11 +244,7 @@ SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fas
if (ip2str(szAddr, sizeof(szAddr), sa->ai_addr, (socklen_t)sa->ai_addrlen))
{
if (showHostName)
printf("Connecting to %s (%s) ... ", addr, szAddr);
else
printf("Connecting to %s ... ", szAddr);
showHostName ? printf("Connecting to %s (%s) ... ", addr, szAddr) : printf("Connecting to %s ... ", szAddr);
fflush(stdout);
}
@ -394,7 +390,7 @@ void getPrivateIPAddresses(int* numAddresses, char*** ipAddresses)
DWORD dwRetVal;
ULONG outBufLen = 16384;
ULONG flags = GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
const ULONG flags = GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
firstAdapter = (PIP_ADAPTER_ADDRESSES)vlmcsd_malloc(outBufLen);
@ -438,7 +434,7 @@ void getPrivateIPAddresses(int* numAddresses, char*** ipAddresses)
if (!isPrivateIPAddress(currentAddress->Address.lpSockaddr, &length)) continue;
char *ipAddress = (char*)vlmcsd_malloc(64);
int error = getnameinfo(currentAddress->Address.lpSockaddr, currentAddress->Address.iSockaddrLength, ipAddress, 64, NULL, 0, NI_NUMERICHOST);
const int error = getnameinfo(currentAddress->Address.lpSockaddr, currentAddress->Address.iSockaddrLength, ipAddress, 64, NULL, 0, NI_NUMERICHOST);
if (error)
{
@ -683,7 +679,7 @@ __pure int_fast8_t checkProtocolStack(const int addressfamily)
SOCKET s; // = INVALID_SOCKET;
s = socket(addressfamily, SOCK_STREAM, 0);
int_fast8_t success = (s != INVALID_SOCKET);
const int_fast8_t success = (s != INVALID_SOCKET);
socketclose(s);
return success;
@ -768,7 +764,7 @@ static void serveClient(const SOCKET s_client, const DWORD RpcAssocGroup)
# if !defined(NO_LOG) && defined(_PEDANTIC)
int result =
const int result =
setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to)) ||
setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));

View File

@ -29,7 +29,7 @@
/* Forwards */
static int checkRpcHeader(const RPC_HEADER *const Header, const BYTE desiredPacketType, const PRINTFUNC p);
static int checkRpcHeader(const RPC_HEADER *const header, const BYTE desiredPacketType, const PRINTFUNC p);
/* Data definitions */
@ -254,7 +254,7 @@ static int rpcRequest(const RPC_REQUEST64 *const Request, RPC_RESPONSE64 *const
# ifndef SIMPLE_RPC
WORD Ctx = LE16(Request->ContextId);
const WORD Ctx = LE16(Request->ContextId);
if (Ctx == *NdrCtx)
{
@ -282,7 +282,7 @@ static int rpcRequest(const RPC_REQUEST64 *const Request, RPC_RESPONSE64 *const
if (isValid)
{
uint16_t majorIndex = LE16(((WORD*)requestData)[1]) - 4;
const uint16_t majorIndex = LE16(((WORD*)requestData)[1]) - 4;
if (!((ResponseSize = _Versions[majorIndex].CreateResponse(requestData, responseData, ipstr)))) ResponseSize = 0x8007000D;
}
@ -329,7 +329,7 @@ static int rpcRequest(const RPC_REQUEST64 *const Request, RPC_RESPONSE64 *const
len += sizeof(DWORD);
// Pad zeros to 32-bit align (seems not neccassary but Windows RPC does it this way)
int pad = ((~len & 3) + 1) & 3;
const int pad = ((~len & 3) + 1) & 3;
memset(pRpcReturnCode + sizeof(DWORD), 0, pad);
len += pad;
@ -348,8 +348,8 @@ static void CheckRpcBindRequest(const RPC_BIND_REQUEST *const Request, const uns
uint_fast8_t i, HasTransferSyntaxNDR32 = FALSE;
char guidBuffer1[GUID_STRING_LENGTH + 1], guidBuffer2[GUID_STRING_LENGTH + 1];
uint32_t CapCtxItems = (len - sizeof(*Request) + sizeof(Request->CtxItems)) / sizeof(Request->CtxItems);
DWORD NumCtxItems = LE32(Request->NumCtxItems);
const uint32_t CapCtxItems = (len - sizeof(*Request) + sizeof(Request->CtxItems)) / sizeof(Request->CtxItems);
const DWORD NumCtxItems = LE32(Request->NumCtxItems);
if (NumCtxItems < CapCtxItems) // Can't be too small because already handled by RpcBindSize
logger("Warning: Excess bytes in RPC bind request.\n");
@ -410,7 +410,7 @@ static unsigned int checkRpcBindSize(const RPC_BIND_REQUEST *const Request, cons
{
if (RequestSize < sizeof(RPC_BIND_REQUEST)) return FALSE;
unsigned int numCtxItems = LE32(Request->NumCtxItems);
const unsigned int numCtxItems = LE32(Request->NumCtxItems);
if (RequestSize < sizeof(RPC_BIND_REQUEST) - sizeof(Request->CtxItems[0]) + numCtxItems * sizeof(Request->CtxItems[0])) return FALSE;
@ -432,7 +432,7 @@ static unsigned int checkRpcBindSize(const RPC_BIND_REQUEST *const Request, cons
static int rpcBind(const RPC_BIND_REQUEST *const Request, RPC_BIND_RESPONSE* Response, const DWORD RpcAssocGroup, const SOCKET sock, WORD* NdrCtx, WORD* Ndr64Ctx, BYTE packetType, const char* const ipstr_unused)
{
unsigned int i;
DWORD numCtxItems = LE32(Request->NumCtxItems);
const DWORD numCtxItems = LE32(Request->NumCtxItems);
int_fast8_t IsNDR64possible = FALSE;
uint_fast8_t portNumberSize;
@ -504,7 +504,7 @@ static int rpcBind(const RPC_BIND_REQUEST *const Request, RPC_BIND_RESPONSE* Res
memset(&result->TransferSyntax, 0, sizeof(GUID));
# ifndef SIMPLE_RPC
int isInterfaceUUID = IsEqualGUID(&Request->CtxItems[i].InterfaceUUID, (GUID*)InterfaceUuid);
const int isInterfaceUUID = IsEqualGUID(&Request->CtxItems[i].InterfaceUUID, (GUID*)InterfaceUuid);
if (isInterfaceUUID) nackReason = RPC_SYNTAX_UNSUPPORTED;
# else // SIMPLE_RPC
# define isInterfaceUUID TRUE
@ -809,7 +809,7 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const kmsRequest, const
RPC_REQUEST64 *RpcRequest;
RPC_RESPONSE64 _Response;
int status;
int_fast8_t useNdr64 = RpcFlags.HasNDR64 && UseClientRpcNDR64 && firstPacketSent;
const int_fast8_t useNdr64 = RpcFlags.HasNDR64 && UseClientRpcNDR64 && firstPacketSent;
size_t size = sizeof(RPC_HEADER) + (useNdr64 ? sizeof(RPC_REQUEST64) : sizeof(RPC_REQUEST)) + requestSize;
size_t responseSize2;
@ -949,8 +949,8 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const kmsRequest, const
DWORD *pReturnCode;
size_t len = *responseSize + (useNdr64 ? sizeof(_Response.Ndr64) : sizeof(_Response.Ndr)) + sizeof(*pReturnCode);
size_t pad = ((~len & 3) + 1) & 3;
const size_t len = *responseSize + (useNdr64 ? sizeof(_Response.Ndr64) : sizeof(_Response.Ndr)) + sizeof(*pReturnCode);
const size_t pad = ((~len & 3) + 1) & 3;
if (len + pad != LE32(_Response.AllocHint))
{
@ -982,7 +982,7 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const kmsRequest, const
}
static int_fast8_t IsNullGuid(BYTE* guidPtr)
static int_fast8_t IsNullGuid(const BYTE* guidPtr)
{
int_fast8_t i;
@ -1005,8 +1005,8 @@ static RpcStatus rpcBindOrAlterClientContext(const RpcCtx sock, const BYTE packe
RPC_BIND_REQUEST *bindRequest;
RPC_BIND_RESPONSE *bindResponse;
int status;
WORD ctxItems = 1 + (packetType == RPC_PT_BIND_REQ ? UseClientRpcNDR64 + UseClientRpcBTFN : 0);
size_t rpcBindSize = (sizeof(RPC_HEADER) + sizeof(RPC_BIND_REQUEST) + (ctxItems - 1) * sizeof(bindRequest->CtxItems[0]));
const WORD ctxItems = 1 + (packetType == RPC_PT_BIND_REQ ? UseClientRpcNDR64 + UseClientRpcBTFN : 0);
const size_t rpcBindSize = (sizeof(RPC_HEADER) + sizeof(RPC_BIND_REQUEST) + (ctxItems - 1) * sizeof(bindRequest->CtxItems[0]));
WORD ctxIndex = 0;
WORD i;
WORD CtxBTFN = RPC_INVALID_CTX, CtxNDR64 = RPC_INVALID_CTX;

View File

@ -104,8 +104,14 @@ const char *fn_exe = NULL;
#ifndef NO_RANDOM_EPID
int_fast8_t RandomizationLevel = 1;
uint16_t Lcid = 0;
uint16_t HostBuild = 0;
#endif
#if !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
uint8_t IsNDR64Defined = FALSE;
#endif // !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
#if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
#ifdef SIMPLE_SOCKETS
SOCKET s_server;

View File

@ -48,7 +48,7 @@
#include "types.h"
#include "kms.h"
#define MIN_CSVLK 5
//#define MIN_CSVLK 6
typedef struct
{
const char* Epid;
@ -162,9 +162,14 @@ extern int_fast8_t logverbose;
#endif
#endif
#if !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
extern uint8_t IsNDR64Defined;
#endif
#ifndef NO_RANDOM_EPID
extern int_fast8_t RandomizationLevel;
extern uint16_t Lcid;
extern uint16_t HostBuild;
#endif
#if !defined(NO_SOCKETS) && !defined(USE_MSRPC)

View File

@ -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: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 = "a:N:B:m:t:A:R:u:g:L:p:i:H: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;
@ -119,11 +119,6 @@ char* IniFileErrorBuffer = NULL;
static IniFileParameter_t IniFileParameterList[] =
{
{ "Windows", INI_PARAM_WINDOWS },
{ "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
@ -144,6 +139,7 @@ static IniFileParameter_t IniFileParameterList[] =
# ifndef NO_RANDOM_EPID
{ "RandomizationLevel", INI_PARAM_RANDOMIZATION_LEVEL },
{ "LCID", INI_PARAM_LCID },
{ "HostBuild", INI_PARAM_HOST_BUILD },
# endif // NO_RANDOM_EPID
# if !defined(NO_SOCKETS) && (defined(USE_MSRPC) || defined(SIMPLE_SOCKETS) || defined(HAVE_GETIFADDR))
{ "Port", INI_PARAM_PORT },
@ -270,21 +266,17 @@ static __noreturn void usage()
"\nUsage:\n"
" %s [ options ]\n\n"
"Where:\n"
# ifndef NO_CL_PIDS
" -w <ePID>\t\talways use <ePID> for Windows\n"
" -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)
" -u <user>\t\tset uid to <user>\n"
" -g <group>\t\tset gid to <group>\n"
# endif // !defined(_WIN32) && !defined(NO_USER_SWITCH)
# ifndef NO_CL_PIDS
" -a <csvlk>=<epid>\tuse <epid> for <csvlk>\n"
# endif // NO_CL_PIDS
# ifndef NO_RANDOM_EPID
" -r 0|1|2\t\tset ePID randomization level (default 1)\n"
" -C <LCID>\t\tuse fixed <LCID> in random ePIDs\n"
" -H <build>\t\tuse fixed <build> number in random ePIDs\n"
# endif // NO_RANDOM_EPID
# if !defined(NO_PRIVATE_IP_DETECT)
# if HAVE_GETIFADDR
@ -334,7 +326,7 @@ static __noreturn void usage()
# endif // _WIN32
# endif // NO_SOCKETS
# ifndef NO_STRICT_MODES
" -K 0|1|2|3\t\tset whitelisting level for KMS IDs (default -K0)\n"
" -K 0|1|2|3\t\tset white-listing level for KMS IDs (default -K0)\n"
" -c0, -c1\t\tdisable/enable client time checking (default -c0)\n"
# ifndef NO_CLIENT_LIST
" -M0, -M1\t\tdisable/enable maintaining clients (default -M0)\n"
@ -392,7 +384,8 @@ static __noreturn void usage()
__pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restrict argument)
{
DWORD val = timeSpanString2Minutes(argument);
const DWORD val = timeSpanString2Minutes(argument);
if (!val)
{
IniFileErrorMessage = "Incorrect time span.";
@ -408,7 +401,7 @@ __pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restr
__pure static DWORD getTimeSpanFromCommandLine(const char *const restrict arg, const char optchar)
{
DWORD val = timeSpanString2Minutes(arg);
const DWORD val = timeSpanString2Minutes(arg);
if (!val)
{
@ -422,6 +415,71 @@ __pure static DWORD getTimeSpanFromCommandLine(const char *const restrict arg, c
#endif // NO_CUSTOM_INTERVALS
#if !defined(NO_INI_FILE) || !defined (NO_CL_PIDS)
static __pure int isControlCharOrSlash(const char c)
{
if ((unsigned char)c < '!') return TRUE;
if (c == '/') return TRUE;
return FALSE;
}
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)
{
iniFileLineNextWord(s);
if (**s == '/')
{
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));
KmsResponseParameters[index].HwId = HwId;
}
return TRUE;
}
static BOOL setEpidFromIniFileLine(const char **s, const uint32_t index, const char *ePidSource, const uint8_t overwrite)
{
iniFileLineNextWord(s);
const char *savedPosition = *s;
uint_fast16_t i;
for (i = 0; !isControlCharOrSlash(**s); i++)
{
if (utf8_to_ucs2_char((const unsigned char*)*s, (const unsigned char**)s) == (WCHAR)~0)
{
return FALSE;
}
}
if (i < 1 || i >= PID_BUFFER_SIZE) return FALSE;
if (!overwrite && KmsResponseParameters[index].Epid) return TRUE;
const size_t size = *s - savedPosition + 1;
char* epidbuffer = (char*)vlmcsd_malloc(size);
memcpy(epidbuffer, savedPosition, size - 1);
epidbuffer[size - 1] = 0;
KmsResponseParameters[index].Epid = epidbuffer;
#ifndef NO_LOG
KmsResponseParameters[index].EpidSource = ePidSource;
#endif //NO_LOG
return TRUE;
}
#endif // !defined(NO_INI_FILE) || !defined (NO_CL_PIDS)
#ifndef NO_INI_FILE
static void ignoreIniFileParameter(uint_fast8_t iniFileParameterId)
{
@ -463,103 +521,12 @@ static BOOL getIniFileArgumentInt(unsigned int *result, const char *const argume
}
static __pure int isControlCharOrSlash(const char c)
{
if ((unsigned char)c < '!') return TRUE;
if (c == '/') return TRUE;
return FALSE;
}
static void iniFileLineNextWord(const char **s)
{
while (**s && isspace((int)**s)) (*s)++;
}
static BOOL setHwIdFromIniFileLine(const char **s, const uint32_t index)
{
iniFileLineNextWord(s);
if (**s == '/')
{
if (KmsResponseParameters[index].HwId) return TRUE;
BYTE* HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6 *)0)->HwId));
hex2bin(HwId, *s + 1, sizeof(((RESPONSE_V6 *)0)->HwId));
KmsResponseParameters[index].HwId = HwId;
}
return TRUE;
}
static BOOL setEpidFromIniFileLine(const char **s, const uint32_t index)
{
iniFileLineNextWord(s);
const char *savedPosition = *s;
uint_fast16_t i;
for (i = 0; !isControlCharOrSlash(**s); i++)
{
if (utf8_to_ucs2_char((const unsigned char*)*s, (const unsigned char**)s) == (WCHAR)~0)
{
return FALSE;
}
}
if (i < 1 || i >= PID_BUFFER_SIZE) return FALSE;
if (KmsResponseParameters[index].Epid) return TRUE;
size_t size = *s - savedPosition + 1;
char* epidbuffer = (char*)vlmcsd_malloc(size);
memcpy(epidbuffer, savedPosition, size - 1);
epidbuffer[size - 1] = 0;
KmsResponseParameters[index].Epid = epidbuffer;
#ifndef NO_LOG
KmsResponseParameters[index].EpidSource = fn_ini;
#endif //NO_LOG
return TRUE;
}
static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
{
unsigned int result;
BOOL success = TRUE;
const char *s = (const char*)iniarg;
switch (id)
{
case INI_PARAM_WINDOWS:
setEpidFromIniFileLine(&s, EPID_INDEX_WINDOWS);
setHwIdFromIniFileLine(&s, EPID_INDEX_WINDOWS);
break;
case INI_PARAM_OFFICE2010:
setEpidFromIniFileLine(&s, EPID_INDEX_OFFICE2010);
setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2010);
break;
case INI_PARAM_OFFICE2013:
setEpidFromIniFileLine(&s, EPID_INDEX_OFFICE2013);
setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2013);
break;
case INI_PARAM_OFFICE2016:
setEpidFromIniFileLine(&s, EPID_INDEX_OFFICE2016);
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:
@ -610,6 +577,11 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
if (success) RandomizationLevel = (int_fast8_t)result;
break;
case INI_PARAM_HOST_BUILD:
success = getIniFileArgumentInt(&result, iniarg, 0, 65535);
if (success) HostBuild = (uint16_t)result;
break;
# endif // NO_RANDOM_EPID
# if (defined(USE_MSRPC) || defined(SIMPLE_SOCKETS) || defined(HAVE_GETIFADDR)) && !defined(NO_SOCKETS)
@ -728,6 +700,7 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
case INI_PARAM_RPC_NDR64:
success = getIniFileArgumentBool(&UseServerRpcNDR64, iniarg);
if (success) IsNDR64Defined = TRUE;
break;
case INI_PARAM_RPC_BTFN:
@ -800,6 +773,56 @@ 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)
{
int8_t i;
for (i = 0; i < KmsData->CsvlkCount; i++)
{
const char *csvlkName = GetNextString(KmsData->CsvlkData[i].EPid);
if (!strncasecmp(csvlkName, s, strlen(csvlkName)))
{
return i;
}
}
return -1;
}
static BOOL handleIniFileEpidParameter(const char *s, uint8_t allowIniFileDirectives, const char *ePidSource)
{
int_fast16_t i;
if (allowIniFileDirectives)
{
for (i = 0; i < (int_fast16_t)vlmcsd_countof(IniFileParameterList); i++)
{
if (!strncasecmp(IniFileParameterList[i].Name, s, strlen(IniFileParameterList[i].Name)))
{
return TRUE;
}
}
}
i = GetCsvlkIndexFromName(s);
if (i >= 0)
{
if (!getIniFileArgument(&s)) return FALSE;
if (!setEpidFromIniFileLine(&s, i, ePidSource, !allowIniFileDirectives)) return FALSE;
if (!setHwIdFromIniFileLine(&s, i, !allowIniFileDirectives)) return FALSE;
return TRUE;
}
IniFileErrorMessage = "Unknown keyword.";
return FALSE;
}
static BOOL handleIniFileParameter(const char *s)
{
@ -809,14 +832,13 @@ static BOOL handleIniFileParameter(const char *s)
{
if (strncasecmp(IniFileParameterList[i].Name, s, strlen(IniFileParameterList[i].Name))) continue;
if (!IniFileParameterList[i].Id) return TRUE;
if (!getIniFileArgument(&s)) return FALSE;
return setIniFileParameter(IniFileParameterList[i].Id, s);
}
IniFileErrorMessage = "Unknown keyword.";
return FALSE;
IniFileErrorMessage = NULL;
return TRUE;
}
@ -844,6 +866,11 @@ static BOOL readIniFile(const uint_fast8_t pass)
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;
@ -855,18 +882,18 @@ static BOOL readIniFile(const uint_fast8_t pass)
iniFileLineNextWord(&s);
if (*s == ';' || *s == '#' || !*s) continue;
# ifndef NO_SOCKETS
if (pass == INI_FILE_PASS_1)
# endif // NO_SOCKETS
{
if (handleIniFileParameter(s)) continue;
lineParseError = TRUE;/*!checkGuidInIniFileLine(&s, &appIndex) ||
!setEpidFromIniFileLine(&s, appIndex) ||
!setHwIdFromIniFileLine(&s, appIndex);*/
lineParseError = TRUE;
}
else if (pass == INI_FILE_PASS_2)
{
if (handleIniFileEpidParameter(s, TRUE, fn_ini)) continue;
lineParseError = TRUE;
}
# if !defined(NO_SOCKETS) && !defined(SIMPLE_SOCKETS) && !defined(USE_MSRPC)
else if (pass == INI_FILE_PASS_2)
else if (pass == INI_FILE_PASS_3)
{
lineParseError = !setupListeningSocketsFromIniFile(s);
}
@ -1020,7 +1047,7 @@ static int daemonizeAndSetSignalAction()
#else // _WIN32
static BOOL terminationHandler(const DWORD fdwCtrlType)
static BOOL __stdcall terminationHandler(const DWORD fdwCtrlType)
{
// What a lame substitute for Unix signal handling
switch (fdwCtrlType)
@ -1043,7 +1070,7 @@ static DWORD daemonizeAndSetSignalAction()
if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)terminationHandler, TRUE))
{
#ifndef NO_LOG
DWORD rc = GetLastError();
const DWORD rc = GetLastError();
logger("Warning: Could not register Windows signal handler: Error %u\n", rc);
#endif // NO_LOG
}
@ -1073,10 +1100,6 @@ __pure static char* getCommandLineArg(char *const restrict arg)
static void parseGeneralArguments() {
int o;
#ifndef NO_CL_PIDS
BYTE* HwId;
#endif // NO_CL_PIDS
for (opterr = 0; (o = getopt(global_argc, (char* const*)global_argv, (const char*)optstring)) > 0; ) switch (o)
{
# if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
@ -1097,50 +1120,7 @@ static void parseGeneralArguments() {
# ifndef NO_CL_PIDS
case 'w':
KmsResponseParameters[EPID_INDEX_WINDOWS].Epid = getCommandLineArg(optarg);
# ifndef NO_LOG
KmsResponseParameters[EPID_INDEX_WINDOWS].EpidSource = "command line";
# endif // NO_LOG
break;
case '0':
KmsResponseParameters[EPID_INDEX_OFFICE2010].Epid = getCommandLineArg(optarg);
# ifndef NO_LOG
KmsResponseParameters[EPID_INDEX_OFFICE2010].EpidSource = "command line";
# endif // NO_LOG
break;
case '3':
KmsResponseParameters[EPID_INDEX_OFFICE2013].Epid = getCommandLineArg(optarg);
# ifndef NO_LOG
KmsResponseParameters[EPID_INDEX_OFFICE2013].EpidSource = "command line";
# endif // NO_LOG
break;
case '6':
KmsResponseParameters[EPID_INDEX_OFFICE2016].Epid = getCommandLineArg(optarg);
# ifndef NO_LOG
KmsResponseParameters[EPID_INDEX_OFFICE2016].EpidSource = "command line";
# 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));
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;
case 'a':
break;
# endif // NO_CL_PIDS
@ -1341,6 +1321,19 @@ static void parseGeneralArguments() {
# endif // _PEDANTIC
break;
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
# if !defined(NO_USER_SWITCH) && !defined(_WIN32)
@ -1393,6 +1386,7 @@ static void parseGeneralArguments() {
# ifndef SIMPLE_RPC
case 'N':
if (!getArgumentBool(&UseServerRpcNDR64, optarg)) usage();
IsNDR64Defined = TRUE;
ignoreIniFileParameter(INI_PARAM_RPC_NDR64);
break;
@ -1461,8 +1455,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)
@ -1569,8 +1563,8 @@ static void allocateSemaphore(void)
{
printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(errno));
MaxTasks = SEM_VALUE_MAX;
}
}
}
}
# endif // THREADS or CYGWIN
@ -1583,7 +1577,7 @@ static void allocateSemaphore(void)
}
# endif // _WIN32
}
}
}
#endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__
@ -1596,15 +1590,15 @@ int setupListeningSockets()
char** privateIPList = NULL;
int numPrivateIPs = 0;
if (PublicIPProtectionLevel & 1) getPrivateIPAddresses(&numPrivateIPs, &privateIPList);
uint_fast8_t allocsockets = (uint_fast8_t)(maxsockets ? (maxsockets + numPrivateIPs) : ((PublicIPProtectionLevel & 1) ? numPrivateIPs : 2));
const 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
SocketList = (SOCKET*)vlmcsd_malloc((size_t)allocsockets * sizeof(SOCKET));
int_fast8_t haveIPv4Stack = checkProtocolStack(AF_INET);
int_fast8_t haveIPv6Stack = checkProtocolStack(AF_INET6);
const int_fast8_t haveIPv4Stack = checkProtocolStack(AF_INET);
const int_fast8_t haveIPv6Stack = checkProtocolStack(AF_INET6);
// Reset getopt since we've alread used it
optReset();
@ -1627,7 +1621,7 @@ int setupListeningSockets()
# ifndef NO_INI_FILE
if (maxsockets && !numsockets)
{
if (fn_ini && !readIniFile(INI_FILE_PASS_2))
if (fn_ini && !readIniFile(INI_FILE_PASS_3))
{
# ifdef INI_FILE
if (strcmp(fn_ini, INI_FILE))
@ -1662,7 +1656,7 @@ int setupListeningSockets()
if (haveIPv6Stack) addListeningSocket("::");
if (haveIPv4Stack) addListeningSocket("0.0.0.0");
# endif // !HAVE_GETIFADDR
}
}
if (!numsockets)
{
@ -1698,11 +1692,6 @@ int server_main(int argc, CARGV argv)
int newmain()
{
# if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
KmsResponseParameters = (KmsResponseParam_t*)vlmcsd_malloc(sizeof(KmsResponseParam_t) * MIN_CSVLK);
memset(KmsResponseParameters, 0, sizeof(KmsResponseParam_t) * MIN_CSVLK);
# endif // !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
// Initialize thread synchronization objects for Windows and Cygwin
# ifdef USE_THREADS
@ -1762,7 +1751,7 @@ int newmain()
# ifndef NO_LOG
logstdout = 0;
# endif // !NO_LOG
}
}
# endif // !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
@ -1780,6 +1769,67 @@ int newmain()
loadKmsData();
# if !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
if
(
!IsNDR64Defined
)
{
UseServerRpcNDR64 = !!KmsData->Flags & KMS_OPTIONS_USENDR64;
# ifndef NO_RANDOM_EPID
if (HostBuild&&RandomizationLevel)
{
UseServerRpcNDR64 = HostBuild > 7601;
}
# endif
}
# 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);
# endif // !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
#ifndef NO_CL_PIDS
optReset();
int o;
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"))
{
usage();
}
break;
default:
break;
}
#endif // NO_CL_PIDS
# ifndef NO_INI_FILE
if (fn_ini && !readIniFile(INI_FILE_PASS_2))
{
# ifdef INI_FILE
if (strcmp(fn_ini, INI_FILE))
# endif // INI_FILE
printerrorf("Warning: Can't read %s: %s\n", fn_ini, strerror(errno));
}
# endif // NO_INI_FILE
# ifndef NO_CLIENT_LIST
if (MaintainClients) InitializeClientLists();
# endif // !NO_CLIENT_LIST
@ -1842,7 +1892,7 @@ int newmain()
{
printerrorf("Fatal: %s for %s failed: %s\n", "setuid", uname, strerror(errno));
return errno;
}
}
# ifndef NO_SIGHUP
}
# endif // NO_SIGHUP

View File

@ -48,10 +48,7 @@ int server_main(int argc, CARGV argv);
#define INI_PARAM_FREEBIND 17
#define INI_PARAM_PUBLIC_IP_PROTECTION_LEVEL 18
#define INI_PARAM_LOG_DATE_AND_TIME 19
#define INI_PARAM_WINDOWS 20
#define INI_PARAM_OFFICE2010 21
#define INI_PARAM_OFFICE2013 22
#define INI_PARAM_OFFICE2016 23
#define INI_PARAM_HOST_BUILD 20
#define INI_PARAM_WHITELISTING_LEVEL 24
#define INI_PARAM_CHECK_CLIENT_TIME 25
#define INI_PARAM_MAINTAIN_CLIENTS 26
@ -59,10 +56,10 @@ 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
#define INI_FILE_PASS_3 3
typedef struct IniFileParameter
{

View File

@ -262,7 +262,7 @@ static int DevCtl(DWORD code, void* data, DWORD len)
{
if (!DeviceIoControl(TapHandle, code, data, len, data, len, &len, NULL))
{
DWORD error = GetLastError();
const DWORD error = GetLastError();
printerrorf("Fatal: VPN adapter error: %s\n", win_strerror(error));
exit(error);
}
@ -278,7 +278,7 @@ static DWORD WINAPI TapMirror(LPVOID data_unused)
DWORD bytesRead, bytesWritten;
if (!ReadFile(TapHandle, IpPacket, Mtu, &bytesRead, NULL)) break;
uint32_t temp = IpPacket->ip_src;
const uint32_t temp = IpPacket->ip_src;
IpPacket->ip_src = IpPacket->ip_dst;
IpPacket->ip_dst = temp;
@ -289,7 +289,7 @@ static DWORD WINAPI TapMirror(LPVOID data_unused)
# endif // !defined(NO_LOG) && defined(_PEDANTIC)
}
DWORD error = GetLastError();
const DWORD error = GetLastError();
# ifndef NO_LOG
logger("Warning: VPN thread for device \"%s\" exiting: %s\n", ActiveTapName, win_strerror(error));