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.

297 lines
7.3 KiB

  1. //
  2. // NetUtil.cpp
  3. //
  4. #include "stdafx.h"
  5. #include <lm.h>
  6. #include "NetUtil.h"
  7. #include <wincrypt.h>
  8. #include <certrpc.h>
  9. #include <certcli.h>
  10. #include <malloc.h>
  11. #define LEVEL_1 1
  12. #define LEVEL_2 2
  13. BOOL GetCurrentUserFullName(CString& name)
  14. {
  15. BOOL bRes = FALSE;
  16. NET_API_STATUS nas;
  17. WKSTA_USER_INFO_1 * pWksInfo = NULL;
  18. if (NERR_Success == (nas = NetWkstaUserGetInfo(NULL,
  19. LEVEL_1, (BYTE **)&pWksInfo)))
  20. {
  21. USER_INFO_2 * pUserInfo = NULL;
  22. CString strServerName = _T("\\\\");
  23. ASSERT(pWksInfo->wkui1_logon_server[0] != 0);
  24. strServerName += pWksInfo->wkui1_logon_server;
  25. if (NERR_Success == (nas = NetUserGetInfo(
  26. (LPCWSTR)strServerName,
  27. (LPCWSTR)pWksInfo->wkui1_username,
  28. LEVEL_2,
  29. (BYTE **)&pUserInfo)))
  30. {
  31. name = pUserInfo->usri2_full_name;
  32. if (pUserInfo != NULL)
  33. NetApiBufferFree(pUserInfo);
  34. bRes = TRUE;
  35. }
  36. if (pWksInfo != NULL)
  37. NetApiBufferFree(pWksInfo);
  38. }
  39. return bRes;
  40. }
  41. #if 0
  42. /*********************************** Direct Cert Request *********************************/
  43. typedef struct _RPC_BINDING_LIST
  44. {
  45. LPTSTR pszProtSeq;
  46. LPTSTR pszEndpoint;
  47. } RPC_BINDING_LIST;
  48. RPC_BINDING_LIST g_BindingList[] =
  49. {
  50. {_T("ncacn_ip_tcp"), NULL},
  51. {_T("ncacn_np"), _T("\\pipe\\cert")}
  52. };
  53. DWORD g_BindingListSize = sizeof(g_BindingList)/sizeof(g_BindingList[0]);
  54. typedef struct _RPC_ATHN_LIST
  55. {
  56. DWORD dwAuthnLevel;
  57. DWORD dwAuthnService;
  58. } RPC_ATHN_LIST;
  59. RPC_ATHN_LIST g_AthnList[] =
  60. {
  61. { RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_GSS_NEGOTIATE},
  62. { RPC_C_AUTHN_LEVEL_NONE, RPC_C_AUTHN_NONE }
  63. };
  64. DWORD g_AthnListSize = sizeof(g_AthnList)/sizeof(g_AthnList[0]);
  65. //-----------------------------------------------------------------------
  66. //
  67. // RetrivePKCS7FromCA
  68. //
  69. //------------------------------------------------------------------------
  70. HRESULT
  71. RetrievePKCS7FromCA(CString& strCALocation,
  72. CString& strCAName,
  73. LPWSTR pwszRequestString,
  74. CRYPT_DATA_BLOB * pPKCS10Blob,
  75. CRYPT_DATA_BLOB * pPKCS7Blob,
  76. DWORD * pdwStatus,
  77. BOOL bRenew)
  78. {
  79. HRESULT hr = E_FAIL;
  80. UINT id = 0;
  81. DWORD dwDisposition = 0;
  82. DWORD dwErr = 0;
  83. DWORD dwStatus = 0;
  84. RPC_STATUS rpcStatus = 0;
  85. CERTTRANSBLOB tbRequest = {0, NULL};
  86. CERTTRANSBLOB tbCert = {0, NULL};
  87. CERTTRANSBLOB tbCertChain = {0, NULL};
  88. CERTTRANSBLOB tbAttrib = {0, NULL};
  89. CERTTRANSBLOB tbDispositionMessage = {0, NULL};
  90. LPTSTR szStringBinding = NULL;
  91. RPC_BINDING_HANDLE hCARPCBinding = NULL;
  92. LPTSTR pszCAPrinceName = NULL;
  93. //input checking
  94. if (!pPKCS10Blob || !pPKCS7Blob)
  95. return E_INVALIDARG;
  96. for (DWORD i = 0; i < g_BindingListSize; i++)
  97. {
  98. if (RPC_S_OK != RpcNetworkIsProtseqValid(g_BindingList[i].pszProtSeq))
  99. continue;
  100. rpcStatus = RpcStringBindingCompose(NULL,
  101. g_BindingList[i].pszProtSeq,
  102. (LPTSTR)(LPCTSTR)strCALocation,
  103. g_BindingList[i].pszEndpoint,
  104. NULL,
  105. &szStringBinding);
  106. if(rpcStatus != RPC_S_OK)
  107. continue;
  108. rpcStatus = RpcBindingFromStringBinding(szStringBinding, &hCARPCBinding);
  109. if (szStringBinding)
  110. RpcStringFree(&szStringBinding);
  111. if (rpcStatus != RPC_S_OK)
  112. continue;
  113. rpcStatus = RpcEpResolveBinding(hCARPCBinding, ICertPassage_v0_0_c_ifspec);
  114. if (rpcStatus == RPC_S_OK)
  115. break;
  116. }
  117. if (rpcStatus != RPC_S_OK)
  118. {
  119. dwStatus = WIZ_CERT_REQUEST_STATUS_CONNECTION_FAILED;
  120. hr = E_FAIL;
  121. goto CLEANUP;
  122. }
  123. //add the attribute to the request
  124. if (pwszRequestString)
  125. {
  126. tbAttrib.cb = (wcslen(pwszRequestString) + 1) * sizeof(WCHAR);
  127. tbAttrib.pb = (BYTE *)pwszRequestString;
  128. }
  129. //submit the request
  130. tbRequest.cb = pPKCS10Blob->cbData;
  131. tbRequest.pb = pPKCS10Blob->pbData;
  132. //set the RPC connect as the SNEGO connect, which can authenticate
  133. //a machine if supported by the system
  134. //do not need to check the return value since not supported by NT4/Win9x
  135. for (i = 0; i < g_AthnListSize; i++)
  136. {
  137. pszCAPrinceName = NULL;
  138. if (g_AthnList[i].dwAuthnService != RPC_C_AUTHN_NONE)
  139. {
  140. dwErr = RpcMgmtInqServerPrincNameA(hCARPCBinding,
  141. g_AthnList[i].dwAuthnService,
  142. (PBYTE *)&pszCAPrinceName);
  143. if (dwErr == RPC_S_UNKNOWN_AUTHN_SERVICE)
  144. continue;
  145. }
  146. dwErr = RpcBindingSetAuthInfo(hCARPCBinding,
  147. pszCAPrinceName,
  148. g_AthnList[i].dwAuthnLevel,
  149. g_AthnList[i].dwAuthnService,
  150. NULL,
  151. RPC_C_AUTHZ_NONE);
  152. if (pszCAPrinceName)
  153. RpcStringFree(&pszCAPrinceName);
  154. if (dwErr == RPC_S_UNKNOWN_AUTHN_SERVICE)
  155. continue;
  156. if (dwErr != RPC_S_OK)
  157. break;
  158. //determine the format flag
  159. DWORD dwFlags = CR_IN_BINARY | bRenew ? CR_IN_PKCS7 : CR_IN_PKCS10;
  160. DWORD dwRequestId = 0;
  161. __try
  162. {
  163. dwErr = CertServerRequest(
  164. hCARPCBinding,
  165. dwFlags,
  166. strCAName,
  167. &dwRequestId,
  168. &dwDisposition,
  169. &tbAttrib,
  170. &tbRequest,
  171. &tbCertChain,
  172. &tbCert,
  173. &tbDispositionMessage);
  174. }
  175. __except(dwErr = GetExceptionCode(), EXCEPTION_EXECUTE_HANDLER)
  176. {
  177. }
  178. if (dwErr != RPC_S_UNKNOWN_AUTHN_SERVICE)
  179. break;
  180. }
  181. if ( dwErr == RPC_S_UNKNOWN_AUTHN_SERVICE
  182. || dwErr == RPC_S_SERVER_UNAVAILABLE
  183. || dwErr == RPC_S_SERVER_TOO_BUSY
  184. )
  185. {
  186. // We tried all of our auth services, but just couldn't connect
  187. dwStatus = WIZ_CERT_REQUEST_STATUS_CONNECTION_FAILED;
  188. hr = E_FAIL;
  189. goto CLEANUP;
  190. }
  191. //get the return code
  192. hr = HRESULT_FROM_WIN32(dwErr);
  193. //we want to detect the case when hr is S_OK and the
  194. //request is denied. In this case, dwDispotion
  195. //is the REAL hresult code.
  196. if (hr == S_OK)
  197. {
  198. if(FAILED(dwDisposition))
  199. {
  200. hr = dwDisposition;
  201. dwDisposition = CR_DISP_DENIED;
  202. }
  203. }
  204. else
  205. {
  206. dwDisposition=CR_DISP_ERROR;
  207. }
  208. //map the dwDisposition
  209. switch (dwDisposition)
  210. {
  211. case CR_DISP_DENIED:
  212. dwStatus = WIZ_CERT_REQUEST_STATUS_REQUEST_DENIED;
  213. if (!FAILED(hr))
  214. hr = E_FAIL;
  215. break;
  216. case CR_DISP_ISSUED:
  217. dwStatus = WIZ_CERT_REQUEST_STATUS_CERT_ISSUED;
  218. break;
  219. case CR_DISP_ISSUED_OUT_OF_BAND:
  220. dwStatus = WIZ_CERT_REQUEST_STATUS_ISSUED_SEPARATELY;
  221. break;
  222. case CR_DISP_UNDER_SUBMISSION:
  223. dwStatus = WIZ_CERT_REQUEST_STATUS_UNDER_SUBMISSION;
  224. break;
  225. //we should never get CR_DISP_INCOMPLETE or CR_DISP_REVOKED
  226. //case CR_DISP_INCOMPLETE:
  227. //case CR_DISP_REVOKED:
  228. case CR_DISP_ERROR:
  229. default:
  230. dwStatus = WIZ_CERT_REQUEST_STATUS_REQUEST_ERROR;
  231. if (!FAILED(hr))
  232. hr=E_FAIL;
  233. break;
  234. }
  235. if (hr != S_OK)
  236. goto CLEANUP;
  237. //copy the PKCS7 blob
  238. pPKCS7Blob->cbData = tbCertChain.cb;
  239. pPKCS7Blob->pbData = new BYTE[tbCertChain.cb];
  240. if (NULL == pPKCS7Blob->pbData)
  241. {
  242. hr = E_OUTOFMEMORY;
  243. dwStatus = WIZ_CERT_REQUEST_STATUS_INSTALL_FAILED;
  244. goto CLEANUP;
  245. }
  246. memcpy(pPKCS7Blob->pbData,tbCertChain.pb,tbCertChain.cb);
  247. hr = S_OK;
  248. CLEANUP:
  249. if (pdwStatus)
  250. *pdwStatus = dwStatus;
  251. if (tbCert.pb)
  252. CoTaskMemFree(tbCert.pb);
  253. if (tbCertChain.pb)
  254. CoTaskMemFree(tbCertChain.pb);
  255. if (tbDispositionMessage.pb)
  256. CoTaskMemFree(tbDispositionMessage.pb);
  257. if (hCARPCBinding)
  258. RpcBindingFree(&hCARPCBinding);
  259. return hr;
  260. }
  261. #endif