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.

1403 lines
32 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: samlock.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 4-19-97 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "samlock.h"
  18. #include <stdio.h>
  19. #include <wchar.h>
  20. #if DBG
  21. #define HIDDEN
  22. #else
  23. #define HIDDEN static
  24. #endif
  25. #define MAKE_SAM_CALLS 1
  26. #if MAKE_SAM_CALLS
  27. #define SYSTEM_KEY TEXT("SecureBoot")
  28. #else
  29. #define SYSTEM_KEY TEXT("BootType")
  30. #endif
  31. #define KEYFILE TEXT("A:\\StartKey.Key")
  32. #define KEYFILE_SAVE TEXT("A:\\StartKey.Bak")
  33. HICON hLockIcon ;
  34. HICON KeyDataPwIcon ;
  35. HICON KeyDataDiskIcon ;
  36. SAMPR_BOOT_TYPE SecureBootOption = 0;
  37. SAMPR_BOOT_TYPE OriginalBootOption = 0 ;
  38. SAM_HANDLE SamHandle ;
  39. SAM_HANDLE DomainHandle ;
  40. HKEY LsaKey ;
  41. HCURSOR hcurArrow ;
  42. HCURSOR hcurWait ;
  43. BOOL WaitCursor ;
  44. WCHAR OptionL[ 4 ]; // Unattended, local store
  45. WCHAR OptionQ[ 4 ]; // Question (usage)
  46. BOOL Unattended = FALSE ;
  47. DWORD PwSection[] = { IDD_PW_PW_TEXT, IDD_PW_PW_LABEL, IDD_PW_PASSWORD,
  48. IDD_PW_CONFIRM_LABEL, IDD_PW_CONFIRM };
  49. DWORD GenSection[]= { IDD_PW_FLOPPY, IDD_PW_STORE_LOCAL, IDD_PW_FLOPPY_TEXT,
  50. IDD_PW_LOCAL_TEXT };
  51. typedef WXHASH HASH, *PHASH;
  52. BOOL ObfuscateKey(PHASH H)
  53. {
  54. return(NT_SUCCESS(WxSaveSysKey(sizeof(H->Digest),&H->Digest)));
  55. }
  56. BOOL DeobfuscateKey(PHASH H)
  57. {
  58. ULONG KeyLen = sizeof(H->Digest);
  59. return(NT_SUCCESS(WxReadSysKey(&KeyLen,&H->Digest)));
  60. }
  61. #if MAKE_SAM_CALLS
  62. #define xSamiGetBootKeyInformation SamiGetBootKeyInformation
  63. #define xSamiSetBootKeyInformation SamiSetBootKeyInformation
  64. #else
  65. NTSTATUS
  66. xSamiGetBootKeyInformation(
  67. SAM_HANDLE Domain,
  68. SAMPR_BOOT_TYPE * BootType
  69. )
  70. {
  71. DWORD Type ;
  72. DWORD Length ;
  73. int Result ;
  74. Length = sizeof( SAMPR_BOOT_TYPE );
  75. Result = RegQueryValueEx( LsaKey,
  76. TEXT("SamiSetting"),
  77. 0,
  78. &Type,
  79. (PUCHAR) BootType,
  80. &Length );
  81. if ( Result == 0 )
  82. {
  83. NOTHING ;
  84. }
  85. else
  86. {
  87. *BootType = SamBootKeyNone ;
  88. }
  89. return STATUS_SUCCESS ;
  90. }
  91. NTSTATUS
  92. xSamiSetBootKeyInformation(
  93. SAM_HANDLE Domain,
  94. SAMPR_BOOT_TYPE BootType,
  95. PUNICODE_STRING Old,
  96. PUNICODE_STRING New
  97. )
  98. {
  99. DWORD Type ;
  100. DWORD Length ;
  101. HASH Hash ;
  102. int Result ;
  103. Length = 16 ;
  104. Result = RegQueryValueEx( LsaKey,
  105. TEXT("SamiKey"),
  106. 0,
  107. &Type,
  108. Hash.Digest,
  109. &Length );
  110. if ( Result == 0 )
  111. {
  112. if (!RtlEqualMemory( Hash.Digest, Old->Buffer, 16 ) )
  113. {
  114. return STATUS_WRONG_PASSWORD ;
  115. }
  116. }
  117. RegSetValueEx( LsaKey,
  118. TEXT("SamiKey"),
  119. 0,
  120. REG_BINARY,
  121. (PUCHAR) New->Buffer,
  122. 16 );
  123. RegSetValueEx( LsaKey,
  124. TEXT("SamiSetting"),
  125. 0,
  126. REG_DWORD,
  127. (PUCHAR) &BootType,
  128. sizeof( DWORD ) );
  129. return STATUS_SUCCESS ;
  130. }
  131. #endif
  132. BOOL
  133. SetupCursor(
  134. BOOL fWait
  135. )
  136. {
  137. BOOL Current ;
  138. if ( hcurArrow == NULL )
  139. {
  140. hcurArrow = LoadCursor( NULL, IDC_ARROW );
  141. }
  142. if ( hcurWait == NULL )
  143. {
  144. hcurWait = LoadCursor( NULL, IDC_WAIT );
  145. }
  146. if ( WaitCursor != fWait )
  147. {
  148. SetCursor( fWait ? hcurWait : hcurArrow );
  149. Current = WaitCursor ;
  150. WaitCursor = fWait ;
  151. }
  152. else
  153. {
  154. Current = fWait ;
  155. }
  156. return Current ;
  157. }
  158. int
  159. MyMessageBox(
  160. HWND hWnd,
  161. int Text,
  162. int Caption,
  163. UINT Flags
  164. )
  165. {
  166. WCHAR String1[ MAX_PATH ];
  167. WCHAR String2[ MAX_PATH ];
  168. int Result ;
  169. BOOL Cursor ;
  170. LoadString( GetModuleHandle(NULL), Caption, String1, MAX_PATH );
  171. LoadString( GetModuleHandle(NULL), Text, String2, MAX_PATH );
  172. Cursor = SetupCursor( FALSE );
  173. Result = MessageBox( hWnd, String2, String1, Flags );
  174. SetupCursor( Cursor );
  175. return Result ;
  176. }
  177. int
  178. DisplayError(
  179. HWND hWnd,
  180. int Description,
  181. int Error
  182. )
  183. {
  184. TCHAR Message[ MAX_PATH ];
  185. TCHAR Caption[ MAX_PATH ];
  186. TCHAR Descr[ MAX_PATH ];
  187. int Result ;
  188. BOOL Cursor ;
  189. FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
  190. NULL,
  191. Error,
  192. 0,
  193. Message,
  194. MAX_PATH,
  195. NULL );
  196. LoadString( GetModuleHandle( NULL ), Description, Caption, MAX_PATH );
  197. wsprintf( Descr, Caption, Message );
  198. LoadString( GetModuleHandle( NULL ), IDS_ERROR_CAPTION, Caption, MAX_PATH );
  199. Cursor = SetupCursor( FALSE );
  200. Result = MessageBox( hWnd, Message, Caption, MB_ICONSTOP | MB_OK );
  201. SetupCursor( Cursor );
  202. return Result ;
  203. }
  204. VOID
  205. DisplayErrorAndExit(
  206. HWND hWnd,
  207. int Description,
  208. int Error
  209. )
  210. {
  211. DisplayError( hWnd, Description, Error );
  212. ExitProcess( Error );
  213. }
  214. VOID
  215. EnableSection(
  216. HWND hDlg,
  217. BOOL Enable,
  218. PDWORD IdList,
  219. DWORD Count
  220. )
  221. {
  222. DWORD i ;
  223. for ( i = 0 ; i < Count ; i++ )
  224. {
  225. EnableWindow( GetDlgItem( hDlg, IdList[ i ]), Enable );
  226. }
  227. }
  228. NTSTATUS
  229. SbLoadKeyFromDisk(
  230. PUCHAR KeyDataBuffer
  231. )
  232. {
  233. HANDLE hFile ;
  234. ULONG Actual ;
  235. ULONG ErrorMode ;
  236. ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
  237. SetupCursor( TRUE );
  238. hFile = CreateFileA( "A:\\startkey.key",
  239. GENERIC_READ,
  240. 0,
  241. NULL,
  242. OPEN_EXISTING,
  243. FILE_ATTRIBUTE_NORMAL,
  244. NULL );
  245. if ( hFile == INVALID_HANDLE_VALUE )
  246. {
  247. SetErrorMode( ErrorMode );
  248. SetupCursor( FALSE );
  249. return STATUS_OBJECT_NAME_NOT_FOUND ;
  250. }
  251. if (!ReadFile( hFile, KeyDataBuffer, 16, &Actual, NULL ) ||
  252. (Actual != 16 ))
  253. {
  254. SetErrorMode( ErrorMode );
  255. CloseHandle( hFile );
  256. SetupCursor( FALSE );
  257. return STATUS_FILE_CORRUPT_ERROR ;
  258. }
  259. SetErrorMode( ErrorMode );
  260. CloseHandle( hFile );
  261. SetupCursor( FALSE );
  262. return STATUS_SUCCESS ;
  263. }
  264. DWORD
  265. SaveKeyToDisk(
  266. HWND hDlg,
  267. PUCHAR Key
  268. )
  269. {
  270. HANDLE hFile ;
  271. ULONG Actual ;
  272. ULONG ErrorMode ;
  273. DWORD Error ;
  274. ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
  275. SetupCursor( TRUE );
  276. hFile = CreateFile( KEYFILE,
  277. GENERIC_WRITE,
  278. 0,
  279. NULL,
  280. CREATE_NEW,
  281. FILE_ATTRIBUTE_NORMAL,
  282. NULL );
  283. if ( hFile == INVALID_HANDLE_VALUE )
  284. {
  285. Error = GetLastError() ;
  286. if ( Error == ERROR_FILE_EXISTS )
  287. {
  288. //
  289. // This we can handle.
  290. //
  291. (VOID) DeleteFile( KEYFILE_SAVE );
  292. if ( !MoveFile( KEYFILE, KEYFILE_SAVE ) )
  293. {
  294. Error = GetLastError() ;
  295. }
  296. else
  297. {
  298. hFile = CreateFile( KEYFILE,
  299. GENERIC_WRITE,
  300. 0,
  301. NULL,
  302. CREATE_NEW,
  303. FILE_ATTRIBUTE_NORMAL,
  304. NULL );
  305. if ( hFile == INVALID_HANDLE_VALUE )
  306. {
  307. Error = GetLastError() ;
  308. }
  309. else
  310. {
  311. MyMessageBox( hDlg, IDS_RENAMED_OLD,
  312. IDS_WARNING_CAPTION,
  313. MB_OK | MB_ICONINFORMATION );
  314. Error = 0 ;
  315. }
  316. }
  317. }
  318. if ( Error )
  319. {
  320. SetErrorMode( ErrorMode );
  321. SetupCursor( FALSE );
  322. return Error ;
  323. }
  324. }
  325. if (!WriteFile( hFile, Key, 16, &Actual, NULL ) ||
  326. (Actual != 16 ))
  327. {
  328. SetErrorMode( ErrorMode );
  329. CloseHandle( hFile );
  330. SetupCursor( FALSE );
  331. return GetLastError() ;
  332. }
  333. SetErrorMode( ErrorMode );
  334. CloseHandle( hFile );
  335. SetupCursor( FALSE );
  336. return 0 ;
  337. }
  338. LRESULT
  339. ValidateDialog(
  340. HWND hDlg,
  341. PSAMPR_BOOT_TYPE Type,
  342. PHASH NewHash
  343. )
  344. {
  345. SAMPR_BOOT_TYPE NewType ;
  346. WCHAR Password[ MAX_PATH ];
  347. WCHAR Confirm[ MAX_PATH ];
  348. PWSTR Scan ;
  349. DWORD PwLen, ConfLen ;
  350. BOOL Match ;
  351. MD5_CTX Md5 ;
  352. if ( IsDlgButtonChecked( hDlg, IDD_PW_PASSWORD_BTN ) == BST_CHECKED )
  353. {
  354. NewType = SamBootKeyPassword ;
  355. }
  356. else if ( IsDlgButtonChecked( hDlg, IDD_PW_FLOPPY ) == BST_CHECKED )
  357. {
  358. NewType = SamBootKeyDisk ;
  359. }
  360. else
  361. {
  362. NewType = SamBootKeyStored ;
  363. }
  364. *Type = NewType ;
  365. switch ( NewType )
  366. {
  367. case SamBootKeyDisk:
  368. case SamBootKeyStored:
  369. STGenerateRandomBits( NewHash->Digest, 16 );
  370. break;
  371. case SamBootKeyPassword:
  372. PwLen = GetDlgItemText( hDlg, IDD_PW_PASSWORD, Password, MAX_PATH );
  373. ConfLen = GetDlgItemText( hDlg, IDD_PW_CONFIRM, Confirm, MAX_PATH );
  374. if ( (PwLen != ConfLen) ||
  375. (wcscmp( Password, Confirm ) ) )
  376. {
  377. Match = FALSE ;
  378. }
  379. else
  380. {
  381. Match = TRUE ;
  382. }
  383. //
  384. // Clear the PW from the dialog:
  385. //
  386. Scan = Confirm ;
  387. while ( *Scan != L'\0' )
  388. {
  389. *Scan++ = ' ';
  390. }
  391. SetDlgItemText( hDlg, IDD_PW_PASSWORD, Confirm );
  392. SetDlgItemText( hDlg, IDD_PW_CONFIRM, Confirm );
  393. SetDlgItemText( hDlg, IDD_PW_PASSWORD, L"" );
  394. SetDlgItemText( hDlg, IDD_PW_CONFIRM, L"" );
  395. if ( !Match )
  396. {
  397. MyMessageBox( hDlg,
  398. IDS_NEW_PW_MATCH,
  399. IDS_ERROR_CAPTION,
  400. MB_OK | MB_ICONSTOP );
  401. SetFocus( GetDlgItem( hDlg, IDD_PW_PASSWORD ) );
  402. return IDCANCEL ;
  403. }
  404. MD5Init( &Md5 );
  405. MD5Update( &Md5, (PUCHAR) Password, PwLen * sizeof( WCHAR ) );
  406. MD5Final( &Md5 );
  407. ZeroMemory( Password, PwLen * sizeof( WCHAR ) );
  408. CopyMemory( NewHash->Digest, Md5.digest, 16 );
  409. break;
  410. }
  411. return IDOK ;
  412. }
  413. LRESULT
  414. CALLBACK
  415. ConfirmPasswordDlg(
  416. HWND hDlg,
  417. UINT Message,
  418. WPARAM wParam,
  419. LPARAM lParam
  420. )
  421. {
  422. WCHAR PW[ 128 ];
  423. MD5_CTX Md5;
  424. int PWLen ;
  425. PUCHAR Hash ;
  426. switch ( Message )
  427. {
  428. case WM_INITDIALOG:
  429. if ( KeyDataPwIcon == NULL )
  430. {
  431. KeyDataPwIcon = LoadImage( GetModuleHandle(NULL),
  432. MAKEINTRESOURCE( IDD_SB_ICON_PW ),
  433. IMAGE_ICON,
  434. 64, 72,
  435. LR_DEFAULTCOLOR );
  436. }
  437. SendMessage( GetDlgItem( hDlg, IDD_SB_PW_ICON ),
  438. STM_SETICON,
  439. (WPARAM) KeyDataPwIcon,
  440. 0 );
  441. SetWindowLongPtr( hDlg, GWLP_USERDATA, lParam );
  442. return TRUE ;
  443. case WM_COMMAND:
  444. switch ( LOWORD( wParam ) )
  445. {
  446. case IDCANCEL:
  447. EndDialog( hDlg, IDCANCEL );
  448. return TRUE ;
  449. case IDOK:
  450. // Get text
  451. PWLen = GetDlgItemText( hDlg, IDD_SB_PASSWORD, PW, 128 );
  452. // Convert length to bytes
  453. PWLen *= sizeof(WCHAR);
  454. // hash it
  455. MD5Init( &Md5 );
  456. MD5Update( &Md5, (PUCHAR) PW, PWLen );
  457. MD5Final( &Md5 );
  458. // save it
  459. Hash = (PUCHAR) GetWindowLongPtr( hDlg, GWLP_USERDATA );
  460. CopyMemory( Hash, Md5.digest, 16 );
  461. // clean up:
  462. EndDialog( hDlg, IDOK );
  463. FillMemory( PW, PWLen, 0xFF );
  464. ZeroMemory( PW, PWLen );
  465. FillMemory( &Md5, sizeof( Md5 ), 0xFF );
  466. ZeroMemory( &Md5, sizeof( Md5 ) );
  467. return TRUE ;
  468. default:
  469. break;
  470. }
  471. case WM_CLOSE:
  472. break;
  473. }
  474. return FALSE ;
  475. }
  476. LRESULT
  477. CALLBACK
  478. ConfirmDiskDlg(
  479. HWND hDlg,
  480. UINT Message,
  481. WPARAM wParam,
  482. LPARAM lParam
  483. )
  484. {
  485. NTSTATUS Status ;
  486. PUCHAR Hash ;
  487. switch ( Message )
  488. {
  489. case WM_INITDIALOG:
  490. if ( KeyDataDiskIcon == NULL )
  491. {
  492. KeyDataDiskIcon = LoadImage( GetModuleHandle(NULL),
  493. MAKEINTRESOURCE( IDD_SB_ICON_DISK ),
  494. IMAGE_ICON,
  495. 64, 72,
  496. LR_DEFAULTCOLOR );
  497. }
  498. SendMessage( GetDlgItem( hDlg, IDD_SB_DISK_ICON ),
  499. STM_SETICON,
  500. (WPARAM) KeyDataDiskIcon,
  501. 0 );
  502. SetWindowLongPtr( hDlg, GWLP_USERDATA, lParam );
  503. return TRUE ;
  504. case WM_COMMAND:
  505. switch ( LOWORD( wParam ) )
  506. {
  507. case IDCANCEL:
  508. EndDialog( hDlg, IDCANCEL );
  509. return TRUE ;
  510. case IDOK:
  511. Hash = (PUCHAR) GetWindowLongPtr( hDlg, GWLP_USERDATA );
  512. Status = SbLoadKeyFromDisk( Hash );
  513. if ( !NT_SUCCESS( Status ) )
  514. {
  515. MyMessageBox( hDlg,
  516. IDS_KEYFILE_NOT_FOUND,
  517. IDS_ERROR_CAPTION,
  518. MB_ICONSTOP | MB_OK);
  519. }
  520. else
  521. {
  522. EndDialog( hDlg, IDOK );
  523. }
  524. return TRUE ;
  525. default:
  526. break;
  527. }
  528. case WM_CLOSE:
  529. break;
  530. }
  531. return FALSE ;
  532. }
  533. LRESULT
  534. HandleUpdate(
  535. HWND hDlg
  536. )
  537. {
  538. HASH OldHash ;
  539. HASH NewHash ;
  540. SAMPR_BOOT_TYPE NewType ;
  541. SAMPR_BOOT_TYPE ExtraType ;
  542. LRESULT Result ;
  543. NTSTATUS Status ;
  544. UNICODE_STRING Old ;
  545. UNICODE_STRING New ;
  546. Result = ValidateDialog( hDlg, &NewType, &NewHash );
  547. if ( Result == IDCANCEL )
  548. {
  549. return Result ;
  550. }
  551. switch ( OriginalBootOption )
  552. {
  553. case SamBootKeyNone:
  554. break;
  555. case SamBootKeyStored:
  556. if (!DeobfuscateKey(&OldHash))
  557. {
  558. Result = IDCANCEL ;
  559. }
  560. break;
  561. case SamBootKeyPassword:
  562. Result = DialogBoxParam( GetModuleHandle( NULL ),
  563. MAKEINTRESOURCE( IDD_SECURE_BOOT ),
  564. hDlg,
  565. ConfirmPasswordDlg,
  566. (LPARAM) &OldHash );
  567. if ( Result == IDCANCEL )
  568. {
  569. return Result ;
  570. }
  571. break;
  572. case SamBootKeyDisk:
  573. Result = DialogBoxParam( GetModuleHandle( NULL ),
  574. MAKEINTRESOURCE( IDD_SECURE_BOOT_DISK ),
  575. hDlg,
  576. ConfirmDiskDlg,
  577. (LPARAM) &OldHash );
  578. if ( Result == IDCANCEL )
  579. {
  580. return Result ;
  581. }
  582. break;
  583. }
  584. Old.Buffer = (PWSTR) OldHash.Digest ;
  585. Old.Length = 16 ;
  586. Old.MaximumLength = 16 ;
  587. New.Buffer = (PWSTR) NewHash.Digest ;
  588. New.Length = 16 ;
  589. New.MaximumLength = 16 ;
  590. if ( NewType == SamBootKeyDisk )
  591. {
  592. ExtraType = SamBootKeyDisk ;
  593. NewType = SamBootKeyStored ;
  594. }
  595. else
  596. {
  597. ExtraType = NewType ;
  598. }
  599. Status = xSamiSetBootKeyInformation(
  600. DomainHandle,
  601. NewType,
  602. (OriginalBootOption == SamBootKeyNone ? NULL : &Old),
  603. &New );
  604. if ( !NT_SUCCESS( Status ) )
  605. {
  606. Result = RtlNtStatusToDosError( Status );
  607. DisplayError( hDlg, IDS_SETPASS_FAILED, (int) Result );
  608. return IDCANCEL ;
  609. }
  610. Result = RegSetValueEx( LsaKey,
  611. SYSTEM_KEY,
  612. 0,
  613. REG_DWORD,
  614. (PUCHAR) &NewType,
  615. sizeof( NewType ) );
  616. if ( NewType == SamBootKeyStored )
  617. {
  618. ObfuscateKey( &NewHash );
  619. }
  620. MyMessageBox( hDlg, IDS_SETPASS_SUCCESS, IDS_SUCCESS_CAPTION,
  621. MB_OK | MB_ICONINFORMATION );
  622. //
  623. // Switch back to the intended NewType:
  624. //
  625. NewType = ExtraType ;
  626. if ( NewType == SamBootKeyDisk )
  627. {
  628. MyMessageBox( hDlg, IDS_INSERT_FLOPPY, IDS_SAVE_KEY_CAPTION,
  629. MB_OK | MB_ICONQUESTION );
  630. Result = SaveKeyToDisk( hDlg, NewHash.Digest );
  631. while ( Result != 0 )
  632. {
  633. MyMessageBox( hDlg, IDS_SAVE_KEY_FAILED, IDS_SAVE_KEY_CAPTION,
  634. MB_OK | MB_ICONSTOP );
  635. Result = SaveKeyToDisk( hDlg, NewHash.Digest );
  636. }
  637. //
  638. // Once the disk has been written successfully, update SAM and the
  639. // registry with the correct type:
  640. //
  641. Status = xSamiSetBootKeyInformation(
  642. DomainHandle,
  643. NewType,
  644. &New,
  645. &New );
  646. if ( NT_SUCCESS( Status ) )
  647. {
  648. Result = RegSetValueEx( LsaKey,
  649. SYSTEM_KEY,
  650. 0,
  651. REG_DWORD,
  652. (PUCHAR) &NewType,
  653. sizeof( NewType ) );
  654. }
  655. MyMessageBox( hDlg, IDS_SAVE_KEY_SUCCESS, IDS_SAVE_KEY_CAPTION,
  656. MB_OK | MB_ICONINFORMATION );
  657. }
  658. //
  659. // Now, if the new type isn't Store-local, write some random stuff in
  660. // there.
  661. //
  662. if ( NewType != SamBootKeyStored )
  663. {
  664. STGenerateRandomBits( NewHash.Digest, 16 );
  665. ObfuscateKey( &NewHash );
  666. }
  667. return IDOK ;
  668. }
  669. LRESULT
  670. CALLBACK
  671. UpdateDlg(
  672. HWND hDlg,
  673. UINT Message,
  674. WPARAM wParam,
  675. LPARAM lParam
  676. )
  677. {
  678. LRESULT Result ;
  679. switch ( Message )
  680. {
  681. case WM_INITDIALOG:
  682. switch ( SecureBootOption )
  683. {
  684. case SamBootKeyPassword:
  685. CheckDlgButton( hDlg, IDD_PW_PASSWORD_BTN, BST_CHECKED );
  686. CheckDlgButton( hDlg, IDD_PW_STORE_LOCAL, BST_CHECKED );
  687. EnableSection( hDlg,
  688. FALSE,
  689. GenSection,
  690. sizeof( GenSection ) /sizeof ( DWORD ) );
  691. SetFocus( GetDlgItem( hDlg, IDD_PW_PASSWORD_BTN ) );
  692. break;
  693. case SamBootKeyStored:
  694. CheckDlgButton( hDlg, IDD_PW_AUTO, BST_CHECKED );
  695. CheckDlgButton( hDlg, IDD_PW_STORE_LOCAL, BST_CHECKED );
  696. EnableSection( hDlg,
  697. FALSE,
  698. PwSection,
  699. sizeof( PwSection ) / sizeof( DWORD ) );
  700. SetFocus( GetDlgItem( hDlg, IDD_PW_STORE_LOCAL ) );
  701. break;
  702. case SamBootKeyDisk:
  703. CheckDlgButton( hDlg, IDD_PW_AUTO, BST_CHECKED );
  704. CheckDlgButton( hDlg, IDD_PW_FLOPPY, BST_CHECKED );
  705. EnableSection( hDlg,
  706. FALSE,
  707. PwSection,
  708. sizeof( PwSection ) / sizeof( DWORD ) );
  709. SetFocus( GetDlgItem( hDlg, IDD_PW_FLOPPY ) );
  710. break;
  711. default:
  712. return FALSE ;
  713. }
  714. return FALSE ;
  715. case WM_COMMAND:
  716. switch ( LOWORD( wParam ) )
  717. {
  718. case IDOK:
  719. Result = HandleUpdate( hDlg );
  720. if ( Result == IDOK )
  721. {
  722. EndDialog( hDlg, IDOK );
  723. }
  724. return TRUE ;
  725. case IDCANCEL:
  726. EndDialog( hDlg, IDCANCEL );
  727. return TRUE ;
  728. case IDD_PW_PASSWORD_BTN:
  729. if ( HIWORD( wParam ) == BN_CLICKED )
  730. {
  731. if ( IsDlgButtonChecked( hDlg, IDD_PW_PASSWORD_BTN )
  732. != BST_CHECKED )
  733. {
  734. break;
  735. }
  736. EnableSection( hDlg,
  737. TRUE,
  738. PwSection,
  739. sizeof( PwSection ) / sizeof(DWORD) );
  740. EnableSection( hDlg,
  741. FALSE,
  742. GenSection,
  743. sizeof( GenSection ) / sizeof( DWORD ) );
  744. return TRUE ;
  745. }
  746. break;
  747. case IDD_PW_AUTO:
  748. if ( HIWORD( wParam ) == BN_CLICKED )
  749. {
  750. if ( IsDlgButtonChecked( hDlg, IDD_PW_AUTO )
  751. != BST_CHECKED )
  752. {
  753. break;
  754. }
  755. EnableSection( hDlg,
  756. TRUE,
  757. GenSection,
  758. sizeof( GenSection ) / sizeof( DWORD ) );
  759. EnableSection( hDlg,
  760. FALSE,
  761. PwSection,
  762. sizeof( PwSection ) / sizeof( DWORD ) );
  763. return TRUE ;
  764. }
  765. break;
  766. }
  767. break;
  768. default:
  769. break;
  770. }
  771. return FALSE ;
  772. }
  773. LRESULT
  774. CALLBACK
  775. MainDlg(
  776. HWND hDlg,
  777. UINT Message,
  778. WPARAM wParam,
  779. LPARAM lParam
  780. )
  781. {
  782. LRESULT Result ;
  783. switch ( Message )
  784. {
  785. case WM_INITDIALOG:
  786. if ( hLockIcon == NULL )
  787. {
  788. hLockIcon = LoadImage( GetModuleHandle( NULL ),
  789. MAKEINTRESOURCE( LOCK_ICON ),
  790. IMAGE_ICON,
  791. 64, 64,
  792. LR_DEFAULTCOLOR );
  793. }
  794. SendMessage( GetDlgItem( hDlg, IDD_MAIN_ICON ),
  795. STM_SETICON,
  796. (WPARAM) hLockIcon,
  797. 0 );
  798. if ( SecureBootOption )
  799. {
  800. EnableWindow( GetDlgItem( hDlg, IDD_MAIN_DISABLED ), FALSE );
  801. CheckDlgButton( hDlg, IDD_MAIN_ENABLED, BST_CHECKED );
  802. }
  803. else
  804. {
  805. EnableWindow( GetDlgItem( hDlg, IDD_MAIN_UPDATE ), FALSE );
  806. CheckDlgButton( hDlg, IDD_MAIN_DISABLED, BST_CHECKED );
  807. }
  808. return TRUE ;
  809. case WM_COMMAND:
  810. switch ( LOWORD( wParam ) )
  811. {
  812. case IDCANCEL:
  813. EndDialog( hDlg, IDOK );
  814. return TRUE ;
  815. case IDOK:
  816. if ( IsDlgButtonChecked( hDlg, IDD_MAIN_DISABLED ) ==
  817. BST_CHECKED )
  818. {
  819. EndDialog( hDlg, IDOK );
  820. return TRUE ;
  821. }
  822. if ( SecureBootOption )
  823. {
  824. EndDialog( hDlg, IDOK );
  825. return TRUE ;
  826. }
  827. //
  828. // Currently disabled, and the user checked enabled, and
  829. // pressed OK. DROP THROUGH to the
  830. // Update case.
  831. //
  832. //
  833. // Set default to Local Store:
  834. //
  835. Result = MyMessageBox( hDlg, IDS_ARE_YOU_SURE,
  836. IDS_ARE_YOU_SURE_CAP,
  837. MB_ICONWARNING | MB_OKCANCEL |
  838. MB_DEFBUTTON2 );
  839. if ( Result == IDCANCEL )
  840. {
  841. return TRUE ;
  842. }
  843. SecureBootOption = SamBootKeyStored ;
  844. case IDD_MAIN_UPDATE:
  845. Result = DialogBox( GetModuleHandle(NULL),
  846. MAKEINTRESOURCE( IDD_PASSWORD_DLG ),
  847. hDlg,
  848. UpdateDlg
  849. );
  850. if ( Result == IDOK )
  851. {
  852. EnableWindow( GetDlgItem( hDlg, IDD_MAIN_DISABLED ), FALSE );
  853. CheckDlgButton( hDlg, IDD_MAIN_ENABLED, BST_CHECKED );
  854. EndDialog( hDlg, IDOK );
  855. }
  856. else
  857. {
  858. SecureBootOption = OriginalBootOption ;
  859. }
  860. return TRUE ;
  861. }
  862. default:
  863. break;
  864. }
  865. return FALSE ;
  866. }
  867. BOOL
  868. UnattendedLocal(
  869. VOID
  870. )
  871. {
  872. HASH OldHash ;
  873. HASH NewHash ;
  874. SAMPR_BOOT_TYPE NewType ;
  875. int Result ;
  876. NTSTATUS Status ;
  877. UNICODE_STRING Old ;
  878. UNICODE_STRING New ;
  879. Result = 0;
  880. if ( OriginalBootOption == SamBootKeyStored )
  881. {
  882. if ( !DeobfuscateKey( &OldHash ) )
  883. {
  884. Result = IDCANCEL ;
  885. }
  886. }
  887. if ( Result == IDCANCEL )
  888. {
  889. return FALSE ;
  890. }
  891. NewType = SamBootKeyStored ;
  892. Old.Buffer = (PWSTR) OldHash.Digest ;
  893. Old.Length = 16 ;
  894. Old.MaximumLength = 16 ;
  895. New.Buffer = (PWSTR) NewHash.Digest ;
  896. New.Length = 16 ;
  897. New.MaximumLength = 16 ;
  898. Status = xSamiSetBootKeyInformation(
  899. DomainHandle,
  900. NewType,
  901. (OriginalBootOption == SamBootKeyNone ? NULL : &Old),
  902. &New );
  903. if ( !NT_SUCCESS( Status ) )
  904. {
  905. Result = RtlNtStatusToDosError( Status );
  906. return FALSE ;
  907. }
  908. Result = RegSetValueEx( LsaKey,
  909. SYSTEM_KEY,
  910. 0,
  911. REG_DWORD,
  912. (PUCHAR) &NewType,
  913. sizeof( NewType ) );
  914. ObfuscateKey( &NewHash );
  915. return TRUE ;
  916. }
  917. DWORD
  918. OpenSamAccountDomain(
  919. VOID
  920. )
  921. {
  922. NTSTATUS Status ;
  923. UNICODE_STRING String ;
  924. OBJECT_ATTRIBUTES Obja ;
  925. LSA_HANDLE LsaHandle = NULL;
  926. PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo = NULL;
  927. CAIROSID DomainSid;
  928. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  929. RtlInitUnicodeString( &String, L"" );
  930. InitializeObjectAttributes( &Obja, NULL, 0, NULL, NULL );
  931. Status = SamConnect( &String,
  932. &SamHandle,
  933. MAXIMUM_ALLOWED,
  934. &Obja );
  935. if ( !NT_SUCCESS( Status ) )
  936. {
  937. return RtlNtStatusToDosError( Status );
  938. }
  939. RtlZeroMemory(&Obja, sizeof(OBJECT_ATTRIBUTES));
  940. Status = LsaOpenPolicy(
  941. &String,
  942. &Obja,
  943. POLICY_VIEW_LOCAL_INFORMATION,
  944. &LsaHandle
  945. );
  946. if (!NT_SUCCESS(Status))
  947. {
  948. SamCloseHandle( SamHandle );
  949. return( RtlNtStatusToDosError( Status ) );
  950. }
  951. Status = LsaQueryInformationPolicy(
  952. LsaHandle,
  953. PolicyAccountDomainInformation,
  954. (PVOID *) &DomainInfo
  955. );
  956. if (!NT_SUCCESS(Status))
  957. {
  958. LsaClose( LsaHandle);
  959. SamCloseHandle( SamHandle );
  960. return( RtlNtStatusToDosError( Status ) );
  961. }
  962. RtlCopyMemory(
  963. &DomainSid,
  964. DomainInfo->DomainSid,
  965. RtlLengthSid(DomainInfo->DomainSid)
  966. );
  967. LsaFreeMemory(DomainInfo);
  968. LsaClose( LsaHandle );
  969. Status = SamOpenDomain(
  970. SamHandle,
  971. MAXIMUM_ALLOWED,
  972. (PSID) &DomainSid,
  973. &DomainHandle
  974. );
  975. return RtlNtStatusToDosError( Status );
  976. }
  977. void
  978. __cdecl
  979. wmain (int argc, WCHAR *argv[])
  980. {
  981. HKEY Key ;
  982. int err ;
  983. SAMPR_BOOT_TYPE SystemSetting ;
  984. SAMPR_BOOT_TYPE SamSetting ;
  985. DWORD Type;
  986. DWORD Length ;
  987. NTSTATUS Status ;
  988. WCHAR MsgBuffer[ MAX_PATH ];
  989. STInitializeRNG();
  990. err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  991. TEXT("System\\CurrentControlSet\\Control\\Lsa"),
  992. 0,
  993. KEY_READ | KEY_WRITE,
  994. & Key );
  995. if ( err )
  996. {
  997. DisplayErrorAndExit( NULL, IDS_SYSTEM_ERROR_OCCURRED, err );
  998. }
  999. LsaKey = Key ;
  1000. Length = sizeof( SystemSetting );
  1001. err = RegQueryValueEx( Key,
  1002. SYSTEM_KEY,
  1003. NULL,
  1004. &Type,
  1005. (PUCHAR) &SystemSetting,
  1006. &Length );
  1007. if ( err )
  1008. {
  1009. SystemSetting = SamBootKeyNone ;
  1010. }
  1011. //
  1012. // Now, compare with SAM:
  1013. //
  1014. err = OpenSamAccountDomain();
  1015. if ( err )
  1016. {
  1017. DisplayErrorAndExit( NULL, IDS_SYSTEM_ERROR_OCCURRED, err );
  1018. }
  1019. Status = xSamiGetBootKeyInformation( DomainHandle,
  1020. &SamSetting );
  1021. if ( !NT_SUCCESS( Status ) )
  1022. {
  1023. DisplayErrorAndExit( NULL,
  1024. IDS_SYSTEM_ERROR_OCCURRED,
  1025. RtlNtStatusToDosError( Status ) );
  1026. }
  1027. if ( SamSetting != SystemSetting )
  1028. {
  1029. SystemSetting = SamSetting ;
  1030. err = RegSetValueEx( Key,
  1031. SYSTEM_KEY,
  1032. 0,
  1033. REG_DWORD,
  1034. (PUCHAR) &SystemSetting,
  1035. sizeof( DWORD ) );
  1036. MyMessageBox( NULL, IDS_SAM_NOT_SYNC, IDS_WARNING_CAPTION,
  1037. MB_ICONHAND | MB_OK );
  1038. }
  1039. SecureBootOption = SamSetting ;
  1040. OriginalBootOption = SamSetting ;
  1041. if ( argc > 1 )
  1042. {
  1043. LoadString( GetModuleHandle( NULL ), IDS_L_OPTION, OptionL, 4 );
  1044. LoadString( GetModuleHandle( NULL ), IDS_Q_OPTION, OptionQ, 4 );
  1045. //
  1046. // Check for unattended:
  1047. //
  1048. if ( (*argv[1] == L'-') ||
  1049. (*argv[1] == L'/') )
  1050. {
  1051. if ( towupper(argv[1][1]) == OptionL[0] )
  1052. {
  1053. Unattended = TRUE ;
  1054. }
  1055. }
  1056. }
  1057. if ( Unattended )
  1058. {
  1059. if ( ( OriginalBootOption == SamBootKeyStored ) ||
  1060. ( OriginalBootOption == SamBootKeyNone ) )
  1061. {
  1062. UnattendedLocal();
  1063. }
  1064. else
  1065. {
  1066. LoadString( GetModuleHandle( NULL ), IDS_NO_UNATTENDED,
  1067. MsgBuffer, MAX_PATH );
  1068. fprintf( stderr, "%ws\n", MsgBuffer );
  1069. }
  1070. }
  1071. else
  1072. {
  1073. DialogBox( GetModuleHandle(NULL),
  1074. MAKEINTRESOURCE( IDD_MAIN_DIALOG ),
  1075. NULL,
  1076. MainDlg );
  1077. }
  1078. RegCloseKey( LsaKey );
  1079. }