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.

345 lines
8.8 KiB

  1. //=============================================================================
  2. // Copyright (c) 2000 Microsoft Corporation
  3. //
  4. // utils.cpp
  5. //
  6. // Credential manager user interface utility functions.
  7. //
  8. // Created 06/06/2000 johnstep (John Stephens)
  9. //=============================================================================
  10. #include "cred_pch.h"
  11. #include "utils.h"
  12. //=============================================================================
  13. // CreduiIsRemovableCertificate
  14. //
  15. // Arguments:
  16. // certContext (in) - certificate context to query
  17. //
  18. // Returns TRUE if the certificate has a removable component (such as a smart
  19. // card) or FALSE otherwise.
  20. //
  21. // Created 04/09/2000 johnstep (John Stephens)
  22. //=============================================================================
  23. BOOL
  24. CreduiIsRemovableCertificate(
  25. CONST CERT_CONTEXT *certContext
  26. )
  27. {
  28. BOOL isRemovable = FALSE;
  29. // First, determine the buffer size:
  30. DWORD bufferSize = 0;
  31. if (CertGetCertificateContextProperty(
  32. certContext,
  33. CERT_KEY_PROV_INFO_PROP_ID,
  34. NULL,
  35. &bufferSize))
  36. {
  37. // Allocate the buffer on the stack:
  38. CRYPT_KEY_PROV_INFO *provInfo;
  39. __try
  40. {
  41. provInfo = static_cast<CRYPT_KEY_PROV_INFO *>(alloca(bufferSize));
  42. }
  43. __except(EXCEPTION_EXECUTE_HANDLER)
  44. {
  45. provInfo = NULL;
  46. }
  47. if (provInfo != NULL)
  48. {
  49. if (CertGetCertificateContextProperty(
  50. certContext,
  51. CERT_KEY_PROV_INFO_PROP_ID,
  52. provInfo,
  53. &bufferSize))
  54. {
  55. HCRYPTPROV provContext;
  56. if (CryptAcquireContext(
  57. &provContext,
  58. NULL,
  59. provInfo->pwszProvName,
  60. provInfo->dwProvType,
  61. CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
  62. {
  63. DWORD impType;
  64. DWORD impTypeSize = sizeof impType;
  65. if (CryptGetProvParam(
  66. provContext,
  67. PP_IMPTYPE,
  68. reinterpret_cast<BYTE *>(&impType),
  69. &impTypeSize,
  70. 0))
  71. {
  72. if (impType & CRYPT_IMPL_REMOVABLE)
  73. {
  74. isRemovable = TRUE;
  75. }
  76. }
  77. if (!CryptReleaseContext(provContext, 0))
  78. {
  79. CreduiDebugLog(
  80. "CreduiIsRemovableCertificate: "
  81. "CryptReleaseContext failed: %u\n",
  82. GetLastError());
  83. }
  84. }
  85. }
  86. }
  87. }
  88. return isRemovable;
  89. }
  90. //=============================================================================
  91. // CreduiGetCertificateDisplayName
  92. //
  93. // Arguments:
  94. // certContext (in)
  95. // displayName (out)
  96. // displayNameMaxChars (in)
  97. // certificateString (in)
  98. //
  99. // Returns TRUE if a display name was stored or FALSE otherwise.
  100. //
  101. // Created 06/12/2000 johnstep (John Stephens)
  102. //=============================================================================
  103. BOOL
  104. CreduiGetCertificateDisplayName(
  105. CONST CERT_CONTEXT *certContext,
  106. WCHAR *displayName,
  107. ULONG displayNameMaxChars,
  108. WCHAR *certificateString
  109. )
  110. {
  111. BOOL success = FALSE;
  112. WCHAR *tempName;
  113. ULONG tempNameMaxChars = displayNameMaxChars / 2 - 1;
  114. __try
  115. {
  116. tempName =
  117. static_cast<WCHAR *>(
  118. alloca(tempNameMaxChars * sizeof (WCHAR)));
  119. }
  120. __except(EXCEPTION_EXECUTE_HANDLER)
  121. {
  122. tempName = NULL;
  123. }
  124. if (tempName == NULL)
  125. {
  126. return FALSE;
  127. }
  128. displayName[0] = L'\0';
  129. tempName[0] = L'\0';
  130. if (CertGetNameString(
  131. certContext,
  132. CERT_NAME_FRIENDLY_DISPLAY_TYPE,
  133. 0,
  134. NULL,
  135. tempName,
  136. tempNameMaxChars))
  137. {
  138. success = TRUE;
  139. lstrcpy(displayName, tempName);
  140. }
  141. if (CertGetNameString(
  142. certContext,
  143. CERT_NAME_FRIENDLY_DISPLAY_TYPE,
  144. CERT_NAME_ISSUER_FLAG,
  145. NULL,
  146. tempName,
  147. tempNameMaxChars))
  148. {
  149. if (lstrcmpi(displayName, tempName) != 0)
  150. {
  151. success = TRUE;
  152. WCHAR *where = &displayName[lstrlen(displayName)];
  153. if (where > displayName)
  154. {
  155. *where++ = L' ';
  156. *where++ = L'-';
  157. *where++ = L' ';
  158. }
  159. lstrcpy(where, tempName);
  160. }
  161. }
  162. return success;
  163. }
  164. //=============================================================================
  165. // CreduiGetCertDisplayNameFromMarshaledName
  166. //
  167. // Arguments:
  168. // marshaledName (in)
  169. // displayName (out)
  170. // displayNameMaxChars (in)
  171. // onlyRemovable (in) - only get name if for a "removable" certificate
  172. //
  173. // Returns TRUE if a display name was stored or FALSE otherwise.
  174. //
  175. // Created 07/24/2000 johnstep (John Stephens)
  176. //=============================================================================
  177. BOOL
  178. CreduiGetCertDisplayNameFromMarshaledName(
  179. WCHAR *marshaledName,
  180. WCHAR *displayName,
  181. ULONG displayNameMaxChars,
  182. BOOL onlyRemovable
  183. )
  184. {
  185. BOOL success = FALSE;
  186. CRED_MARSHAL_TYPE credMarshalType;
  187. CERT_CREDENTIAL_INFO *certCredInfo;
  188. if (CredUnmarshalCredential(
  189. marshaledName,
  190. &credMarshalType,
  191. reinterpret_cast<VOID **>(&certCredInfo)))
  192. {
  193. if (credMarshalType == CertCredential)
  194. {
  195. HCERTSTORE certStore;
  196. CONST CERT_CONTEXT *certContext;
  197. certStore = CertOpenSystemStore(NULL, L"MY");
  198. if (certStore != NULL)
  199. {
  200. CRYPT_HASH_BLOB hashBlob;
  201. hashBlob.cbData = CERT_HASH_LENGTH;
  202. hashBlob.pbData = reinterpret_cast<BYTE *>(
  203. certCredInfo->rgbHashOfCert);
  204. certContext = CertFindCertificateInStore(
  205. certStore,
  206. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  207. 0,
  208. CERT_FIND_SHA1_HASH,
  209. &hashBlob,
  210. NULL);
  211. if (certContext != NULL)
  212. {
  213. // If onlyRemovable is TRUE, check to see if this is a
  214. // certificate with a removable hardware component; this
  215. // usually means a smart card:
  216. if (!onlyRemovable ||
  217. CreduiIsRemovableCertificate(certContext))
  218. {
  219. success =
  220. CreduiGetCertificateDisplayName(
  221. certContext,
  222. displayName,
  223. displayNameMaxChars,
  224. NULL);
  225. }
  226. CertFreeCertificateContext(certContext);
  227. }
  228. // CertCloseStore returns FALSE if it fails. We could try
  229. // again, depending on the error returned by GetLastError:
  230. CertCloseStore(certStore, 0);
  231. }
  232. }
  233. CredFree(static_cast<VOID *>(certCredInfo));
  234. }
  235. return success;
  236. }
  237. LPWSTR
  238. GetAccountDomainName(
  239. VOID
  240. )
  241. /*++
  242. Routine Description:
  243. Returns the name of the account domain for this machine.
  244. For workstatations, the account domain is the netbios computer name.
  245. For DCs, the account domain is the netbios domain name.
  246. Arguments:
  247. None.
  248. Return Values:
  249. Returns a pointer to the name. The name should be free using NetApiBufferFree.
  250. NULL - on error.
  251. --*/
  252. {
  253. BOOL CreduiIsDomainController = FALSE;
  254. DWORD WinStatus;
  255. LPWSTR AllocatedName = NULL;
  256. OSVERSIONINFOEXW versionInfo;
  257. versionInfo.dwOSVersionInfoSize = sizeof OSVERSIONINFOEXW;
  258. if (GetVersionEx(reinterpret_cast<OSVERSIONINFOW *>(&versionInfo)))
  259. {
  260. CreduiIsDomainController = (versionInfo.wProductType == VER_NT_DOMAIN_CONTROLLER);
  261. }
  262. //
  263. // If this machine is a domain controller,
  264. // get the domain name.
  265. //
  266. if ( CreduiIsDomainController ) {
  267. WinStatus = NetpGetDomainName( &AllocatedName );
  268. if ( WinStatus != NO_ERROR ) {
  269. return NULL;
  270. }
  271. //
  272. // Otherwise, the 'account domain' is the computername
  273. //
  274. } else {
  275. WinStatus = NetpGetComputerName( &AllocatedName );
  276. if ( WinStatus != NO_ERROR ) {
  277. return NULL;
  278. }
  279. }
  280. return AllocatedName;
  281. }