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.

532 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. creden.cxx
  5. Abstract:
  6. This module abstracts user credentials for the multiple credential support.
  7. Author:
  8. Krishna Ganugapati (KrishnaG) 03-Aug-1996
  9. Revision History:
  10. --*/
  11. extern "C" {
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <imagehlp.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include "memory.h"
  20. }
  21. #include <basetyps.h>
  22. #include <des.h>
  23. #include <crypt.h>
  24. typedef long HRESULT;
  25. #include "misc.hxx"
  26. #include "creden.hxx"
  27. #include "macro.h"
  28. //
  29. // This routine allocates and stores the password in the
  30. // passed in pointer. The assumption here is that pszString
  31. // is valid, it can be an empty string but not NULL.
  32. // Note that this code cannot be used as is on Win2k and below
  33. // as they do not support the newer functions.
  34. //
  35. HRESULT
  36. EncryptString(
  37. LPWSTR pszString,
  38. LPWSTR *ppszSafeString,
  39. PDWORD pdwLen
  40. )
  41. {
  42. HRESULT hr = S_OK;
  43. DWORD dwLenStr = 0;
  44. DWORD dwPwdLen = 0;
  45. LPWSTR pszTempStr = NULL;
  46. NTSTATUS errStatus = STATUS_SUCCESS;
  47. *ppszSafeString = NULL;
  48. *pdwLen = 0;
  49. //
  50. // If the string is valid, then we need to get the length
  51. // and initialize the unicode string.
  52. //
  53. if (pszString) {
  54. UNICODE_STRING Password;
  55. //
  56. // Determine the length of buffer taking padding into account.
  57. //
  58. dwLenStr = wcslen(pszString);
  59. dwPwdLen = (dwLenStr + 1) * sizeof(WCHAR) + (DES_BLOCKLEN -1);
  60. pszTempStr = (LPWSTR) AllocADsMem(dwPwdLen);
  61. if (!pszTempStr) {
  62. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  63. }
  64. wcscpy(pszTempStr, pszString);
  65. RtlInitUnicodeString(&Password, pszTempStr);
  66. USHORT usExtra = 0;
  67. if (usExtra = (Password.MaximumLength % DES_BLOCKLEN)) {
  68. Password.MaximumLength += (DES_BLOCKLEN - usExtra);
  69. }
  70. errStatus = RtlEncryptMemory(
  71. Password.Buffer,
  72. Password.MaximumLength,
  73. 0
  74. );
  75. if (errStatus != STATUS_SUCCESS) {
  76. BAIL_ON_FAILURE(hr = HRESULT_FROM_NT(errStatus));
  77. }
  78. *pdwLen = Password.MaximumLength;
  79. *ppszSafeString = pszTempStr;
  80. }
  81. error:
  82. if (FAILED(hr) && pszTempStr) {
  83. FreeADsMem(pszTempStr);
  84. }
  85. RRETURN(hr);
  86. }
  87. HRESULT
  88. DecryptString(
  89. LPWSTR pszEncodedString,
  90. LPWSTR *ppszString,
  91. DWORD dwLen
  92. )
  93. {
  94. HRESULT hr = S_OK;
  95. LPWSTR pszTempStr = NULL;
  96. UNICODE_STRING Password;
  97. NTSTATUS errStatus;
  98. if (!dwLen || !ppszString) {
  99. RRETURN(E_FAIL);
  100. }
  101. *ppszString = NULL;
  102. if (dwLen) {
  103. pszTempStr = (LPWSTR) AllocADsMem(dwLen);
  104. if (!pszTempStr) {
  105. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  106. }
  107. memcpy(pszTempStr, pszEncodedString, dwLen);
  108. errStatus = RtlDecryptMemory(pszTempStr, dwLen, 0);
  109. if (errStatus != STATUS_SUCCESS) {
  110. BAIL_ON_FAILURE(hr = HRESULT_FROM_NT(errStatus));
  111. }
  112. *ppszString = pszTempStr;
  113. }
  114. error:
  115. if (FAILED(hr)) {
  116. FreeADsStr(pszTempStr);
  117. }
  118. RRETURN(hr);
  119. }
  120. //
  121. // Static member of the class
  122. //
  123. CCredentials::CCredentials():
  124. _lpszUserName(NULL),
  125. _lpszPassword(NULL),
  126. _dwAuthFlags(0),
  127. _dwPasswordLen(0)
  128. {
  129. }
  130. CCredentials::CCredentials(
  131. LPWSTR lpszUserName,
  132. LPWSTR lpszPassword,
  133. DWORD dwAuthFlags
  134. ):
  135. _lpszUserName(NULL),
  136. _lpszPassword(NULL),
  137. _dwAuthFlags(0),
  138. _dwPasswordLen(0)
  139. {
  140. //
  141. // AjayR 10-04-99 we need a way to bail if the
  142. // alloc's fail. Since it is in the constructor this is
  143. // not very easy to do.
  144. //
  145. if (lpszUserName) {
  146. _lpszUserName = AllocADsStr(lpszUserName);
  147. }
  148. else {
  149. _lpszUserName = NULL;
  150. }
  151. if (lpszPassword) {
  152. //
  153. // The call can fail but we cannot recover from this.
  154. //
  155. EncryptString(
  156. lpszPassword,
  157. &_lpszPassword,
  158. &_dwPasswordLen
  159. );
  160. }else {
  161. _lpszPassword = NULL;
  162. }
  163. _dwAuthFlags = dwAuthFlags;
  164. }
  165. CCredentials::~CCredentials()
  166. {
  167. if (_lpszUserName) {
  168. FreeADsStr(_lpszUserName);
  169. }
  170. if (_lpszPassword) {
  171. FreeADsStr(_lpszPassword);
  172. }
  173. }
  174. HRESULT
  175. CCredentials::GetUserName(
  176. LPWSTR *lppszUserName
  177. )
  178. {
  179. if (!lppszUserName) {
  180. RRETURN(E_FAIL);
  181. }
  182. if (!_lpszUserName) {
  183. *lppszUserName = NULL;
  184. }else {
  185. *lppszUserName = AllocADsStr(_lpszUserName);
  186. if (!*lppszUserName) {
  187. RRETURN(E_OUTOFMEMORY);
  188. }
  189. }
  190. RRETURN(S_OK);
  191. }
  192. HRESULT
  193. CCredentials::GetPassword(
  194. LPWSTR * lppszPassword
  195. )
  196. {
  197. UNICODE_STRING Password;
  198. LPWSTR lpTempPassword = NULL;
  199. Password.Length = 0;
  200. if (!lppszPassword) {
  201. RRETURN(E_FAIL);
  202. }
  203. if (!_lpszPassword) {
  204. *lppszPassword = NULL;
  205. }else {
  206. RRETURN(
  207. DecryptString(
  208. _lpszPassword,
  209. lppszPassword,
  210. _dwPasswordLen
  211. )
  212. );
  213. }
  214. RRETURN(S_OK);
  215. }
  216. HRESULT
  217. CCredentials::SetUserName(
  218. LPWSTR lpszUserName
  219. )
  220. {
  221. if (_lpszUserName) {
  222. FreeADsStr(_lpszUserName);
  223. }
  224. if (!lpszUserName) {
  225. _lpszUserName = NULL;
  226. RRETURN(S_OK);
  227. }
  228. _lpszUserName = AllocADsStr(
  229. lpszUserName
  230. );
  231. if(!_lpszUserName) {
  232. RRETURN(E_FAIL);
  233. }
  234. RRETURN(S_OK);
  235. }
  236. HRESULT
  237. CCredentials::SetPassword(
  238. LPWSTR lpszPassword
  239. )
  240. {
  241. if (_lpszPassword) {
  242. FreeADsStr(_lpszPassword);
  243. }
  244. if (!lpszPassword) {
  245. _lpszPassword = NULL;
  246. RRETURN(S_OK);
  247. }
  248. RRETURN(
  249. EncryptString(
  250. lpszPassword,
  251. &_lpszPassword,
  252. &_dwPasswordLen
  253. )
  254. );
  255. }
  256. CCredentials::CCredentials(
  257. const CCredentials& Credentials
  258. )
  259. {
  260. HRESULT hr = S_OK;
  261. LPWSTR pszTmpPwd = NULL;
  262. _lpszUserName = NULL;
  263. _lpszPassword = NULL;
  264. _lpszUserName = AllocADsStr(
  265. Credentials._lpszUserName
  266. );
  267. if (Credentials._lpszPassword) {
  268. hr = DecryptString(
  269. Credentials._lpszPassword,
  270. &pszTmpPwd,
  271. Credentials._dwPasswordLen
  272. );
  273. }
  274. if (SUCCEEDED(hr) && pszTmpPwd) {
  275. hr = EncryptString(
  276. pszTmpPwd,
  277. &_lpszPassword,
  278. &_dwPasswordLen
  279. );
  280. }
  281. if (pszTmpPwd) {
  282. FreeADsStr(pszTmpPwd);
  283. }
  284. _dwAuthFlags = Credentials._dwAuthFlags;
  285. }
  286. void
  287. CCredentials::operator=(
  288. const CCredentials& other
  289. )
  290. {
  291. HRESULT hr = S_OK;
  292. LPWSTR pszTmpPwd = NULL;
  293. if ( &other == this) {
  294. return;
  295. }
  296. if (_lpszUserName) {
  297. FreeADsStr(_lpszUserName);
  298. }
  299. if (_lpszPassword) {
  300. FreeADsStr(_lpszPassword);
  301. }
  302. _lpszUserName = AllocADsStr(
  303. other._lpszUserName
  304. );
  305. if (other._lpszPassword) {
  306. hr = DecryptString(
  307. other._lpszPassword,
  308. &pszTmpPwd,
  309. other._dwPasswordLen
  310. );
  311. }
  312. if (SUCCEEDED(hr) && pszTmpPwd) {
  313. hr = EncryptString(
  314. pszTmpPwd,
  315. &_lpszPassword,
  316. &_dwPasswordLen
  317. );
  318. }
  319. if (pszTmpPwd) {
  320. FreeADsStr(pszTmpPwd);
  321. }
  322. _dwAuthFlags = other._dwAuthFlags;
  323. return;
  324. }
  325. BOOL
  326. operator==(
  327. CCredentials& x,
  328. CCredentials& y
  329. )
  330. {
  331. BOOL bEqualUser = FALSE;
  332. BOOL bEqualPassword = FALSE;
  333. BOOL bEqualFlags = FALSE;
  334. LPWSTR lpszXPassword = NULL;
  335. LPWSTR lpszYPassword = NULL;
  336. BOOL bReturnCode = FALSE;
  337. HRESULT hr = S_OK;
  338. if (x._lpszUserName && y._lpszUserName) {
  339. bEqualUser = !(wcscmp(x._lpszUserName, y._lpszUserName));
  340. }else if (!x._lpszUserName && !y._lpszUserName){
  341. bEqualUser = TRUE;
  342. }
  343. hr = x.GetPassword(&lpszXPassword);
  344. if (FAILED(hr)) {
  345. goto error;
  346. }
  347. hr = y.GetPassword(&lpszYPassword);
  348. if (FAILED(hr)) {
  349. goto error;
  350. }
  351. if ((lpszXPassword && lpszYPassword)) {
  352. bEqualPassword = !(wcscmp(lpszXPassword, lpszYPassword));
  353. }else if (!lpszXPassword && !lpszYPassword) {
  354. bEqualPassword = TRUE;
  355. }
  356. if (x._dwAuthFlags == y._dwAuthFlags) {
  357. bEqualFlags = TRUE;
  358. }
  359. if (bEqualUser && bEqualPassword && bEqualFlags) {
  360. bReturnCode = TRUE;
  361. }
  362. error:
  363. if (lpszXPassword) {
  364. FreeADsStr(lpszXPassword);
  365. }
  366. if (lpszYPassword) {
  367. FreeADsStr(lpszYPassword);
  368. }
  369. return(bReturnCode);
  370. }
  371. BOOL
  372. CCredentials::IsNullCredentials(
  373. )
  374. {
  375. // The function will return true even if the flags are set
  376. // this is because we want to try and get the default credentials
  377. // even if the flags were set
  378. if (!_lpszUserName && !_lpszPassword) {
  379. return(TRUE);
  380. }else {
  381. return(FALSE);
  382. }
  383. }
  384. DWORD
  385. CCredentials::GetAuthFlags()
  386. {
  387. return(_dwAuthFlags);
  388. }
  389. void
  390. CCredentials::SetAuthFlags(
  391. DWORD dwAuthFlags
  392. )
  393. {
  394. _dwAuthFlags = dwAuthFlags;
  395. }