Leaked source code of windows server 2003
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.

927 lines
28 KiB

  1. /*
  2. File: Passwd.cpp
  3. Title: Protected Storage User Confirm wrappers
  4. Author: Matt Thomlinson
  5. Date: 2/25/97
  6. Passwd.cpp simply houses a few of the password-management
  7. functions. These functions are called on to return the
  8. user-confirmation derived buffer, and check synchronization
  9. in certain cases.
  10. As the Authentication provider interface gets defined, this
  11. could end up getting moved into a seperate provider.
  12. */
  13. #include <pch.cpp>
  14. #pragma hdrstop
  15. #include "provui.h"
  16. #include "storage.h"
  17. #include "passwd.h"
  18. extern DISPIF_CALLBACKS g_sCallbacks;
  19. extern PRIVATE_CALLBACKS g_sPrivateCallbacks;
  20. extern CUAList* g_pCUAList;
  21. ///////////////////////////////////////////////////////////////////////
  22. // non-user editable passwords
  23. BOOL FIsUserMasterKey(LPCWSTR szMasterKey)
  24. {
  25. if (0 == wcscmp(szMasterKey, WSZ_PASSWORD_WINDOWS))
  26. return FALSE;
  27. return TRUE;
  28. }
  29. BOOL FMyGetWinPassword(
  30. PST_PROVIDER_HANDLE* phPSTProv,
  31. LPCWSTR szUser,
  32. BYTE rgbPwd[A_SHA_DIGEST_LEN] )
  33. {
  34. // nab pwd
  35. if (0 == wcscmp(szUser, WSZ_LOCAL_MACHINE))
  36. {
  37. CopyMemory(rgbPwd, RGB_LOCALMACHINE_KEY, A_SHA_DIGEST_LEN);
  38. }
  39. else
  40. {
  41. /*
  42. if (! g_sPrivateCallbacks.pfnFGetWindowsPassword(
  43. phPSTProv,
  44. rgbPwd,
  45. A_SHA_DIGEST_LEN))
  46. return FALSE;
  47. */
  48. A_SHA_CTX context;
  49. DWORD cb = lstrlenW(szUser) * sizeof(WCHAR);
  50. BYTE Magic1[] = {0x66, 0x41, 0xa3, 0x29};
  51. BYTE Magic2[] = {0x14, 0x9a, 0xef, 0x82};
  52. A_SHAInit(&context);
  53. // note: the three Update calls get buffered up internally to
  54. // multiples of 64 bytes.
  55. //
  56. A_SHAUpdate(&context, Magic1, sizeof(Magic1));
  57. A_SHAUpdate(&context, (LPBYTE)szUser, cb);
  58. A_SHAUpdate(&context, Magic2, (cb+sizeof(Magic2)) % sizeof(Magic2));
  59. A_SHAFinal(&context, rgbPwd);
  60. }
  61. return TRUE;
  62. }
  63. // Base Provider specific fxn: check the password
  64. DWORD BPVerifyPwd(
  65. PST_PROVIDER_HANDLE* phPSTProv,
  66. LPCWSTR szUser,
  67. LPCWSTR szMasterKey,
  68. BYTE rgbPwd[],
  69. DWORD dwPasswordOption)
  70. {
  71. DWORD dwRet = (DWORD)PST_E_WRONG_PASSWORD;
  72. if (dwPasswordOption != BP_CONFIRM_PASSWORDUI)
  73. {
  74. // only non-user keys can be silent (WinPWs only, to be exact)
  75. if (FIsUserMasterKey(szMasterKey))
  76. goto Ret;
  77. // get the Windows pwd
  78. if (!FMyGetWinPassword(phPSTProv, szUser, rgbPwd))
  79. goto Ret;
  80. // check
  81. if (!FCheckPWConfirm(
  82. szUser,
  83. szMasterKey,
  84. rgbPwd))
  85. {
  86. dwRet = (DWORD)PST_E_WRONG_PASSWORD;
  87. goto Ret;
  88. }
  89. }
  90. else // UI wanted
  91. {
  92. // is it the windows password?
  93. if (0 == wcscmp(szMasterKey, WSZ_PASSWORD_WINDOWS))
  94. {
  95. BYTE rgbWinPwd[A_SHA_DIGEST_LEN];
  96. // we need to keep user, WinPW in sync
  97. if(!FMyGetWinPassword(
  98. phPSTProv,
  99. szUser,
  100. rgbWinPwd
  101. ))
  102. {
  103. dwRet = (DWORD)PST_E_WRONG_PASSWORD;
  104. goto Ret;
  105. }
  106. if (0 != memcmp(rgbWinPwd, rgbPwd, sizeof(rgbWinPwd) ))
  107. {
  108. // no match: user entered old password?
  109. if (FCheckPWConfirm(
  110. szUser,
  111. szMasterKey,
  112. rgbPwd))
  113. {
  114. // err: user entered neither old nor new password
  115. dwRet = (DWORD)PST_E_WRONG_PASSWORD;
  116. goto Ret;
  117. }
  118. }
  119. else
  120. {
  121. // matched: user entered password we consider good
  122. if (!FCheckPWConfirm(
  123. szUser,
  124. szMasterKey,
  125. rgbPwd))
  126. {
  127. dwRet = (DWORD)PST_E_WRONG_PASSWORD;
  128. goto Ret;
  129. }
  130. }
  131. }
  132. else
  133. {
  134. // else: not win pw, just do pw correctness check
  135. if (!FCheckPWConfirm(
  136. szUser,
  137. szMasterKey,
  138. rgbPwd))
  139. {
  140. dwRet = (DWORD)PST_E_WRONG_PASSWORD;
  141. goto Ret;
  142. }
  143. }
  144. }
  145. dwRet = (DWORD)PST_E_OK;
  146. Ret:
  147. return dwRet;
  148. }
  149. HRESULT GetUserConfirmDefaults(
  150. PST_PROVIDER_HANDLE* phPSTProv,
  151. DWORD* pdwDefaultConfirmationStyle,
  152. LPWSTR* ppszMasterKey)
  153. {
  154. SS_ASSERT(ppszMasterKey != NULL);
  155. SS_ASSERT(pdwDefaultConfirmationStyle != NULL);
  156. PBYTE pbData = NULL;
  157. DWORD cbData;
  158. HRESULT hr = PST_E_FAIL;
  159. // if not found, restore the machine defaults
  160. // alloc sizeof string + dword
  161. cbData = sizeof(WSZ_PASSWORD_WINDOWS) + sizeof(DWORD);
  162. pbData = (PBYTE)SSAlloc(cbData);
  163. if(pbData == NULL)
  164. return PST_E_FAIL;
  165. // copy string, DWORD confirmation type
  166. *(DWORD*)pbData = BP_CONFIRM_OKCANCEL;
  167. CopyMemory(pbData+sizeof(DWORD), WSZ_PASSWORD_WINDOWS, sizeof(WSZ_PASSWORD_WINDOWS));
  168. // format: confirmation style DWORD, sz
  169. *pdwDefaultConfirmationStyle = *(DWORD*)pbData;
  170. *ppszMasterKey = (LPWSTR)SSAlloc(WSZ_BYTECOUNT((LPWSTR)(pbData+sizeof(DWORD))));
  171. if(*ppszMasterKey != NULL) {
  172. wcscpy(*ppszMasterKey, (LPWSTR) (pbData+sizeof(DWORD)) );
  173. hr = PST_E_OK;
  174. }
  175. // free what ConfigData returned
  176. if (pbData)
  177. SSFree(pbData);
  178. return hr;
  179. }
  180. void NotifyOfWrongPassword(
  181. HWND hwnd,
  182. LPCWSTR szItemName,
  183. LPCWSTR szPasswordName)
  184. {
  185. LPWSTR szMessage;
  186. if (0 == wcscmp(szPasswordName, WSZ_PASSWORD_WINDOWS))
  187. szMessage = g_PasswordWinNoVerify;
  188. else
  189. szMessage = g_PasswordNoVerify; // error doesn't deal with win pw
  190. MessageBoxW(hwnd, szMessage, szItemName, MB_OK | MB_SERVICE_NOTIFICATION);
  191. }
  192. // #define to force an unreadable confirmation to bail from read proc
  193. #define PST_CF_STORED_ONLY 0xcf000001
  194. HRESULT GetUserConfirmBuf(
  195. PST_PROVIDER_HANDLE* phPSTProv,
  196. LPCWSTR szUser,
  197. PST_KEY Key,
  198. LPCWSTR szType,
  199. const GUID* pguidType,
  200. LPCWSTR szSubtype,
  201. const GUID* pguidSubtype,
  202. LPCWSTR szItemName,
  203. PPST_PROMPTINFO psPrompt,
  204. LPCWSTR szAction,
  205. LPWSTR* ppszMasterKey,
  206. BYTE rgbPwd[A_SHA_DIGEST_LEN],
  207. DWORD dwFlags)
  208. {
  209. return GetUserConfirmBuf(
  210. phPSTProv,
  211. szUser,
  212. Key,
  213. szType,
  214. pguidType,
  215. szSubtype,
  216. pguidSubtype,
  217. szItemName,
  218. psPrompt,
  219. szAction,
  220. PST_CF_STORED_ONLY, // hardcoded: must be able to retreive in order to show ui
  221. ppszMasterKey,
  222. rgbPwd,
  223. dwFlags);
  224. }
  225. #define MAX_PASSWD_TRIALS 3
  226. HRESULT GetUserConfirmBuf(
  227. PST_PROVIDER_HANDLE* phPSTProv,
  228. LPCWSTR szUser,
  229. PST_KEY Key,
  230. LPCWSTR szType,
  231. const GUID* pguidType,
  232. LPCWSTR szSubtype,
  233. const GUID* pguidSubtype,
  234. LPCWSTR szItemName,
  235. PPST_PROMPTINFO psPrompt,
  236. LPCWSTR szAction,
  237. DWORD dwDefaultConfirmationStyle,
  238. LPWSTR* ppszMasterKey,
  239. BYTE rgbOutPwd[A_SHA_DIGEST_LEN],
  240. DWORD dwFlags)
  241. {
  242. HRESULT hr;
  243. DWORD dwStoredConfirm, dwChosenConfirm;
  244. LPWSTR szCallerName = NULL;
  245. BOOL fPromptedUser = FALSE;
  246. BOOL fIsCached = FALSE;
  247. BOOL fCacheItNow = FALSE;
  248. BOOL fPwdVerified = FALSE;
  249. SS_ASSERT(*ppszMasterKey == NULL); // don't whack existing memory
  250. if (Key == PST_KEY_LOCAL_MACHINE)
  251. {
  252. // short-circuit password gathering, setting
  253. *ppszMasterKey = (LPWSTR) SSAlloc(sizeof(WSZ_PASSWORD_WINDOWS));
  254. if( *ppszMasterKey == NULL )
  255. {
  256. hr = PST_E_FAIL;
  257. goto Ret;
  258. }
  259. wcscpy(*ppszMasterKey, WSZ_PASSWORD_WINDOWS);
  260. CopyMemory(rgbOutPwd, RGB_LOCALMACHINE_KEY, A_SHA_DIGEST_LEN);
  261. // done
  262. hr = PST_E_OK;
  263. goto Ret;
  264. }
  265. if (!g_sCallbacks.pfnFGetCallerName(phPSTProv, &szCallerName, NULL)) {
  266. hr = PST_E_FAIL;
  267. goto Ret;
  268. }
  269. // Which is this: item creation, item access?
  270. // item access does user authentication
  271. SS_ASSERT(szItemName != NULL);
  272. // per-item key
  273. if (PST_E_OK != (hr =
  274. BPGetItemConfirm(
  275. phPSTProv,
  276. szUser,
  277. pguidType,
  278. pguidSubtype,
  279. szItemName,
  280. &dwStoredConfirm,
  281. ppszMasterKey)) )
  282. {
  283. // this could be a failure in
  284. // * confirmation: tampering detected!!
  285. // * password: couldn't grab user pwd
  286. if (dwDefaultConfirmationStyle == PST_CF_STORED_ONLY)
  287. goto Ret;
  288. //
  289. // if UI is not allowed (eg, Local System account), over-ride
  290. // confirmation style.
  291. //
  292. if (dwDefaultConfirmationStyle != PST_CF_NONE)
  293. {
  294. if(!FIsProviderUIAllowed( szUser ))
  295. dwDefaultConfirmationStyle = PST_CF_NONE;
  296. }
  297. // if app asked to have no confirm, set item that way
  298. if (dwDefaultConfirmationStyle == PST_CF_NONE)
  299. {
  300. dwChosenConfirm = BP_CONFIRM_NONE;
  301. // short-circuit password gathering, setting
  302. *ppszMasterKey = (LPWSTR) SSAlloc(sizeof(WSZ_PASSWORD_WINDOWS));
  303. if(*ppszMasterKey == NULL)
  304. {
  305. hr = PST_E_FAIL;
  306. goto Ret;
  307. }
  308. wcscpy(*ppszMasterKey, WSZ_PASSWORD_WINDOWS);
  309. }
  310. else // app allows user to decide
  311. {
  312. // get user default
  313. if (PST_E_OK != (hr = GetUserConfirmDefaults(
  314. phPSTProv,
  315. &dwChosenConfirm,
  316. ppszMasterKey)) )
  317. goto Ret;
  318. }
  319. // if user default is silent, don't bother user
  320. switch(dwChosenConfirm)
  321. {
  322. // if no confirm
  323. case BP_CONFIRM_NONE:
  324. break;
  325. // if we know the confirm type
  326. case BP_CONFIRM_PASSWORDUI:
  327. {
  328. // make sure we're not asking the user for a password he can't satisfy
  329. if (!FIsUserMasterKey(*ppszMasterKey))
  330. {
  331. hr = PST_E_NO_PERMISSIONS;
  332. goto Ret;
  333. }
  334. // else fall through to prompting case
  335. }
  336. case BP_CONFIRM_OKCANCEL:
  337. {
  338. int i;
  339. fPromptedUser = TRUE;
  340. for(i=1; ; i++)
  341. {
  342. BYTE rgbOutPwdLowerCase[A_SHA_DIGEST_LEN];
  343. // Request the user apply a new password
  344. if (!FSimplifiedPasswordConfirm(
  345. phPSTProv,
  346. szUser,
  347. szCallerName,
  348. szType,
  349. szSubtype,
  350. szItemName,
  351. psPrompt,
  352. szAction,
  353. ppszMasterKey,
  354. &dwChosenConfirm,
  355. TRUE, // user select which pwd
  356. rgbOutPwd,
  357. A_SHA_DIGEST_LEN,
  358. rgbOutPwdLowerCase,
  359. A_SHA_DIGEST_LEN,
  360. dwFlags
  361. ))
  362. {
  363. hr = PST_E_NO_PERMISSIONS;
  364. goto Ret;
  365. }
  366. // verify whatever password we got
  367. if (PST_E_OK != (hr =
  368. BPVerifyPwd(
  369. phPSTProv,
  370. szUser,
  371. *ppszMasterKey,
  372. rgbOutPwd,
  373. dwChosenConfirm)) )
  374. {
  375. //
  376. // try lower-case form to handle Win9x migration case.
  377. //
  378. if (PST_E_OK != (hr =
  379. BPVerifyPwd(
  380. phPSTProv,
  381. szUser,
  382. *ppszMasterKey,
  383. rgbOutPwdLowerCase,
  384. dwChosenConfirm)) )
  385. {
  386. // too many trials? break out of loop
  387. if (i < MAX_PASSWD_TRIALS)
  388. {
  389. // notify user, give them another chance
  390. NotifyOfWrongPassword((HWND)psPrompt->hwndApp, szItemName, *ppszMasterKey);
  391. continue;
  392. } else {
  393. break; // break out
  394. }
  395. } else {
  396. CopyMemory( rgbOutPwd, rgbOutPwdLowerCase, A_SHA_DIGEST_LEN );
  397. }
  398. }
  399. // passed verify password test: break out of loop!
  400. fPwdVerified = TRUE;
  401. break;
  402. }
  403. if (!fPwdVerified)
  404. {
  405. hr = PST_E_NO_PERMISSIONS;
  406. goto Ret;
  407. }
  408. }
  409. }
  410. // and remember the selections made
  411. if (PST_E_OK != (hr =
  412. BPSetItemConfirm(
  413. phPSTProv,
  414. szUser,
  415. pguidType,
  416. pguidSubtype,
  417. szItemName,
  418. dwChosenConfirm,
  419. *ppszMasterKey)) )
  420. goto Ret;
  421. // now, _this_ is the stored confirm
  422. dwStoredConfirm = dwChosenConfirm;
  423. }
  424. else
  425. {
  426. // keep a copy of the stored key
  427. LPWSTR szStoredMasterKey = (LPWSTR)SSAlloc(WSZ_BYTECOUNT(*ppszMasterKey));
  428. if(NULL != szStoredMasterKey)
  429. {
  430. CopyMemory(szStoredMasterKey, *ppszMasterKey, WSZ_BYTECOUNT(*ppszMasterKey));
  431. }
  432. // we retrieved confirmation behavior
  433. dwChosenConfirm = dwStoredConfirm; // already chosen for you
  434. switch (dwStoredConfirm)
  435. {
  436. // if no confirm
  437. case BP_CONFIRM_NONE:
  438. break;
  439. // if we know the confirm type
  440. case BP_CONFIRM_PASSWORDUI:
  441. {
  442. // else fall through to prompting case
  443. }
  444. case BP_CONFIRM_OKCANCEL:
  445. {
  446. // retrieved item, must show ui, but not allowed to show ui
  447. if (psPrompt->dwPromptFlags & PST_PF_NEVER_SHOW)
  448. {
  449. hr = ERROR_PASSWORD_RESTRICTION;
  450. goto Ret;
  451. }
  452. // found that a pwd is req'd
  453. fPromptedUser = TRUE;
  454. fCacheItNow = fIsCached;
  455. int i;
  456. for(i=1; ; i++)
  457. {
  458. BYTE rgbOutPwdLowerCase[A_SHA_DIGEST_LEN];
  459. // ask the user for it
  460. if (!FSimplifiedPasswordConfirm(
  461. phPSTProv,
  462. szUser,
  463. szCallerName,
  464. szType,
  465. szSubtype,
  466. szItemName,
  467. psPrompt,
  468. szAction,
  469. ppszMasterKey,
  470. &dwChosenConfirm,
  471. TRUE, // allow user to select pwd
  472. rgbOutPwd,
  473. A_SHA_DIGEST_LEN,
  474. rgbOutPwdLowerCase,
  475. A_SHA_DIGEST_LEN,
  476. dwFlags
  477. ))
  478. {
  479. hr = PST_E_NO_PERMISSIONS;
  480. goto Ret;
  481. }
  482. // if we got it from the cache and user left it alone
  483. {
  484. // verify whatever password we got
  485. if (PST_E_OK != (hr =
  486. BPVerifyPwd(
  487. phPSTProv,
  488. szUser,
  489. *ppszMasterKey,
  490. rgbOutPwd,
  491. dwChosenConfirm)) )
  492. {
  493. //
  494. // check lower case form.
  495. //
  496. if (PST_E_OK != (hr =
  497. BPVerifyPwd(
  498. phPSTProv,
  499. szUser,
  500. *ppszMasterKey,
  501. rgbOutPwdLowerCase,
  502. dwChosenConfirm)) )
  503. {
  504. // too many trials? break out of loop
  505. if (i < MAX_PASSWD_TRIALS)
  506. {
  507. // notify user, give them another chance
  508. NotifyOfWrongPassword((HWND)psPrompt->hwndApp, szItemName, *ppszMasterKey);
  509. continue;
  510. }
  511. else
  512. {
  513. hr = PST_E_NO_PERMISSIONS;
  514. goto Ret;
  515. }
  516. } else {
  517. CopyMemory( rgbOutPwd, rgbOutPwdLowerCase, A_SHA_DIGEST_LEN );
  518. }
  519. }
  520. fPwdVerified = TRUE;
  521. }
  522. // passed verify password test: break out of loop!
  523. break;
  524. }
  525. break;
  526. }
  527. } // end switch
  528. // have we received all data we need from the user?
  529. // user may choose to change the way items are encrypted;
  530. // if stored under password, we must make them enter the old pwd
  531. if ((dwStoredConfirm != dwChosenConfirm) || // confirm type changed OR
  532. (NULL == szStoredMasterKey) ||
  533. (0 != wcscmp(*ppszMasterKey, szStoredMasterKey)) ) // difft master key
  534. {
  535. BYTE rgbOldPwd[A_SHA_DIGEST_LEN];
  536. BOOL fDontAllowCache = FALSE;
  537. BOOL fOldPwdVerified = FALSE;
  538. PST_PROMPTINFO sGetOldPWPrompt = {sizeof(PST_PROMPTINFO), psPrompt->dwPromptFlags, psPrompt->hwndApp, g_PasswordSolicitOld};
  539. // only re-display if originally passworded
  540. if (dwStoredConfirm == BP_CONFIRM_PASSWORDUI)
  541. {
  542. for(int i=1; ; i++)
  543. {
  544. BYTE rgbOldPwdLowerCase[A_SHA_DIGEST_LEN];
  545. // ask the user for it
  546. if (!FSimplifiedPasswordConfirm(
  547. phPSTProv,
  548. szUser,
  549. szCallerName,
  550. szType,
  551. szSubtype,
  552. szItemName,
  553. &sGetOldPWPrompt,
  554. szAction,
  555. &szStoredMasterKey,
  556. &dwStoredConfirm,
  557. FALSE, // don't allow user to get around this one
  558. rgbOldPwd,
  559. sizeof(rgbOldPwd),
  560. rgbOldPwdLowerCase,
  561. sizeof(rgbOldPwdLowerCase),
  562. dwFlags
  563. ))
  564. {
  565. hr = PST_E_NO_PERMISSIONS;
  566. goto Ret;
  567. }
  568. // verify whatever password we got
  569. if (PST_E_OK != (hr =
  570. BPVerifyPwd(
  571. phPSTProv,
  572. szUser,
  573. szStoredMasterKey,
  574. rgbOldPwd,
  575. dwStoredConfirm)) )
  576. {
  577. if (PST_E_OK != (hr =
  578. BPVerifyPwd(
  579. phPSTProv,
  580. szUser,
  581. szStoredMasterKey,
  582. rgbOldPwdLowerCase,
  583. dwStoredConfirm)) )
  584. {
  585. // too many trials? break out of loop
  586. if (i < MAX_PASSWD_TRIALS)
  587. {
  588. // notify user, give them another chance
  589. NotifyOfWrongPassword((HWND)sGetOldPWPrompt.hwndApp, szItemName, szStoredMasterKey);
  590. continue;
  591. } else {
  592. break; // break out
  593. }
  594. } else {
  595. CopyMemory( rgbOldPwd, rgbOldPwdLowerCase, A_SHA_DIGEST_LEN );
  596. }
  597. }
  598. // passed verify password test: break out of loop!
  599. fOldPwdVerified = TRUE;
  600. break;
  601. }
  602. if (!fOldPwdVerified)
  603. {
  604. hr = PST_E_NO_PERMISSIONS;
  605. goto Ret;
  606. }
  607. }
  608. else
  609. {
  610. // ok/cancel; silent pwd usage
  611. // use VerifyPwd fxn to retrieve the pwd
  612. if (PST_E_OK != (hr =
  613. BPVerifyPwd(
  614. phPSTProv,
  615. szUser,
  616. szStoredMasterKey,
  617. rgbOldPwd,
  618. dwStoredConfirm)) )
  619. {
  620. hr = PST_E_NO_PERMISSIONS;
  621. goto Ret;
  622. }
  623. }
  624. //////
  625. // execute pwd change HERE
  626. {
  627. PBYTE pbData = NULL;
  628. DWORD cbData;
  629. // FBPGetSecuredItemData // decrypt data with old
  630. if (!FBPGetSecuredItemData(
  631. szUser,
  632. szStoredMasterKey,
  633. rgbOldPwd,
  634. pguidType,
  635. pguidSubtype,
  636. szItemName,
  637. &pbData,
  638. &cbData))
  639. {
  640. hr = PST_E_STORAGE_ERROR;
  641. goto Ret;
  642. }
  643. // FBPSetSecuredItemData // encrypt data with new
  644. if (!FBPSetSecuredItemData(
  645. szUser,
  646. *ppszMasterKey,
  647. rgbOutPwd,
  648. pguidType,
  649. pguidSubtype,
  650. szItemName,
  651. pbData,
  652. cbData))
  653. {
  654. hr = PST_E_STORAGE_ERROR;
  655. goto Ret;
  656. }
  657. if (pbData)
  658. SSFree(pbData);
  659. // BPSetItemConfirm // store new confirm type
  660. if (PST_E_OK !=
  661. BPSetItemConfirm(
  662. phPSTProv,
  663. szUser,
  664. pguidType,
  665. pguidSubtype,
  666. szItemName,
  667. dwChosenConfirm,
  668. *ppszMasterKey))
  669. {
  670. hr = PST_E_STORAGE_ERROR;
  671. goto Ret;
  672. }
  673. }
  674. }
  675. if (szStoredMasterKey)
  676. {
  677. SSFree(szStoredMasterKey);
  678. szStoredMasterKey = NULL;
  679. }
  680. }
  681. // verify whatever password we got if not yet verified
  682. if (!fPwdVerified)
  683. {
  684. if (PST_E_OK != (hr =
  685. BPVerifyPwd(
  686. phPSTProv,
  687. szUser,
  688. *ppszMasterKey,
  689. rgbOutPwd,
  690. dwChosenConfirm)) )
  691. goto Ret;
  692. }
  693. // Now correct pwd is in rgbOutPwd ALWAYS
  694. // if we haven't prompted user and were supposed to
  695. if (!fPromptedUser && (psPrompt->dwPromptFlags == PST_PF_ALWAYS_SHOW))
  696. {
  697. // we must've retrieved from cache OR Automagic WinPW
  698. SS_ASSERT(fIsCached || (BP_CONFIRM_NONE == dwStoredConfirm));
  699. BYTE rgbBarfPwd[A_SHA_DIGEST_LEN*2];
  700. BYTE rgbBarfPwdLowerCase[A_SHA_DIGEST_LEN];
  701. // haven't prompted user but must confirm
  702. if (!FSimplifiedPasswordConfirm(
  703. phPSTProv,
  704. szUser,
  705. szCallerName,
  706. szType,
  707. szSubtype,
  708. szItemName,
  709. psPrompt,
  710. szAction,
  711. ppszMasterKey,
  712. &dwChosenConfirm,
  713. FALSE,
  714. rgbBarfPwd,
  715. sizeof(rgbBarfPwd),
  716. rgbBarfPwdLowerCase,
  717. sizeof(rgbBarfPwdLowerCase),
  718. dwFlags
  719. ) )
  720. {
  721. hr = PST_E_NO_PERMISSIONS;
  722. goto Ret;
  723. }
  724. }
  725. hr = PST_E_OK;
  726. Ret:
  727. if (szCallerName)
  728. SSFree(szCallerName);
  729. return hr;
  730. }
  731. HRESULT ShowOKCancelUI(
  732. PST_PROVIDER_HANDLE* phPSTProv,
  733. LPCWSTR szUser,
  734. PST_KEY Key,
  735. LPCWSTR szType,
  736. LPCWSTR szSubtype,
  737. LPCWSTR szItemName,
  738. PPST_PROMPTINFO psPrompt,
  739. LPCWSTR szAction)
  740. {
  741. BOOL fCache = FALSE;
  742. BYTE rgbTrash[A_SHA_DIGEST_LEN*2];
  743. BYTE rgbTrashLowerCase[A_SHA_DIGEST_LEN];
  744. DWORD dwConfirmOptions = BP_CONFIRM_OKCANCEL;
  745. LPWSTR szMasterKey = NULL;
  746. LPWSTR szCallerName = NULL;
  747. DWORD dwRet = PST_E_FAIL;
  748. if (Key == PST_KEY_LOCAL_MACHINE)
  749. {
  750. // done
  751. dwRet = PST_E_OK;
  752. goto Ret;
  753. }
  754. szMasterKey = (LPWSTR)SSAlloc(sizeof(WSZ_NULLSTRING));
  755. if(szMasterKey)
  756. {
  757. wcscpy(szMasterKey, WSZ_NULLSTRING);
  758. }
  759. if (!g_sCallbacks.pfnFGetCallerName(phPSTProv, &szCallerName, NULL))
  760. goto Ret;
  761. if (!FSimplifiedPasswordConfirm(
  762. phPSTProv,
  763. szUser,
  764. szCallerName,
  765. szType,
  766. szSubtype,
  767. szItemName,
  768. psPrompt,
  769. szAction,
  770. &szMasterKey,
  771. &dwConfirmOptions,
  772. FALSE,
  773. rgbTrash,
  774. sizeof(rgbTrash),
  775. rgbTrashLowerCase,
  776. sizeof(rgbTrashLowerCase),
  777. 0
  778. ) )
  779. goto Ret;
  780. dwRet = PST_E_OK;
  781. Ret:
  782. if (szCallerName)
  783. SSFree(szCallerName);
  784. if (szMasterKey)
  785. SSFree(szMasterKey);
  786. return dwRet;
  787. }