Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

340 lines
9.3 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: verify.c
  7. //
  8. // Contents: License Verification API
  9. //
  10. // History: 01-21-98 FredCh Created
  11. //
  12. //-----------------------------------------------------------------------------
  13. #include "precomp.h"
  14. #include "tlsapip.h"
  15. extern DWORD g_dwLicenseExpirationLeeway;
  16. ///////////////////////////////////////////////////////////////////////////////
  17. LICENSE_STATUS
  18. GetVerifyResult(
  19. DWORD dwLicenseState )
  20. {
  21. switch( dwLicenseState )
  22. {
  23. //
  24. // Temporary licenses verification results
  25. //
  26. case ( LICENSE_STATE_INVALID_PRODUCT ) :
  27. // FALL THRU - TS5 RC1 license server bug.
  28. case( VERIFY_RESULT_TEMP_0_0 ):
  29. return( LICENSE_STATUS_SHOULD_UPGRADE_LICENSE );
  30. case( VERIFY_RESULT_TEMP_EXPIRED_0 ):
  31. return( LICENSE_STATUS_MUST_UPGRADE_LICENSE );
  32. case( VERIFY_RESULT_TEMP_0_OLD ):
  33. return( LICENSE_STATUS_MUST_UPGRADE_LICENSE );
  34. case( VERIFY_RESULT_TEMP_EXPIRED_OLD ):
  35. return( LICENSE_STATUS_MUST_UPGRADE_LICENSE );
  36. //
  37. // permanent license verification results
  38. //
  39. case( VERIFY_RESULT_0_EXPIRED_0 ):
  40. return( LICENSE_STATUS_MUST_UPGRADE_LICENSE );
  41. case( VERIFY_RESULT_0_EXPIRED_OLD ):
  42. return( LICENSE_STATUS_MUST_UPGRADE_LICENSE );
  43. case( VERIFY_RESULT_0_LEEWAY_0 ):
  44. return( LICENSE_STATUS_SHOULD_UPGRADE_LICENSE );
  45. case( VERIFY_RESULT_0_LEEWAY_OLD ):
  46. return( LICENSE_STATUS_MUST_UPGRADE_LICENSE );
  47. case( VERIFY_RESULT_0_0_OLD ):
  48. return( LICENSE_STATUS_MUST_UPGRADE_LICENSE );
  49. case( VERIFY_RESULT_0_0_0 ):
  50. return( LICENSE_STATUS_OK );
  51. default:
  52. //
  53. // this case should never happen. For now, if it happens, just
  54. // let the client go through
  55. //
  56. // ASSERT( VERIFY_RESULT_0_EXPIRED_0 );
  57. #if DBG
  58. DbgPrint( "GetVerifyResult: Invalid verification result: 0x%x\n", dwLicenseState );
  59. #endif
  60. return( LICENSE_STATUS_INVALID_LICENSE );
  61. // return( LICENSE_STATUS_CANNOT_DECODE_LICENSE );
  62. }
  63. }
  64. ///////////////////////////////////////////////////////////////////////////////
  65. LICENSE_STATUS
  66. VerifyClientHwid(
  67. PHS_Protocol_Context pContext,
  68. PValidation_Info pValidationInfo,
  69. PLICENSEDPRODUCT pLicenseInfo )
  70. {
  71. HWID Hwid;
  72. LICENSE_STATUS Status;
  73. //
  74. // do a memory compare of the HWID
  75. //
  76. if( 0 != memcmp( &pLicenseInfo->Hwid, pValidationInfo->pValidationData,
  77. sizeof( HWID ) ) )
  78. {
  79. return( LICENSE_STATUS_CANNOT_VERIFY_HWID );
  80. }
  81. return ( LICENSE_STATUS_OK );
  82. #if 0
  83. #define LICENSE_MIN_MATCH_COUNT 3
  84. HWID* pHwid;
  85. DWORD dwMatchCount;
  86. //
  87. // liceapi.c, line 1023 set this to HWID
  88. //
  89. pHwid = (HWID *)pValidationInfo->pValidationData;
  90. dwMatchCount = 0;
  91. dwMatchCount += (pHwid->dwPlatformID == pLicenseInfo->Hwid.dwPlatformID);
  92. dwMatchCount += (pHwid->Data1 == pLicenseInfo->Hwid.Data1);
  93. dwMatchCount += (pHwid->Data2 == pLicenseInfo->Hwid.Data2);
  94. dwMatchCount += (pHwid->Data3 == pLicenseInfo->Hwid.Data3);
  95. dwMatchCount += (pHwid->Data4 == pLicenseInfo->Hwid.Data4);
  96. return (dwMatchCount >= LICENSE_MIN_MATCH_COUNT) ?
  97. LICENSE_STATUS_OK : LICENSE_STATUS_CANNOT_VERIFY_HWID;
  98. #endif
  99. }
  100. ///////////////////////////////////////////////////////////////////////////////
  101. LICENSE_STATUS
  102. VerifyLicenseProductInfo(
  103. PHS_Protocol_Context pLmContext,
  104. PValidation_Info pValidationInfo,
  105. PLICENSEDPRODUCT pLicenseInfo,
  106. PDWORD pdwLicenseState )
  107. {
  108. DWORD
  109. cbCompanyName = ( wcslen( PRODUCT_INFO_COMPANY_NAME ) + 1 ) * sizeof( TCHAR ),
  110. cbProductId = ( wcslen( PRODUCT_INFO_SKU_PRODUCT_ID ) + 1 ) * sizeof( TCHAR );
  111. //
  112. // Verify the company name
  113. //
  114. if( pLicenseInfo->LicensedProduct.pProductInfo->cbCompanyName < cbCompanyName )
  115. {
  116. #if DBG
  117. DbgPrint( "LICPROT: Invalid company name in client license\n" );
  118. #endif
  119. // return( LICENSE_STATUS_INVALID_LICENSE );
  120. return( LICENSE_STATUS_CANNOT_DECODE_LICENSE );
  121. }
  122. if ( 0 != memcmp( pLicenseInfo->LicensedProduct.pProductInfo->pbCompanyName,
  123. PRODUCT_INFO_COMPANY_NAME, cbCompanyName ) )
  124. {
  125. #if DBG
  126. DbgPrint( "LICPROT: Invalid company name in client license\n" );
  127. #endif
  128. // return( LICENSE_STATUS_INVALID_LICENSE );
  129. return( LICENSE_STATUS_CANNOT_DECODE_LICENSE );
  130. }
  131. //
  132. // verify the product ID
  133. //
  134. if( pLicenseInfo->cbOrgProductID < cbProductId )
  135. {
  136. // return( LICENSE_STATUS_INVALID_LICENSE );
  137. return( LICENSE_STATUS_CANNOT_DECODE_LICENSE );
  138. }
  139. if( 0 != memcmp( pLicenseInfo->pbOrgProductID,
  140. PRODUCT_INFO_SKU_PRODUCT_ID, cbProductId ) )
  141. {
  142. #if DBG
  143. DbgPrint( "LICPROT: Invalid product ID in client license\n" );
  144. #endif
  145. // return( LICENSE_STATUS_INVALID_LICENSE );
  146. return( LICENSE_STATUS_CANNOT_DECODE_LICENSE );
  147. }
  148. //
  149. // Check actual licensed product.
  150. //
  151. if( pLicenseInfo->LicensedProduct.pProductInfo->cbProductID == 0 )
  152. {
  153. #if DBG
  154. DbgPrint( "LICPROT: Invalid Product ID in client license\n" );
  155. #endif
  156. // return( LICENSE_STATUS_INVALID_LICENSE );
  157. return( LICENSE_STATUS_CANNOT_DECODE_LICENSE );
  158. }
  159. if( 0 != memcmp(pLicenseInfo->LicensedProduct.pProductInfo->pbProductID,
  160. PRODUCT_INFO_SKU_PRODUCT_ID, wcslen(PRODUCT_INFO_SKU_PRODUCT_ID) * sizeof(WCHAR)) )
  161. {
  162. #if DBG
  163. DbgPrint( "LICPROT: Invalid product ID in client license\n" );
  164. #endif
  165. if( 0 == memcmp(pLicenseInfo->LicensedProduct.pProductInfo->pbProductID,
  166. PRODUCT_INFO_INTERNET_SKU_PRODUCT_ID, wcslen(PRODUCT_INFO_INTERNET_SKU_PRODUCT_ID) * sizeof(WCHAR)) )
  167. {
  168. // TS5 beta3 RC1 license server bug, force a upgrade license.
  169. LicenseSetState( *pdwLicenseState, LICENSE_STATE_INVALID_PRODUCT );
  170. return( LICENSE_STATUS_OK );
  171. }
  172. //
  173. // Backward compatibility - treat the new product ID as product family and
  174. // let client connect
  175. //
  176. }
  177. //
  178. // check if this is a temporary license
  179. //
  180. if( pLicenseInfo->pLicensedVersion->dwFlags & 0x80000000 )
  181. {
  182. LicenseSetState( *pdwLicenseState, LICENSE_STATE_TEMPORARY );
  183. }
  184. else if(TLSIsBetaNTServer() == FALSE)
  185. {
  186. // verify license is issued by RTM license server
  187. if(IS_LICENSE_ISSUER_RTM(pLicenseInfo->pLicensedVersion->dwFlags) == FALSE)
  188. {
  189. //LicenseSetState( *pdwLicenseState, VERIFY_RESULT_BETA_LICENSE );
  190. return( LICENSE_STATUS_INVALID_LICENSE );
  191. }
  192. }
  193. if(TLSIsLicenseEnforceEnable() == TRUE)
  194. {
  195. //
  196. // W2K beta 3 to RC1 upgrade.
  197. // Enforce TermSrv will reject any license issued by Beta 3 non-enforce license
  198. // server.
  199. //
  200. if( GET_LICENSE_ISSUER_MAJORVERSION(pLicenseInfo->pLicensedVersion->dwFlags) <= 5 &&
  201. GET_LICENSE_ISSUER_MINORVERSION(pLicenseInfo->pLicensedVersion->dwFlags) <= 2 )
  202. {
  203. //
  204. // Build 20XX license server has version of 05 03, since we still need to maintain
  205. // inter-op, we don't want to keep rejecting client holding non-enforce
  206. // license server, so we check if license issuer is 5.2 or older.
  207. //
  208. if( IS_LICENSE_ISSUER_ENFORCE(pLicenseInfo->pLicensedVersion->dwFlags) == FALSE )
  209. {
  210. #if DBG
  211. DbgPrint( "LICPROT: Rejecting license from non-enforce license server\n" );
  212. #endif
  213. return( LICENSE_STATUS_INVALID_LICENSE );
  214. }
  215. }
  216. }
  217. return( LICENSE_STATUS_OK );
  218. }
  219. ///////////////////////////////////////////////////////////////////////////////
  220. LICENSE_STATUS
  221. VerifyLicenseDateAndTime(
  222. PLICENSEDPRODUCT pLicenseInfo,
  223. PDWORD pdwLicenseState )
  224. {
  225. SYSTEMTIME CurrentSysTime;
  226. FILETIME CurrentFileTime;
  227. LONG lReturn;
  228. ULARGE_INTEGER ullNotAfterLeeway;
  229. ULARGE_INTEGER ullCurrentTime;
  230. //
  231. // get the current system time
  232. //
  233. GetSystemTime( &CurrentSysTime );
  234. //
  235. // convert it to file time
  236. //
  237. SystemTimeToFileTime( &CurrentSysTime, &CurrentFileTime );
  238. //
  239. // Verify that the license is still valid at this time
  240. //
  241. lReturn = CompareFileTime( &pLicenseInfo->NotAfter, &CurrentFileTime );
  242. if( 1 != lReturn )
  243. {
  244. LicenseSetState( *pdwLicenseState, LICENSE_STATE_EXPIRED );
  245. }
  246. else if (!(pLicenseInfo->pLicensedVersion->dwFlags & 0x80000000))
  247. {
  248. // permanent license
  249. ullNotAfterLeeway.LowPart = pLicenseInfo->NotAfter.dwLowDateTime;
  250. ullNotAfterLeeway.HighPart = pLicenseInfo->NotAfter.dwHighDateTime;
  251. ullNotAfterLeeway.QuadPart -= Int32x32To64(g_dwLicenseExpirationLeeway,10*1000*1000);
  252. ullCurrentTime.LowPart = CurrentFileTime.dwLowDateTime;
  253. ullCurrentTime.HighPart = CurrentFileTime.dwHighDateTime;
  254. if (ullNotAfterLeeway.QuadPart < ullCurrentTime.QuadPart)
  255. {
  256. LicenseSetState( *pdwLicenseState, LICENSE_STATE_LEEWAY );
  257. }
  258. }
  259. return( LICENSE_STATUS_OK );
  260. }