output.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #ifndef _DEFAULT_SOURCE
  2. #define _DEFAULT_SOURCE
  3. #endif // _DEFAULT_SOURCE
  4. #ifndef CONFIG
  5. #define CONFIG "config.h"
  6. #endif // CONFIG
  7. #include CONFIG
  8. #include "output.h"
  9. #include "shared_globals.h"
  10. #include "endian.h"
  11. #include "helpers.h"
  12. #ifndef NO_LOG
  13. static void vlogger(const char *message, va_list args)
  14. {
  15. FILE *log;
  16. #ifdef _NTSERVICE
  17. if (!IsNTService && logstdout) log = stdout;
  18. #else
  19. if (logstdout) log = stdout;
  20. #endif
  21. else
  22. {
  23. if (fn_log == NULL) return;
  24. #ifndef _WIN32
  25. if (!strcmp(fn_log, "syslog"))
  26. {
  27. openlog("vlmcsd", LOG_CONS | LOG_PID, LOG_USER);
  28. ////PORTABILITY: vsyslog is not in Posix but virtually all Unixes have it
  29. vsyslog(LOG_INFO, message, args);
  30. closelog();
  31. return;
  32. }
  33. #endif // _WIN32
  34. log = fopen(fn_log, "a");
  35. if ( !log ) return;
  36. }
  37. time_t now = time(0);
  38. #ifdef USE_THREADS
  39. char mbstr[2048];
  40. #else
  41. char mbstr[24];
  42. #endif
  43. strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", localtime(&now));
  44. #ifndef USE_THREADS
  45. fprintf(log, "%s: ", mbstr);
  46. vfprintf(log, message, args);
  47. fflush(log);
  48. #else // USE_THREADS
  49. // We write everything to a string before we really log inside the critical section
  50. // so formatting the output can be concurrent
  51. strcat(mbstr, ": ");
  52. int len = strlen(mbstr);
  53. vsnprintf(mbstr + len, sizeof(mbstr) - len, message, args);
  54. lock_mutex(&logmutex);
  55. fputs(mbstr, log);
  56. fflush(log);
  57. unlock_mutex(&logmutex);
  58. #endif // USE_THREADS
  59. if (log != stdout) fclose(log);
  60. }
  61. // Always sends to log output
  62. int logger(const char *const fmt, ...)
  63. {
  64. va_list args;
  65. va_start(args, fmt);
  66. vlogger(fmt, args);
  67. va_end(args);
  68. return 0;
  69. }
  70. #endif //NO_LOG
  71. // Output to stderr if it is available or to log otherwise (e.g. if running as daemon/service)
  72. void printerrorf(const char *const fmt, ...)
  73. {
  74. va_list arglist;
  75. va_start(arglist, fmt);
  76. #ifndef NO_LOG
  77. #ifdef _NTSERVICE
  78. if (InetdMode || IsNTService)
  79. #else // !_NTSERVICE
  80. if (InetdMode)
  81. #endif // NTSERVIICE
  82. vlogger(fmt, arglist);
  83. else
  84. #endif //NO_LOG
  85. {
  86. vfprintf(stderr, fmt, arglist);
  87. fflush(stderr);
  88. }
  89. va_end(arglist);
  90. }
  91. // Always output to stderr
  92. int errorout(const char* fmt, ...)
  93. {
  94. va_list args;
  95. va_start(args, fmt);
  96. int i = vfprintf(stderr, fmt, args);
  97. va_end(args);
  98. fflush(stderr);
  99. return i;
  100. }
  101. static const char *LicenseStatusText[] =
  102. {
  103. "Unlicensed", "Licensed", "OOB grace", "OOT grace", "Non-Genuine", "Notification", "Extended grace"
  104. };
  105. void uuid2StringLE(const GUID *const guid, char *const string)
  106. {
  107. sprintf(string,
  108. #ifdef _WIN32
  109. "%08x-%04x-%04x-%04x-%012I64x",
  110. #else
  111. "%08x-%04x-%04x-%04x-%012llx",
  112. #endif
  113. (unsigned int)LE32( guid->Data1 ),
  114. (unsigned int)LE16( guid->Data2 ),
  115. (unsigned int)LE16( guid->Data3 ),
  116. (unsigned int)BE16( *(uint16_t*)guid->Data4 ),
  117. (unsigned long long)BE64(*(uint64_t*)(guid->Data4)) & 0xffffffffffffLL
  118. );
  119. }
  120. void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p)
  121. {
  122. char guidBuffer[GUID_STRING_LENGTH + 1];
  123. char WorkstationBuffer[3 * WORKSTATION_NAME_BUFFER];
  124. const char *productName;
  125. ProdListIndex_t index;
  126. p("Protocol version : %u.%u\n", LE16(Request->MajorVer), LE16(Request->MinorVer));
  127. p("Client is a virtual machine : %s\n", LE32(Request->VMInfo) ? "Yes" : "No");
  128. p("Licensing status : %u (%s)\n", (uint32_t)LE32(Request->LicenseStatus), LE32(Request->LicenseStatus) < _countof(LicenseStatusText) ? LicenseStatusText[LE32(Request->LicenseStatus)] : "Unknown");
  129. p("Remaining time (0 = forever) : %i minutes\n", (uint32_t)LE32(Request->BindingExpiration));
  130. uuid2StringLE(&Request->AppID, guidBuffer);
  131. productName = getProductNameLE(&Request->AppID, AppList, &index);
  132. p("Application ID : %s (%s)\n", guidBuffer, productName);
  133. uuid2StringLE(&Request->ActID, guidBuffer);
  134. #ifndef NO_EXTENDED_PRODUCT_LIST
  135. productName = getProductNameLE(&Request->ActID, ExtendedProductList, &index);
  136. #else
  137. productName = "Unknown";
  138. #endif
  139. p("Activation ID (Product) : %s (%s)\n", guidBuffer, productName);
  140. uuid2StringLE(&Request->KMSID, guidBuffer);
  141. #ifndef NO_BASIC_PRODUCT_LIST
  142. productName = getProductNameLE(&Request->KMSID, ProductList, &index);
  143. #else
  144. productName = "Unknown";
  145. #endif
  146. p("Key Management Service ID : %s (%s)\n", guidBuffer, productName);
  147. uuid2StringLE(&Request->CMID, guidBuffer);
  148. p("Client machine ID : %s\n", guidBuffer);
  149. uuid2StringLE(&Request->CMID_prev, guidBuffer);
  150. p("Previous client machine ID : %s\n", guidBuffer);
  151. char mbstr[64];
  152. time_t st;
  153. st = fileTimeToUnixTime(&Request->ClientTime);
  154. strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st));
  155. p("Client request timestamp (UTC) : %s\n", mbstr);
  156. ucs2_to_utf8(Request->WorkstationName, WorkstationBuffer, WORKSTATION_NAME_BUFFER, sizeof(WorkstationBuffer));
  157. p("Workstation name : %s\n", WorkstationBuffer);
  158. p("N count policy (minimum clients): %u\n", (uint32_t)LE32(Request->N_Policy));
  159. }
  160. void logResponseVerbose(const char *const ePID, const BYTE *const hwid, const RESPONSE *const response, const PRINTFUNC p)
  161. {
  162. char guidBuffer[GUID_STRING_LENGTH + 1];
  163. //SYSTEMTIME st;
  164. p("Protocol version : %u.%u\n", (uint32_t)LE16(response->MajorVer), (uint32_t)LE16(response->MinorVer));
  165. p("KMS host extended PID : %s\n", ePID);
  166. if (LE16(response->MajorVer) > 5)
  167. # ifndef _WIN32
  168. p("KMS host Hardware ID : %016llX\n", (unsigned long long)BE64(*(uint64_t*)hwid));
  169. # else // _WIN32
  170. p("KMS host Hardware ID : %016I64X\n", (unsigned long long)BE64(*(uint64_t*)hwid));
  171. # endif // WIN32
  172. uuid2StringLE(&response->CMID, guidBuffer);
  173. p("Client machine ID : %s\n", guidBuffer);
  174. char mbstr[64];
  175. time_t st;
  176. st = fileTimeToUnixTime(&response->ClientTime);
  177. strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st));
  178. p("Client request timestamp (UTC) : %s\n", mbstr);
  179. p("KMS host current active clients : %u\n", (uint32_t)LE32(response->Count));
  180. p("Renewal interval policy : %u\n", (uint32_t)LE32(response->VLRenewalInterval));
  181. p("Activation interval policy : %u\n", (uint32_t)LE32(response->VLActivationInterval));
  182. }