modified: myjupyterlab.sh
[GalaxyCodeBases.git] / etc / Windows / vlmcsd_old_vancepym / vlmcs.c
blobdb6a60fd1af2f117a92384dc43d8a891e3524ebb
1 #ifndef CONFIG
2 #define CONFIG "config.h"
3 #endif // CONFIG
4 #include CONFIG
6 #ifndef _GNU_SOURCE
7 #define _GNU_SOURCE
8 #endif
10 #include "vlmcs.h"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <stdint.h>
16 #include <getopt.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <unistd.h>
20 #ifndef _WIN32
21 #include <sys/ioctl.h>
22 #include <termios.h>
23 #else // _WIN32
24 #endif // _WIN32
25 #include "endian.h"
26 #include "shared_globals.h"
27 #include "output.h"
28 #ifndef USE_MSRPC
29 #include "network.h"
30 #include "rpc.h"
31 #else // USE_MSRPC
32 #include "msrpc-client.h"
33 #endif // USE_MSRPC
34 #include "kms.h"
35 #include "helpers.h"
36 #include "dns_srv.h"
39 #define VLMCS_OPTION_GRAB_INI 1
40 #define VLMCS_OPTION_NO_GRAB_INI 2
42 #define kmsVersionMinor 0 // Currently constant. May change in future KMS versions
44 // Function Prototypes
45 static void CreateRequestBase(REQUEST *Request);
48 // KMS Parameters
49 static int_fast8_t verbose = FALSE;
50 static int_fast8_t VMInfo = FALSE;
51 static int_fast8_t dnsnames = TRUE;
52 static int FixedRequests = 0;
53 static BYTE LicenseStatus = 0x02;
54 static const char *CMID = NULL;
55 static const char *CMID_prev = NULL;
56 static const char *WorkstationName = NULL;
57 static int BindingExpiration = 43200; //30 days
58 static const char *RemoteAddr;
59 static int_fast8_t ReconnectForEachRequest = FALSE;
60 static int AddressFamily = AF_UNSPEC;
61 static int_fast8_t incompatibleOptions = 0;
62 static const char* fn_ini_client = NULL;
64 #ifndef NO_DNS
65 static int_fast8_t NoSrvRecordPriority = FALSE;
66 #endif // NO_DNS
69 // Structure for handling "License Packs" (e.g. Office2013v5 or WindowsVista)
70 typedef struct
72 const char *names; //This is a list of strings. Terminate with additional Zero!!!
73 int N_Policy;
74 int kmsVersionMajor;
75 const GUID *AppID;
76 GUID ActID;
77 GUID KMSID;
78 } LicensePack;
81 typedef char iniFileEpidLines[3][256];
83 // Well known "license packs"
84 static const LicensePack LicensePackList[] =
86 // List of names min lics version appID skuId KMSCountedID
87 /* 000 */ { "Vista\000W6\000"
88 "WindowsVista\000"
89 "Windows\000", 25, 4, PWINGUID, { 0x4f3d1606, 0x3fea, 0x4c01, { 0xbe, 0x3c, 0x8d, 0x67, 0x1c, 0x40, 0x1e, 0x3b, } }, { 0x212a64dc, 0x43b1, 0x4d3d, { 0xa3, 0x0c, 0x2f, 0xc6, 0x9d, 0x20, 0x95, 0xc6 } } },
90 /* 001 */ { "W7\000Windows7\000", 25, 4, PWINGUID, { 0xb92e9980, 0xb9d5, 0x4821, { 0x9c, 0x94, 0x14, 0x0f, 0x63, 0x2f, 0x63, 0x12, } }, { 0x7fde5219, 0xfbfa, 0x484a, { 0x82, 0xc9, 0x34, 0xd1, 0xad, 0x53, 0xe8, 0x56 } } },
91 /* 002 */ { "W8\000Windows8\000", 25, 5, PWINGUID, { 0xa98bcd6d, 0x5343, 0x4603, { 0x8a, 0xfe, 0x59, 0x08, 0xe4, 0x61, 0x11, 0x12, } }, { 0x3c40b358, 0x5948, 0x45af, { 0x92, 0x3b, 0x53, 0xd2, 0x1f, 0xcc, 0x7e, 0x79 } } },
92 /* 003 */ { "W8C\000Windows8C\000", 25, 5, PWINGUID, { 0xc04ed6bf, 0x55c8, 0x4b47, { 0x9f, 0x8e, 0x5a, 0x1f, 0x31, 0xce, 0xee, 0x60, } }, { 0xbbb97b3b, 0x8ca4, 0x4a28, { 0x97, 0x17, 0x89, 0xfa, 0xbd, 0x42, 0xc4, 0xac } } },
93 /* 004 */ { "W81\000Windows81\000", 25, 6, PWINGUID, { 0xc06b6981, 0xd7fd, 0x4a35, { 0xb7, 0xb4, 0x05, 0x47, 0x42, 0xb7, 0xaf, 0x67, } }, { 0xcb8fc780, 0x2c05, 0x495a, { 0x97, 0x10, 0x85, 0xaf, 0xff, 0xc9, 0x04, 0xd7 } } },
94 /* 005 */ { "W81C\000Windows81C\000", 25, 6, PWINGUID, { 0xfe1c3238, 0x432a, 0x43a1, { 0x8e, 0x25, 0x97, 0xe7, 0xd1, 0xef, 0x10, 0xf3, } }, { 0x6d646890, 0x3606, 0x461a, { 0x86, 0xab, 0x59, 0x8b, 0xb8, 0x4a, 0xce, 0x82 } } },
95 /* 006 */ { "W10\000Windows10\000", 25, 6, PWINGUID, { 0x73111121, 0x5638, 0x40f6, { 0xbc, 0x11, 0xf1, 0xd7, 0xb0, 0xd6, 0x43, 0x00, } }, { 0x58e2134f, 0x8e11, 0x4d17, { 0x9c, 0xb2, 0x91, 0x06, 0x9c, 0x15, 0x11, 0x48 } } },
96 /* 007 */ { "W10C\000Windows10C\000", 25, 6, PWINGUID, { 0x58e97c99, 0xf377, 0x4ef1, { 0x81, 0xd5, 0x4a, 0xd5, 0x52, 0x2b, 0x5f, 0xd8, } }, { 0xe1c51358, 0xfe3e, 0x4203, { 0xa4, 0xa2, 0x3b, 0x6b, 0x20, 0xc9, 0x73, 0x4e } } },
97 /* 008 */ { "2008" "\0" "2008A\000", 5, 4, PWINGUID, { 0xddfa9f7c, 0xf09e, 0x40b9, { 0x8c, 0x1a, 0xbe, 0x87, 0x7a, 0x9a, 0x7f, 0x4b, } }, { 0x33e156e4, 0xb76f, 0x4a52, { 0x9f, 0x91, 0xf6, 0x41, 0xdd, 0x95, 0xac, 0x48 } } },
98 /* 009 */ { "2008B\000", 5, 4, PWINGUID, { 0xc1af4d90, 0xd1bc, 0x44ca, { 0x85, 0xd4, 0x00, 0x3b, 0xa3, 0x3d, 0xb3, 0xb9, } }, { 0x8fe53387, 0x3087, 0x4447, { 0x89, 0x85, 0xf7, 0x51, 0x32, 0x21, 0x5a, 0xc9 } } },
99 /* 010 */ { "2008C\000", 5, 4, PWINGUID, { 0x68b6e220, 0xcf09, 0x466b, { 0x92, 0xd3, 0x45, 0xcd, 0x96, 0x4b, 0x95, 0x09, } }, { 0x8a21fdf3, 0xcbc5, 0x44eb, { 0x83, 0xf3, 0xfe, 0x28, 0x4e, 0x66, 0x80, 0xa7 } } },
100 /* 011 */ { "2008R2" "\0" "2008R2A\000", 5, 4, PWINGUID, { 0xa78b8bd9, 0x8017, 0x4df5, { 0xb8, 0x6a, 0x09, 0xf7, 0x56, 0xaf, 0xfa, 0x7c, } }, { 0x0fc6ccaf, 0xff0e, 0x4fae, { 0x9d, 0x08, 0x43, 0x70, 0x78, 0x5b, 0xf7, 0xed } } },
101 /* 012 */ { "2008R2B\000", 5, 4, PWINGUID, { 0x620e2b3d, 0x09e7, 0x42fd, { 0x80, 0x2a, 0x17, 0xa1, 0x36, 0x52, 0xfe, 0x7a, } }, { 0xca87f5b6, 0xcd46, 0x40c0, { 0xb0, 0x6d, 0x8e, 0xcd, 0x57, 0xa4, 0x37, 0x3f } } },
102 /* 013 */ { "2008R2C\000", 5, 4, PWINGUID, { 0x7482e61b, 0xc589, 0x4b7f, { 0x8e, 0xcc, 0x46, 0xd4, 0x55, 0xac, 0x3b, 0x87, } }, { 0xb2ca2689, 0xa9a8, 0x42d7, { 0x93, 0x8d, 0xcf, 0x8e, 0x9f, 0x20, 0x19, 0x58 } } },
103 /* 014 */ { "2012\000", 5, 5, PWINGUID, { 0xf0f5ec41, 0x0d55, 0x4732, { 0xaf, 0x02, 0x44, 0x0a, 0x44, 0xa3, 0xcf, 0x0f, } }, { 0x8665cb71, 0x468c, 0x4aa3, { 0xa3, 0x37, 0xcb, 0x9b, 0xc9, 0xd5, 0xea, 0xac } } },
104 /* 015 */ { "2012R2\000" "12R2\000", 5, 6, PWINGUID, { 0x00091344, 0x1ea4, 0x4f37, { 0xb7, 0x89, 0x01, 0x75, 0x0b, 0xa6, 0x98, 0x8c, } }, { 0x8456EFD3, 0x0C04, 0x4089, { 0x87, 0x40, 0x5b, 0x72, 0x38, 0x53, 0x5a, 0x65 } } },
105 /* 016 */ { "Office2010\000O14\000", 5, 4, POFFICE2010GUID, { 0x6f327760, 0x8c5c, 0x417c, { 0x9b, 0x61, 0x83, 0x6a, 0x98, 0x28, 0x7e, 0x0c, } }, { 0xe85af946, 0x2e25, 0x47b7, { 0x83, 0xe1, 0xbe, 0xbc, 0xeb, 0xea, 0xc6, 0x11 } } },
106 /* 017 */ { "Office2013\000O15\000", 5, 6, POFFICE2013GUID, { 0xb322da9c, 0xa2e2, 0x4058, { 0x9e, 0x4e, 0xf5, 0x9a, 0x69, 0x70, 0xbd, 0x69, } }, { 0xe6a6f1bf, 0x9d40, 0x40c3, { 0xaa, 0x9f, 0xc7, 0x7b, 0xa2, 0x15, 0x78, 0xc0 } } },
107 /* 018 */ { "Office2013V5\000", 5, 5, POFFICE2013GUID, { 0xb322da9c, 0xa2e2, 0x4058, { 0x9e, 0x4e, 0xf5, 0x9a, 0x69, 0x70, 0xbd, 0x69, } }, { 0xe6a6f1bf, 0x9d40, 0x40c3, { 0xaa, 0x9f, 0xc7, 0x7b, 0xa2, 0x15, 0x78, 0xc0 } } },
108 /* 019 */ { "Office2016\000" "O16\000", 5, 6, POFFICE2013GUID, { 0xd450596f, 0x894d, 0x49e0, { 0x96, 0x6a, 0xfd, 0x39, 0xed, 0x4c, 0x4c, 0x64, } }, { 0x85b5f61b, 0x320b, 0x4be3, { 0x81, 0x4a, 0xb7, 0x6b, 0x2b, 0xfa, 0xfc, 0x82 } } },
109 /* 020 */ { NULL, 0, 0, NULL, { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }, { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } } }
113 typedef struct
115 const char* first[16];
116 const char* second[16];
117 const char* tld[22];
118 } DnsNames;
121 // Some names for the DNS name random generator
122 static DnsNames ClientDnsNames =
124 { "www", "ftp", "kms", "hack-me", "smtp", "ns1", "mx1", "ns1", "pop3", "imap", "mail", "dns", "headquarter", "we-love", "_vlmcs._tcp", "ceo-laptop" },
125 { ".microsoft", ".apple", ".amazon", ".samsung", ".adobe", ".google", ".yahoo", ".facebook", ".ubuntu", ".oracle", ".borland", ".htc", ".acer", ".windows", ".linux", ".sony" },
126 { ".com", ".net", ".org", ".cn", ".co.uk", ".de", ".com.tw", ".us", ".fr", ".it", ".me", ".info", ".biz", ".co.jp", ".ua", ".at", ".es", ".pro", ".by", ".ru", ".pl", ".kr" }
130 // This is the one, we are actually using. We use Vista, if user selects nothing
131 LicensePack ActiveLicensePack;
134 // Request Count Control Variables
135 static int RequestsToGo = 1;
136 static BOOL firstRequestSent = FALSE;
139 static void string2UuidOrExit(const char *const restrict input, GUID *const restrict guid)
141 if (strlen(input) != GUID_STRING_LENGTH || !string2Uuid(input, guid))
143 errorout("Fatal: Command line contains an invalid GUID.\n");
144 exit(!0);
149 #ifndef NO_HELP
151 __noreturn static void clientUsage(const char* const programName)
153 errorout(
154 "vlmcs %s \n\n"
155 # ifndef NO_DNS
156 "Usage: %s [options] [ <host>[:<port>] | .<domain> | - ] [options]\n\n"
157 # else // DNS
158 "Usage: %s [options] [<host>[:<port>]] [options]\n\n"
159 # endif // DNS
161 "Options:\n\n"
163 " -v Be verbose\n"
164 " -l <app>\n"
165 " -4 Force V4 protocol\n"
166 " -5 Force V5 protocol\n"
167 " -6 Force V6 protocol\n"
168 # ifndef USE_MSRPC
169 " -i <IpVersion> Use IP protocol (4 or 6)\n"
170 # endif // USE_MSRPC
171 " -e Show some valid examples\n"
172 " -x Show valid Apps\n"
173 " -d no DNS names, use Netbios names (no effect if -w is used)\n\n"
175 "Advanced options:\n\n"
177 " -a <AppGUID> Use custom Application GUID\n"
178 " -s <ActGUID> Use custom Activation Configuration GUID\n"
179 " -k <KmsGUID> Use custom KMS GUID\n"
180 " -c <ClientGUID> Use custom Client GUID. Default: Use random\n"
181 " -o <PreviousClientGUID> Use custom Prevoius Client GUID. Default: ZeroGUID\n"
182 " -w <Workstation> Use custom workstation name. Default: Use random\n"
183 " -r <RequiredClientCount> Fake required clients\n"
184 " -n <Requests> Fixed # of requests (Default: Enough to charge)\n"
185 " -m Pretend to be a virtual machine\n"
186 " -G <file> Get ePID/HwId data and write to <file>. Can't be used with -l, -4, -5, -6, -a, -s, -k, -r and -n\n"
187 # ifndef USE_MSRPC
188 " -T Use a new TCP connection for each request.\n"
189 " -N <0|1> disable or enable NDR64. Default: 1\n"
190 " -B <0|1> disable or enable RPC bind time feature negotiation. Default: 1\n"
191 # endif // USE_MSRPC
192 " -t <LicenseStatus> Use specfic license status (0 <= T <= 6)\n"
193 " -g <BindingExpiration> Use a specfic binding expiration time in minutes. Default 43200\n"
194 # ifndef NO_DNS
195 " -P Ignore priority and weight in DNS SRV records\n"
196 # endif // NO_DNS
197 # ifndef USE_MSRPC
198 " -p Don't use multiplexed RPC bind\n"
199 # endif // USE_MSRPC
200 "\n"
202 "<port>:\t\tTCP port name of the KMS to use. Default 1688.\n"
203 "<host>:\t\thost name of the KMS to use. Default 127.0.0.1\n"
204 # ifndef NO_DNS
205 ".<domain>:\tfind KMS server in <domain> via DNS\n"
206 # endif // NO_DNS
207 "<app>:\t\t(Type %s -x to see a list of valid apps)\n\n",
208 Version, programName, programName
211 exit(!0);
214 __pure static int getLineWidth(void)
216 #ifdef TERMINAL_FIXED_WIDTH // For Toolchains that to not have winsize
217 return TERMINAL_FIXED_WIDTH;
218 #else // Can determine width of terminal
219 #ifndef _WIN32
221 struct winsize w;
223 if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &w))
225 return 80; // Return this if stdout is not a tty
228 return w.ws_col;
230 #else // _WIN32
232 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
233 HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
235 if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
237 return 80; // Return this if stdout is not a Console
240 return csbiInfo.srWindow.Right - csbiInfo.srWindow.Left;
242 #endif // WIN32
244 #endif // Can determine width of terminal
248 __noreturn static void showProducts(PRINTFUNC p)
250 int cols = getLineWidth();
251 int itemsPerLine;
252 uint8_t i;
255 "The following "
256 #if !defined(NO_EXTENDED_PRODUCT_LIST) && !defined(NO_BASIC_PRODUCT_LIST)
257 "aliases "
258 #else
259 "names "
260 #endif
261 "can be used with -l:\n\n"
264 const LicensePack* lp;
266 itemsPerLine = cols / 20;
267 if (!itemsPerLine) itemsPerLine = 1;
269 for (i = 1, lp = LicensePackList; lp->names; lp++)
271 const char* name;
273 for (name = lp->names; *name; name += strlen(name) + 1, i++)
275 p("%-20s", name);
277 if (!(i % itemsPerLine)) p("\n");
281 p("\n\n");
283 #if !defined(NO_EXTENDED_PRODUCT_LIST) && !defined(NO_BASIC_PRODUCT_LIST)
285 const KmsIdList* currentProduct;
286 uint_fast8_t longestString = 0;
287 uint8_t k, items = getExtendedProductListSize();
289 p("You may also use these product names or numbers:\n\n");
291 for (currentProduct = ExtendedProductList; currentProduct->name; currentProduct++)
293 uint_fast8_t len = strlen(currentProduct->name);
295 if (len > longestString)
296 longestString = len;
299 itemsPerLine = cols / (longestString + 10);
300 if (!itemsPerLine) itemsPerLine = 1;
301 uint8_t lines = items / itemsPerLine;
302 if (items % itemsPerLine) lines++;
304 for (i = 0; i < lines; i++)
306 for (k = 0; k < itemsPerLine; k++)
308 uint8_t j;
309 uint8_t index = k * lines + i;
311 if (index >= items) break;
313 p("%3u = %s", index + 1, ExtendedProductList[index].name);
315 for (j = 0; j < longestString + 4 - strlen(ExtendedProductList[index].name); j++)
317 p(" ");
321 p("\n");
324 p("\n");
326 #endif // !defined(NO_EXTENDED_PRODUCT_LIST) && !defined(NO_BASIC_PRODUCT_LIST)
328 exit(0);
331 __noreturn static void examples(const char* const programName)
333 printf(
334 "\nRequest activation for Office2013 using V4 protocol from 192.168.1.5:1688\n"
335 "\t%s -l O15 -4 192.168.1.5\n"
336 "\t%s -l O15 -4 192.168.1.5:1688\n\n"
338 "Request activation for Windows Server 2012 using V4 protocol from localhost:1688\n"
339 "\t%s -4 -l Windows -k 8665cb71-468c-4aa3-a337-cb9bc9d5eaac\n"
340 "\t%s -4 -l 2012\n"
341 "\t%s -4 -l 2012 [::1]:1688\n"
342 "\t%s -4 -l 12 127.0.0.2:1688\n\n"
344 "Send 100,000 requests to localhost:1688\n"
345 "\t%s -n 100000 -l Office2010\n\n"
347 "Request Activation for Windows 8 from 10.0.0.1:4711 and pretend to be Steve Ballmer\n"
348 "\t%s -l Windows8 -w steveb1.redmond.microsoft.com 10.0.0.1:4711\n\n",
349 programName, programName, programName, programName, programName, programName, programName, programName
352 exit(0);
356 #else // NO_HELP
359 __noreturn static void clientUsage(const char* const programName)
361 errorout("Incorrect parameter specified.\n");
362 exit(!0);
366 #endif // NO_HELP
369 static BOOL findLicensePackByName(const char* const name, LicensePack* const lp)
371 // Try to find a package in the short list first
373 LicensePack *licensePack;
374 for (licensePack = (LicensePack*)&LicensePackList; licensePack->names; licensePack ++)
376 const char *currentName;
377 for (currentName = licensePack->names; *currentName; currentName += strlen(currentName) + 1)
379 if (!strcasecmp(name, currentName))
381 *lp = *licensePack;
382 return TRUE;
387 #if defined(NO_BASIC_PRODUCT_LIST) || defined(NO_EXTENDED_PRODUCT_LIST)
389 return FALSE;
391 #else // Both Lists are available
393 // search extended product list
395 uint8_t items = getExtendedProductListSize();
396 unsigned int index;
398 if (stringToInt(name, 1, items, &index))
400 index--;
402 else
404 for (index = 0; index < items; index++)
406 if (!strcasecmp(ExtendedProductList[index].name, name)) break;
409 if (index >= items) return FALSE;
412 lp->AppID = &AppList[ExtendedProductList[index].AppIndex].guid;
413 lp->KMSID = ProductList[ExtendedProductList[index].KmsIndex].guid;
414 lp->ActID = ExtendedProductList[index].guid;
415 lp->N_Policy = ProductList[ExtendedProductList[index].KmsIndex].KMS_PARAM_REQUIREDCOUNT;
416 lp->kmsVersionMajor = ProductList[ExtendedProductList[index].KmsIndex].KMS_PARAM_MAJOR;
418 return TRUE;
420 #endif // Both Lists are available
423 static const char* const client_optstring = "+N:B:i:l:a:s:k:c:w:r:n:t:g:G:o:pPTv456mexd";
426 //First pass. We handle only "-l". Since -a -k -s -4 -5 and -6 are exceptions to -l, we process -l first
427 static void parseCommandLinePass1(const int argc, CARGV argv)
429 int o;
430 optReset();
432 for (opterr = 0; ( o = getopt(argc, (char* const*)argv, client_optstring) ) > 0; ) switch (o)
434 case 'l': // Set "License Pack" and protocol version (e.g. Windows8, Office2013v5, ...)
436 if (!findLicensePackByName(optarg, &ActiveLicensePack))
438 errorout("Invalid client application. \"%s\" is not valid for -l.\n\n", optarg);
439 #ifndef NO_HELP
440 showProducts(&errorout);
441 #endif // !NO_HELP
444 break;
446 default:
447 break;
452 // Second Pass. Handle all options except "-l"
453 static void parseCommandLinePass2(const char *const programName, const int argc, CARGV argv)
455 int o;
456 optReset();
458 for (opterr = 0; ( o = getopt(argc, (char* const*)argv, client_optstring) ) > 0; ) switch (o)
460 #ifndef NO_HELP
462 case 'e': // Show examples
464 examples(programName);
465 break;
467 case 'x': // Show Apps
469 showProducts(&printf);
470 break;
472 #endif // NO_HELP
474 # ifndef NO_DNS
476 case 'P':
478 NoSrvRecordPriority = TRUE;
479 break;
481 # endif // NO_DNS
483 case 'G':
485 incompatibleOptions |= VLMCS_OPTION_GRAB_INI;
486 fn_ini_client = optarg;
487 break;
489 # ifndef USE_MSRPC
491 case 'N':
492 if (!getArgumentBool(&UseRpcNDR64, optarg)) clientUsage(programName);
493 break;
495 case 'B':
496 if (!getArgumentBool(&UseRpcBTFN, optarg)) clientUsage(programName);
497 break;
499 case 'i':
501 switch(getOptionArgumentInt(o, 4, 6))
503 case 4:
504 AddressFamily = AF_INET;
505 break;
506 case 6:
507 AddressFamily = AF_INET6;
508 break;
509 default:
510 errorout("IPv5 does not exist.\n");
511 exit(!0);
512 break;
515 break;
517 case 'p': // Multiplexed RPC
519 UseMultiplexedRpc = FALSE;
520 break;
522 # endif // USE_MSRPC
524 case 'n': // Fixed number of Requests (regardless, whether they are required)
526 incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
527 FixedRequests = getOptionArgumentInt(o, 1, INT_MAX);
528 break;
530 case 'r': // Fake minimum required client count
532 incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
533 ActiveLicensePack.N_Policy = getOptionArgumentInt(o, 1, INT_MAX);
534 break;
536 case 'c': // use a specific client GUID
538 // If using a constant Client ID, send only one request unless /N= explicitly specified
539 if (!FixedRequests) FixedRequests = 1;
541 CMID = optarg;
542 break;
544 case 'o': // use a specific previous client GUID
546 CMID_prev = optarg;
547 break;
549 case 'a': // Set specific App Id
551 incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
552 ActiveLicensePack.AppID = (GUID*)vlmcsd_malloc(sizeof(GUID));
554 string2UuidOrExit(optarg, (GUID*)ActiveLicensePack.AppID);
555 break;
557 case 'g': // Set custom "grace" time in minutes (default 30 days)
559 BindingExpiration = getOptionArgumentInt(o, 0, INT_MAX);
560 break;
562 case 's': // Set specfic SKU ID
564 incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
565 string2UuidOrExit(optarg, &ActiveLicensePack.ActID);
566 break;
568 case 'k': // Set specific KMS ID
570 incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
571 string2UuidOrExit(optarg, &ActiveLicensePack.KMSID);
572 break;
574 case '4': // Force V4 protocol
575 case '5': // Force V5 protocol
576 case '6': // Force V5 protocol
578 incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
579 ActiveLicensePack.kmsVersionMajor = o - 0x30;
580 break;
582 case 'd': // Don't use DNS names
584 dnsnames = FALSE;
585 break;
587 case 'v': // Be verbose
589 verbose = TRUE;
590 break;
592 case 'm': // Pretend to be a virtual machine
594 VMInfo = TRUE;
595 break;
597 case 'w': // WorkstationName (max. 63 chars)
599 WorkstationName = optarg;
601 if (strlen(WorkstationName) > 63)
603 errorout("\007WARNING! Truncating Workstation name to 63 characters (%s).\n", WorkstationName);
606 break;
608 case 't':
610 LicenseStatus = getOptionArgumentInt(o, 0, 6) & 0xff;
611 break;
613 # ifndef USE_MSRPC
615 case 'T':
617 ReconnectForEachRequest = TRUE;
618 break;
620 # endif // USE_MSRPC
622 case 'l':
623 incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
624 break;
626 default:
627 clientUsage(programName);
629 if ((incompatibleOptions & (VLMCS_OPTION_NO_GRAB_INI | VLMCS_OPTION_GRAB_INI)) == (VLMCS_OPTION_NO_GRAB_INI | VLMCS_OPTION_GRAB_INI))
630 clientUsage(programName);
635 * Compares 2 GUIDs where one is host-endian and the other is little-endian (network byte order)
637 int_fast8_t IsEqualGuidLEHE(const GUID* const guid1, const GUID* const guid2)
639 GUID tempGuid;
640 LEGUID(&tempGuid, guid2);
641 return IsEqualGUID(guid1, &tempGuid);
645 #ifndef USE_MSRPC
646 static void checkRpcLevel(const REQUEST* request, RESPONSE* response)
648 if (!RpcFlags.HasNDR32)
649 errorout("\nWARNING: Server's RPC protocol does not support NDR32.\n");
651 if (UseRpcBTFN && UseRpcNDR64 && RpcFlags.HasNDR64 && !RpcFlags.HasBTFN)
652 errorout("\nWARNING: Server's RPC protocol has NDR64 but no BTFN.\n");
654 if (!IsEqualGuidLEHE(&request->KMSID, &ProductList[15].guid) && UseRpcBTFN && !RpcFlags.HasBTFN)
655 errorout("\nWARNING: A server with pre-Vista RPC activated a product other than Office 2010.\n");
657 #endif // USE_MSRPC
660 static void displayResponse(const RESPONSE_RESULT result, const REQUEST* request, RESPONSE* response, BYTE *hwid)
662 fflush(stdout);
664 if (!result.RpcOK) errorout("\n\007ERROR: Non-Zero RPC result code.\n");
665 if (!result.DecryptSuccess) errorout("\n\007ERROR: Decryption of V5/V6 response failed.\n");
666 if (!result.IVsOK) errorout("\n\007ERROR: AES CBC initialization vectors (IVs) of request and response do not match.\n");
667 if (!result.PidLengthOK) errorout("\n\007ERROR: The length of the PID is not valid.\n");
668 if (!result.HashOK) errorout("\n\007ERROR: Computed hash does not match hash in response.\n");
669 if (!result.ClientMachineIDOK) errorout("\n\007ERROR: Client machine GUIDs of request and response do not match.\n");
670 if (!result.TimeStampOK) errorout("\n\007ERROR: Time stamps of request and response do not match.\n");
671 if (!result.VersionOK) errorout("\n\007ERROR: Protocol versions of request and response do not match.\n");
672 if (!result.HmacSha256OK) errorout("\n\007ERROR: Keyed-Hash Message Authentication Code (HMAC) is incorrect.\n");
673 if (!result.IVnotSuspicious) errorout("\nWARNING: Response uses an IV following KMSv5 rules in KMSv6 protocol.\n");
675 if (result.effectiveResponseSize != result.correctResponseSize)
677 errorout("\n\007WARNING: Size of RPC payload (KMS Message) should be %u but is %u.", result.correctResponseSize, result.effectiveResponseSize);
680 # ifndef USE_MSRPC
681 checkRpcLevel(request, response);
682 # endif // USE_MSRPC
684 if (!result.DecryptSuccess) return; // Makes no sense to display anything
686 char ePID[3 * PID_BUFFER_SIZE];
687 if (!ucs2_to_utf8(response->KmsPID, ePID, PID_BUFFER_SIZE, 3 * PID_BUFFER_SIZE))
689 memset(ePID + 3 * PID_BUFFER_SIZE - 3, 0, 3);
692 // Read KMSPID from Response
693 if (!verbose)
695 printf(" -> %s", ePID);
697 if (LE16(response->MajorVer) > 5)
699 # ifndef _WIN32
700 printf(" (%016llX)", (unsigned long long)BE64(*(uint64_t*)hwid));
701 # else // _WIN32
702 printf(" (%016I64X)", (unsigned long long)BE64(*(uint64_t*)hwid));
703 # endif // _WIN32
706 printf("\n");
708 else
710 printf(
711 "\n\nResponse from KMS server\n========================\n\n"
712 "Size of KMS Response : %u (0x%x)\n", result.effectiveResponseSize, result.effectiveResponseSize
715 logResponseVerbose(ePID, hwid, response, &printf);
716 printf("\n");
721 static void connectRpc(RpcCtx *s)
723 # ifdef NO_DNS
725 *s = connectToAddress(RemoteAddr, AddressFamily, FALSE);
726 if (*s == INVALID_RPCCTX)
728 errorout("Fatal: Could not connect to %s\n", RemoteAddr);
729 exit(!0);
732 if (verbose)
733 printf("\nPerforming RPC bind ...\n");
735 if (rpcBindClient(*s, verbose))
737 errorout("Fatal: Could not bind RPC\n");
738 exit(!0);
741 if (verbose) printf("... successful\n");
743 # else // DNS
745 static kms_server_dns_ptr* serverlist = NULL;
746 static int numServers = 0;
747 //static int_fast8_t ServerListAlreadyPrinted = FALSE;
748 int i;
750 if (!strcmp(RemoteAddr, "-") || *RemoteAddr == '.') // Get KMS server via DNS SRV record
752 if (!serverlist)
753 numServers = getKmsServerList(&serverlist, RemoteAddr);
755 if (numServers < 1)
757 errorout("Fatal: No KMS servers found\n");
758 exit(!0);
761 if (!NoSrvRecordPriority) sortSrvRecords(serverlist, numServers);
763 if (verbose /*&& !ServerListAlreadyPrinted*/)
765 for (i = 0; i < numServers; i++)
767 printf(
768 "Found %-40s (priority: %hu, weight: %hu, randomized weight: %i)\n",
769 serverlist[i]->serverName,
770 serverlist[i]->priority, serverlist[i]->weight,
771 NoSrvRecordPriority ? 0 : serverlist[i]->random_weight
775 printf("\n");
776 //ServerListAlreadyPrinted = TRUE;
779 else // Just use the server supplied on the command line
781 if (!serverlist)
783 serverlist = (kms_server_dns_ptr*)vlmcsd_malloc(sizeof(kms_server_dns_ptr));
784 *serverlist = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
786 numServers = 1;
787 strncpy((*serverlist)->serverName, RemoteAddr, sizeof((*serverlist)->serverName));
791 for (i = 0; i < numServers; i++)
793 *s = connectToAddress(serverlist[i]->serverName, AddressFamily, (*RemoteAddr == '.' || *RemoteAddr == '-'));
795 if (*s == INVALID_RPCCTX) continue;
797 if (verbose)
798 printf("\nPerforming RPC bind ...\n");
800 if (rpcBindClient(*s, verbose))
802 errorout("Warning: Could not bind RPC\n");
803 continue;
806 if (verbose) printf("... successful\n");
808 return;
811 errorout("Fatal: Could not connect to any KMS server\n");
812 exit(!0);
814 # endif // DNS
818 static int SendActivationRequest(const RpcCtx sock, RESPONSE *baseResponse, REQUEST *baseRequest, RESPONSE_RESULT *result, BYTE *const hwid)
820 size_t requestSize, responseSize;
821 BYTE *request, *response;
822 int status;
824 result->mask = 0;
826 if (LE16(baseRequest->MajorVer) == 4)
827 request = CreateRequestV4(&requestSize, baseRequest);
828 else
829 request = CreateRequestV6(&requestSize, baseRequest);
831 if (!(status = rpcSendRequest(sock, request, requestSize, &response, &responseSize)))
833 if (LE16(((RESPONSE*)(response))->MajorVer) == 4)
835 RESPONSE_V4 response_v4;
836 *result = DecryptResponseV4(&response_v4, responseSize, response, request);
837 memcpy(baseResponse, &response_v4.ResponseBase, sizeof(RESPONSE));
839 else
841 RESPONSE_V6 response_v6;
842 *result = DecryptResponseV6(&response_v6, responseSize, response, request, hwid);
843 memcpy(baseResponse, &response_v6.ResponseBase, sizeof(RESPONSE));
846 result->RpcOK = TRUE;
849 if (response) free(response);
850 free(request);
851 return status;
855 static int sendRequest(RpcCtx *const s, REQUEST *const request, RESPONSE *const response, hwid_t hwid, RESPONSE_RESULT *const result)
857 CreateRequestBase(request);
859 if (*s == INVALID_RPCCTX )
860 connectRpc(s);
861 else
863 // Check for lame KMS emulators that close the socket after each request
864 int_fast8_t disconnected = isDisconnected(*s);
866 if (disconnected)
867 errorout("\nWarning: Server closed RPC connection (probably non-multitasked KMS emulator)\n");
869 if (ReconnectForEachRequest || disconnected)
871 closeRpc(*s);
872 connectRpc(s);
876 printf("Sending activation request (KMS V%u) ", ActiveLicensePack.kmsVersionMajor);
877 fflush(stdout);
879 return SendActivationRequest(*s, response, request, result, hwid);
883 static void displayRequestError(RpcCtx *const s, const int status, const int currentRequest, const int totalRequests)
885 errorout("\nError 0x%08X while sending request %u of %u\n", status, currentRequest, RequestsToGo + totalRequests);
887 switch(status)
889 case 0xC004F042: // not licensed
890 errorout("The server refused to activate the requested product\n");
891 break;
893 case 0x8007000D: // e.g. v6 protocol on a v5 server
894 errorout("The server didn't understand the request\n");
895 break;
897 case 1:
898 errorout("An RPC protocol error has occured\n");
899 closeRpc(*s);
900 connectRpc(s);
901 break;
903 default:
904 break;
909 static void newIniBackupFile(const char* const restrict fname)
911 FILE *restrict f = fopen(fname, "wb");
913 if (!f)
915 errorout("Fatal: Cannot create %s: %s\n", fname, strerror(errno));
916 exit(!0);
919 if (fclose(f))
921 errorout("Fatal: Cannot write to %s: %s\n", fname, strerror(errno));
922 unlink(fname);
923 exit(!0);
928 static void updateIniFile(iniFileEpidLines* const restrict lines)
930 int_fast8_t lineWritten[_countof(*lines)];
931 struct stat statbuf;
932 uint_fast8_t i;
933 int_fast8_t iniFileExistedBefore = TRUE;
934 unsigned int lineNumber;
936 memset(lineWritten, FALSE, sizeof(lineWritten));
938 char* restrict fn_bak = (char*)vlmcsd_malloc(strlen(fn_ini_client) + 2);
940 strcpy(fn_bak, fn_ini_client);
941 strcat(fn_bak, "~");
943 if (stat(fn_ini_client, &statbuf))
945 if (errno != ENOENT)
947 errorout("Fatal: %s: %s\n", fn_ini_client, strerror(errno));
948 exit(!0);
950 else
952 iniFileExistedBefore = FALSE;
953 newIniBackupFile(fn_bak);
956 else
958 unlink(fn_bak); // Required for Windows. Most Unix systems don't need it.
959 if (rename(fn_ini_client, fn_bak))
961 errorout("Fatal: Cannot create %s: %s\n", fn_bak, strerror(errno));
962 exit(!0);
966 printf("\n%s file %s\n", iniFileExistedBefore ? "Updating" : "Creating", fn_ini_client);
968 FILE *restrict in, *restrict out;
970 in = fopen(fn_bak, "rb");
972 if (!in)
974 errorout("Fatal: Cannot open %s: %s\n", fn_bak, strerror(errno));
975 exit(!0);
978 out = fopen(fn_ini_client, "wb");
980 if (!out)
982 errorout("Fatal: Cannot create %s: %s\n", fn_ini_client, strerror(errno));
983 exit(!0);
986 char sourceLine[256];
988 for (lineNumber = 1; fgets(sourceLine, sizeof(sourceLine), in); lineNumber++)
990 for (i = 0; i < _countof(*lines); i++)
992 if (*(*lines)[i] && !strncasecmp(sourceLine, (*lines)[i], GUID_STRING_LENGTH))
994 if (lineWritten[i]) break;
996 fprintf(out, "%s", (*lines)[i]);
997 printf("line %2i: %s", lineNumber, (*lines)[i]);
998 lineWritten[i] = TRUE;
999 break;
1003 if (i >= _countof(*lines))
1005 fprintf(out, "%s", sourceLine);
1009 if (ferror(in))
1011 errorout("Fatal: Cannot read from %s: %s\n", fn_bak, strerror(errno));
1012 exit(!0);
1015 fclose(in);
1017 for (i = 0; i < _countof(*lines); i++)
1019 if (!lineWritten[i] && *(*lines)[i])
1021 fprintf(out, "%s", (*lines)[i]);
1022 printf("line %2i: %s", lineNumber + i, (*lines)[i]);
1026 if (fclose(out))
1028 errorout("Fatal: Cannot write to %s: %s\n", fn_ini_client, strerror(errno));
1029 exit(!0);
1032 if (!iniFileExistedBefore) unlink(fn_bak);
1034 free(fn_bak);
1037 static void grabServerData()
1039 RpcCtx s = INVALID_RPCCTX;
1040 WORD MajorVer = 6;
1041 iniFileEpidLines lines;
1042 int_fast8_t Licenses[_countof(lines)] = { 0, 15, 14 };
1043 uint_fast8_t i;
1044 RESPONSE response;
1045 RESPONSE_RESULT result;
1046 REQUEST request;
1047 hwid_t hwid;
1048 int status;
1049 size_t len;
1051 for (i = 0; i < _countof(lines); i++) *lines[i] = 0;
1053 for (i = 0; i < _countof(Licenses) && MajorVer > 3; i++)
1055 ActiveLicensePack = LicensePackList[Licenses[i]];
1056 ActiveLicensePack.kmsVersionMajor = MajorVer;
1057 status = sendRequest(&s, &request, &response, hwid, &result);
1058 printf("%-11s", ActiveLicensePack.names);
1060 if (status)
1062 displayRequestError(&s, status, i + 7 - MajorVer, 9 - MajorVer);
1064 if (status == 1) break;
1066 if ((status & 0xF0000000) == 0x80000000)
1068 MajorVer--;
1069 i--;
1072 continue;
1075 printf("%i of %i", (int)(i + 7 - MajorVer), (int)(9 - MajorVer));
1076 displayResponse(result, &request, &response, hwid);
1078 char guidBuffer[GUID_STRING_LENGTH + 1];
1079 char ePID[3 * PID_BUFFER_SIZE];
1081 uuid2StringLE(&request.AppID, guidBuffer);
1083 if (!ucs2_to_utf8(response.KmsPID, ePID, PID_BUFFER_SIZE, 3 * PID_BUFFER_SIZE))
1085 memset(ePID + 3 * PID_BUFFER_SIZE - 3, 0, 3);
1088 snprintf(lines[i], sizeof(lines[0]), "%s = %s", guidBuffer, ePID);
1090 if (response.MajorVer > 5)
1092 len = strlen(lines[i]);
1093 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]);
1096 len = strlen(lines[i]);
1097 snprintf(lines[i] + len, sizeof(lines[0]) - len, "\n");
1101 if (strcmp(fn_ini_client, "-"))
1103 updateIniFile(&lines);
1105 else
1107 printf("\n");
1108 for (i = 0; i < _countof(lines); i++) printf("%s", lines[i]);
1113 int client_main(const int argc, CARGV argv)
1115 #if defined(_WIN32) && !defined(USE_MSRPC)
1117 // Windows Sockets must be initialized
1119 WSADATA wsadata;
1120 int error;
1122 if ((error = WSAStartup(0x0202, &wsadata)))
1124 printerrorf("Fatal: Could not initialize Windows sockets (Error: %d).\n", error);
1125 return error;
1128 #endif // _WIN32
1130 #ifdef _NTSERVICE
1132 // We are not a service
1133 IsNTService = FALSE;
1135 // Set console output page to UTF-8
1136 // SetConsoleOutputCP(65001);
1138 #endif // _NTSERVICE
1140 randomNumberInit();
1141 ActiveLicensePack = *LicensePackList; //first license is Windows Vista
1143 parseCommandLinePass1(argc, argv);
1145 int_fast8_t useDefaultHost = FALSE;
1147 if (optind < argc)
1148 RemoteAddr = argv[optind];
1149 else
1150 useDefaultHost = TRUE;
1152 int hostportarg = optind;
1154 if (optind < argc - 1)
1156 parseCommandLinePass1(argc - hostportarg, argv + hostportarg);
1158 if (optind < argc - hostportarg)
1159 clientUsage(argv[0]);
1162 parseCommandLinePass2(argv[0], argc, argv);
1164 if (optind < argc - 1)
1165 parseCommandLinePass2(argv[0], argc - hostportarg, argv + hostportarg);
1167 if (useDefaultHost)
1168 RemoteAddr = AddressFamily == AF_INET6 ? "::1" : "127.0.0.1";
1170 if (fn_ini_client != NULL)
1171 grabServerData();
1172 else
1174 int requests;
1175 RpcCtx s = INVALID_RPCCTX;
1177 for (requests = 0, RequestsToGo = ActiveLicensePack.N_Policy - 1; RequestsToGo; requests++)
1179 RESPONSE response;
1180 REQUEST request;
1181 RESPONSE_RESULT result;
1182 hwid_t hwid;
1184 int status = sendRequest(&s, &request, &response, hwid, &result);
1186 if (FixedRequests) RequestsToGo = FixedRequests - requests - 1;
1188 if (status)
1190 displayRequestError(&s, status, requests + 1, RequestsToGo + requests + 1);
1191 if (!FixedRequests) RequestsToGo = 0;
1193 else
1195 if (!FixedRequests)
1197 if (firstRequestSent && ActiveLicensePack.N_Policy - (int)response.Count >= RequestsToGo)
1199 errorout("\nThe KMS server does not increment it's active clients. Aborting...\n");
1200 RequestsToGo = 0;
1202 else
1204 RequestsToGo = ActiveLicensePack.N_Policy - response.Count;
1205 if (RequestsToGo < 0) RequestsToGo = 0;
1209 fflush(stderr);
1210 printf("%i of %i ", requests + 1, RequestsToGo + requests + 1);
1211 displayResponse(result, &request, &response, hwid);
1212 firstRequestSent = TRUE;
1217 return 0;
1221 // Create Base KMS Client Request
1222 static void CreateRequestBase(REQUEST *Request)
1225 Request->MinorVer = LE16((WORD)kmsVersionMinor);
1226 Request->MajorVer = LE16((WORD)ActiveLicensePack.kmsVersionMajor);
1227 Request->VMInfo = LE32(VMInfo);
1228 Request->LicenseStatus = LE32(LicenseStatus);
1229 Request->BindingExpiration = LE32(BindingExpiration);
1230 LEGUID(&Request->AppID, ActiveLicensePack.AppID);
1231 LEGUID(&Request->ActID, &ActiveLicensePack.ActID);
1232 LEGUID(&Request->KMSID, &ActiveLicensePack.KMSID);
1234 getUnixTimeAsFileTime(&Request->ClientTime);
1235 Request->N_Policy = LE32(ActiveLicensePack.N_Policy);
1238 GUID tempGUID;
1240 if (CMID)
1242 string2UuidOrExit(CMID, &tempGUID);
1243 LEGUID(&Request->CMID, &tempGUID);
1245 else
1247 get16RandomBytes(&Request->CMID);
1249 // Set reserved UUID bits
1250 Request->CMID.Data4[0] &= 0x3F;
1251 Request->CMID.Data4[0] |= 0x80;
1253 // Set UUID type 4 (random UUID)
1254 Request->CMID.Data3 &= LE16(0xfff);
1255 Request->CMID.Data3 |= LE16(0x4000);
1258 if (CMID_prev)
1260 string2UuidOrExit(CMID_prev, &tempGUID);
1261 LEGUID(&Request->CMID_prev, &tempGUID);
1263 else
1265 memset(&Request->CMID_prev, 0, sizeof(Request->CMID_prev));
1269 static const char alphanum[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /*"abcdefghijklmnopqrstuvwxyz" */;
1271 if (WorkstationName)
1273 utf8_to_ucs2(Request->WorkstationName, WorkstationName, WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
1275 else if (dnsnames)
1277 int len, len2;
1278 unsigned int index = rand() % _countof(ClientDnsNames.first);
1279 len = utf8_to_ucs2(Request->WorkstationName, ClientDnsNames.first[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
1281 index = rand() % _countof(ClientDnsNames.second);
1282 len2 = utf8_to_ucs2(Request->WorkstationName + len, ClientDnsNames.second[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
1284 index = rand() % _countof(ClientDnsNames.tld);
1285 utf8_to_ucs2(Request->WorkstationName + len + len2, ClientDnsNames.tld[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
1287 else
1289 unsigned int size = (rand() % 14) + 1;
1290 const unsigned char *dummy;
1291 unsigned int i;
1293 for (i = 0; i < size; i++)
1295 Request->WorkstationName[i] = utf8_to_ucs2_char((unsigned char*)alphanum + (rand() % (sizeof(alphanum) - 1)), &dummy);
1298 Request->WorkstationName[size] = 0;
1301 //Show Details
1302 if (verbose)
1304 printf("\nRequest Parameters\n==================\n\n");
1305 logRequestVerbose(Request, &printf);
1306 printf("\n");