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.

912 lines
22 KiB

  1. /* Copyright (c) 1992-2001, Microsoft Corporation, all rights reserved
  2. **
  3. ** pcache.c
  4. ** Remote Access Phonebook - Win9x Password cache (PWL) decrypter
  5. ** Main routines
  6. **
  7. ** Portions of this code have been ported from:
  8. ** Win9x\proj\net\user\src\WNET\PCACHE
  9. **
  10. ** Whistler bug: 208318 Win9x Upg: Username and Password for DUN connectoid not
  11. ** migrated from Win9x to Whistler
  12. **
  13. ** 06/24/92 gregj
  14. ** 03/06/01 Jeff Sigman
  15. */
  16. #include "pch.h" // Pre-compiled
  17. #include "migmainp.h"
  18. #include "pcache.h" // Private pcache header
  19. #include <rc4.h> // RSA RC4 MD5 library
  20. #include <md5.h> // RSA RC4 MD5 library
  21. //----------------------------------------------------------------------------
  22. // Globals
  23. //----------------------------------------------------------------------------
  24. CHAR g_szPWLUsername[ UNLEN + 1 ];
  25. CHAR g_szPWLPassword[ PWLEN + 1 ];
  26. HANDLE g_hFile = NULL;
  27. RC4_KEYSTRUCT g_ks;
  28. NEW_PLAINTEXT_HEADER g_hdrPlaintext;
  29. NEW_ENCRYPTED_HEADER g_hdrEncrypted;
  30. //-----------------------------------------------------------------------------
  31. // Routines
  32. //-----------------------------------------------------------------------------
  33. UINT
  34. HashName (
  35. const CHAR* pbResource,
  36. WORD cbResource
  37. )
  38. {
  39. return cbResource ? ( ( *pbResource ) % BUCKET_COUNT ) : 0;
  40. }
  41. VOID
  42. Encrypt (
  43. CHAR *pbSource,
  44. WORD cbSource,
  45. CHAR *pbDest
  46. )
  47. {
  48. if ( pbDest )
  49. {
  50. memcpy ( pbDest, pbSource, cbSource );
  51. pbSource = pbDest;
  52. }
  53. rc4 ( &g_ks, cbSource, pbSource );
  54. return;
  55. }
  56. VOID
  57. Decrypt (
  58. CHAR *pbSource,
  59. WORD cbSource
  60. )
  61. {
  62. Encrypt ( pbSource, cbSource, NULL );
  63. return;
  64. }
  65. VOID
  66. ENCRYPTER (
  67. const CHAR* pszUsername,
  68. const CHAR* pszPassword,
  69. UINT iBucket,
  70. DWORD dwSalt
  71. )
  72. {
  73. UCHAR md5_hash[ 16 ];
  74. MD5_CTX ctxBucketNumber;
  75. MD5_CTX ctx;
  76. MD5Init ( &ctxBucketNumber );
  77. MD5Update (
  78. &ctxBucketNumber,
  79. (UCHAR* )&iBucket,
  80. sizeof( iBucket ) );
  81. MD5Update (
  82. &ctxBucketNumber,
  83. (UCHAR* )pszUsername,
  84. strlen ( pszUsername ) + 1 );
  85. MD5Update ( &ctxBucketNumber, (UCHAR* )&dwSalt, sizeof( dwSalt ) );
  86. MD5Final ( &ctxBucketNumber );
  87. MD5Init ( &ctx );
  88. MD5Update (
  89. &ctx,
  90. (UCHAR* )pszPassword,
  91. strlen ( pszPassword ) + 1 );
  92. MD5Update (
  93. &ctx,
  94. (UCHAR* )ctxBucketNumber.digest,
  95. sizeof( ctxBucketNumber.digest ) );
  96. MD5Final ( &ctx );
  97. memcpy ( md5_hash, ctx.digest, sizeof( md5_hash ) );
  98. memset ( (CHAR * )&ctx, '\0', sizeof( ctx ));
  99. memset ( (CHAR * )&ctxBucketNumber, '\0', sizeof( ctxBucketNumber ) );
  100. rc4_key ( &g_ks, sizeof( md5_hash ), md5_hash );
  101. }
  102. DWORD
  103. ReadData (
  104. WORD ibSeek,
  105. PVOID pbBuffer,
  106. WORD cbBuffer
  107. )
  108. {
  109. DWORD dwErr = ERROR_SUCCESS;
  110. DWORD cbRead = 0;
  111. if ( ( SetFilePointer (
  112. g_hFile, ibSeek, NULL,
  113. FILE_BEGIN ) == 0xffffffff ) ||
  114. ( !ReadFile (
  115. g_hFile, pbBuffer, cbBuffer,
  116. &cbRead, NULL ) ) )
  117. {
  118. return GetLastError ( );
  119. }
  120. return ( cbRead < cbBuffer ) ? IERR_CacheCorrupt : ERROR_SUCCESS;
  121. }
  122. VOID
  123. AssembleFindCacheName (
  124. CHAR* pszWindir,
  125. CHAR* pszResult
  126. )
  127. {
  128. CHAR szFind[ 6 ];
  129. CHAR* Current = szFind;
  130. DWORD i;
  131. strncpy ( pszResult, pszWindir, MAX_PATH - strlen(pszResult) );
  132. strncat ( pszResult, S_PWLDIR, MAX_PATH - strlen(pszResult) );
  133. strncat ( pszResult, "\\", MAX_PATH - strlen(pszResult) );
  134. for ( i = 0; (i < 5) && (i < strlen(g_szPWLUsername)); i++ )
  135. {
  136. *(Current++) = g_szPWLUsername[ i ];
  137. *Current = '\0';
  138. }
  139. if ( Current != szFind )
  140. {
  141. strncat ( pszResult, szFind, MAX_PATH - strlen(pszResult) );
  142. }
  143. strncat ( pszResult, S_SRCHPWL, MAX_PATH - strlen(pszResult) );
  144. }
  145. DWORD
  146. OpenCacheFile (
  147. VOID
  148. )
  149. {
  150. CHAR szFind[ MAX_PATH + 1 ];
  151. CHAR szWindir[ MAX_PATH + 1 ];
  152. CHAR szFilename[ MAX_PATH + 1 ];
  153. DWORD dwErr;
  154. HANDLE hFile;
  155. do
  156. {
  157. if ( !GetWindowsDirectoryA (szWindir, sizeof(szWindir) ) )
  158. {
  159. dwErr = ERROR_FILE_NOT_FOUND;
  160. break;
  161. }
  162. AssembleFindCacheName ( szWindir, szFind );
  163. DEBUGMSGA ((S_DBG_RAS, "AssembleFindCacheName: %s", szFind));
  164. dwErr = FindNewestFile ( szFind );
  165. BREAK_ON_DWERR( dwErr );
  166. strcpy ( szFilename, szWindir );
  167. strcat ( szFilename, S_PWLDIR );
  168. strcat ( szFilename, szFind );
  169. DEBUGMSGA ((S_DBG_RAS, "FindNewestFile: %s", szFind));
  170. hFile = CreateFileA (
  171. szFilename,
  172. GENERIC_READ | GENERIC_WRITE,
  173. 0,
  174. NULL,
  175. OPEN_EXISTING,
  176. FILE_FLAG_RANDOM_ACCESS,
  177. NULL );
  178. if ( hFile == INVALID_HANDLE_VALUE )
  179. {
  180. dwErr = GetLastError ( );
  181. break;
  182. }
  183. DEBUGMSGA ((S_DBG_RAS, "CreateFileA: %s", szFilename));
  184. g_hFile = hFile;
  185. } while ( FALSE );
  186. return dwErr;
  187. }
  188. DWORD
  189. ReadAndDecrypt (
  190. WORD ibSeek,
  191. PVOID pbBuffer,
  192. WORD cbBuffer
  193. )
  194. {
  195. DWORD dwErr = ReadData ( ibSeek, pbBuffer, cbBuffer );
  196. if ( dwErr )
  197. {
  198. return dwErr;
  199. }
  200. Decrypt ( (CHAR* )pbBuffer, cbBuffer );
  201. return ERROR_SUCCESS;
  202. }
  203. INT
  204. CompareCacheNames (
  205. const CHAR* pbRes1,
  206. WORD cbRes1,
  207. const CHAR* pbRes2,
  208. WORD cbRes2
  209. )
  210. {
  211. INT nRet = memcmp ( pbRes1, pbRes2, min ( cbRes1, cbRes2 ) );
  212. // DEBUGMSGA ((S_DBG_RAS, "CompareCacheNames"));
  213. // DEBUGMSGA ((S_DBG_RAS, "1 - %s", pbRes1));
  214. // DEBUGMSGA ((S_DBG_RAS, "2 - %s", pbRes2));
  215. if (nRet != 0)
  216. {
  217. return nRet;
  218. }
  219. return ( cbRes1 < cbRes2 ) ? -1 : ( ( cbRes1 == cbRes2 ) ? 0 : 1 );
  220. }
  221. DWORD
  222. LoadEncryptedHeader (
  223. VOID
  224. )
  225. {
  226. const UINT cbFirst = FIELDOFFSET ( NEW_ENCRYPTED_HEADER, aibBuckets );
  227. const UINT IBUCKET_HEADER = 0xffffffff;
  228. DWORD dwErr = ERROR_SUCCESS;
  229. do
  230. {
  231. ENCRYPTER (
  232. g_szPWLUsername,
  233. g_szPWLPassword,
  234. IBUCKET_HEADER,
  235. g_hdrPlaintext.adwBucketSalts[ BUCKET_COUNT ] );
  236. dwErr = ReadAndDecrypt (
  237. (WORD )g_hdrPlaintext.cbHeader,
  238. &g_hdrEncrypted,
  239. (WORD )cbFirst );
  240. BREAK_ON_DWERR( dwErr );
  241. // All aibBuckets except the first and last are stored in the file
  242. //
  243. dwErr = ReadAndDecrypt (
  244. (WORD )g_hdrPlaintext.cbHeader + cbFirst,
  245. (LPSTR )( &g_hdrEncrypted.aibBuckets[ 1 ] ),
  246. sizeof( g_hdrEncrypted.aibBuckets ) -
  247. ( sizeof( g_hdrEncrypted.aibBuckets[ 0 ] ) * 2) );
  248. BREAK_ON_DWERR( dwErr );
  249. // Generate the first and last aibBuckets values on the fly
  250. //
  251. g_hdrEncrypted.aibBuckets[ 0 ] =
  252. (USHORT )( g_hdrPlaintext.cbHeader + sizeof( NEW_ENCRYPTED_HEADER )
  253. - sizeof( g_hdrEncrypted.aibBuckets[ 0 ] ) * 2 );
  254. g_hdrEncrypted.aibBuckets[ BUCKET_COUNT ] =
  255. (USHORT )GetFileSize ( g_hFile, NULL );
  256. } while ( FALSE );
  257. return dwErr;
  258. }
  259. DWORD
  260. LoadPlaintextHeader (
  261. VOID
  262. )
  263. {
  264. DWORD dwErr = ReadData ( 0, &g_hdrPlaintext, sizeof( g_hdrPlaintext ) );
  265. if ( dwErr )
  266. {
  267. return dwErr;
  268. }
  269. if ( g_hdrPlaintext.ulSig != NEW_PLAINTEXT_SIGNATURE )
  270. {
  271. return ERROR_SUCCESS; // no key blobs, for sure
  272. }
  273. // If there are any key blobs, read them all in a chunk (the remainder of
  274. // the header) Otherwise we've already got the whole thing
  275. //
  276. if ( g_hdrPlaintext.cbHeader > sizeof( g_hdrPlaintext ) )
  277. {
  278. return ReadData (
  279. sizeof( g_hdrPlaintext ),
  280. ((CHAR* )&g_hdrPlaintext) + sizeof( g_hdrPlaintext ),
  281. ((WORD )g_hdrPlaintext.cbHeader) - sizeof( g_hdrPlaintext ) );
  282. }
  283. else
  284. {
  285. return ERROR_SUCCESS;
  286. }
  287. }
  288. DWORD
  289. LookupEntry (
  290. const CHAR* pbResource,
  291. WORD cbResource,
  292. UCHAR nType,
  293. PASSWORD_CACHE_ENTRY** ppce
  294. )
  295. {
  296. UINT iBucket = HashName ( pbResource, cbResource );
  297. WORD ibEntry = g_hdrEncrypted.aibBuckets[ iBucket ]; // offs of 1st entry
  298. WORD cbEntry;
  299. DWORD dwErr;
  300. PASSWORD_CACHE_ENTRY* pce = NULL;
  301. ENCRYPTER ( g_szPWLUsername, g_szPWLPassword, iBucket,
  302. g_hdrPlaintext.adwBucketSalts[ iBucket ] );
  303. dwErr = ReadAndDecrypt ( ibEntry, &cbEntry, sizeof( cbEntry ) );
  304. if ( dwErr )
  305. {
  306. return dwErr;
  307. }
  308. ibEntry += sizeof( cbEntry );
  309. if ( !cbEntry )
  310. {
  311. return IERR_CacheEntryNotFound;
  312. }
  313. pce = ( PASSWORD_CACHE_ENTRY* ) LocalAlloc (
  314. LMEM_FIXED,
  315. MAX_ENTRY_SIZE + sizeof( cbEntry ) );
  316. if ( pce == NULL )
  317. {
  318. return ERROR_NOT_ENOUGH_MEMORY;
  319. }
  320. while ( !( cbEntry & PCE_END_MARKER ) )
  321. {
  322. if ( cbEntry > MAX_ENTRY_SIZE )
  323. {
  324. dwErr = IERR_CacheCorrupt;
  325. break;
  326. }
  327. dwErr = ReadAndDecrypt ( ibEntry,
  328. ((CHAR* )pce) + sizeof( cbEntry ),
  329. cbEntry );
  330. BREAK_ON_DWERR( dwErr );
  331. pce->cbEntry = cbEntry; // we read this earlier, set it manually
  332. // DEBUGMSGA ((S_DBG_RAS, "LookupEntry: Searching for %s", pbResource));
  333. if (nType == pce->nType && !CompareCacheNames ( pbResource, cbResource,
  334. pce->abResource, pce->cbResource ))
  335. {
  336. DEBUGMSGA ((S_DBG_RAS, "LookupEntry: Match Found"));
  337. break; // dwErr == ERROR_SUCCESS
  338. }
  339. ibEntry += cbEntry;
  340. cbEntry = NEXT_PCE(pce)->cbEntry; // fetch next entry's length
  341. }
  342. if ( ( cbEntry & PCE_END_MARKER ) || dwErr != ERROR_SUCCESS )
  343. {
  344. LocalFree ( pce );
  345. pce = NULL;
  346. DEBUGMSGA ((S_DBG_RAS, "LookupEntry: Nothing Found"));
  347. return ( cbEntry & PCE_END_MARKER ) ? IERR_CacheEntryNotFound : dwErr;
  348. }
  349. *ppce = pce;
  350. return ERROR_SUCCESS;
  351. }
  352. DWORD
  353. ValidateEncryptedHeader (
  354. VOID
  355. )
  356. {
  357. MD5_CTX ctx;
  358. MD5Init ( &ctx );
  359. MD5Update ( &ctx, (UCHAR* )g_szPWLUsername,
  360. strlen( g_szPWLUsername ) + 1 );
  361. MD5Update (
  362. &ctx,
  363. (UCHAR* )g_hdrEncrypted.abRandomPadding,
  364. sizeof( g_hdrEncrypted.abRandomPadding ) );
  365. MD5Final ( &ctx );
  366. if ( memcmp (
  367. ctx.digest,
  368. g_hdrEncrypted.abAuthenticationHash,
  369. sizeof( ctx.digest ) ) )
  370. {
  371. return IERR_IncorrectUsername;
  372. }
  373. return ERROR_SUCCESS;
  374. }
  375. DWORD
  376. FindPWLResource (
  377. const CHAR* pbResource,
  378. WORD cbResource,
  379. CHAR* pbBuffer,
  380. WORD cbBuffer,
  381. UCHAR nType
  382. )
  383. {
  384. DWORD dwErr = ERROR_SUCCESS;
  385. CACHE_ENTRY_INFO* pcei = (CACHE_ENTRY_INFO* )pbBuffer;
  386. PASSWORD_CACHE_ENTRY* pce = NULL;
  387. do
  388. {
  389. if ( cbBuffer < sizeof( CACHE_ENTRY_INFO ) )
  390. {
  391. dwErr = ERROR_INSUFFICIENT_BUFFER;
  392. break;
  393. }
  394. dwErr = LookupEntry ( pbResource, cbResource, nType, &pce );
  395. BREAK_ON_DWERR( dwErr );
  396. pcei->cbResource = pce->cbResource;
  397. pcei->cbPassword = pce->cbPassword;
  398. pcei->iEntry = pce->iEntry;
  399. pcei->nType = pce->nType;
  400. pcei->dchResource = 0;
  401. pcei->dchPassword = 0;
  402. cbBuffer -= sizeof( CACHE_ENTRY_INFO );
  403. if ( pce->cbResource > cbBuffer )
  404. {
  405. dwErr = ERROR_MORE_DATA;
  406. break;
  407. }
  408. pcei->dchResource = sizeof( CACHE_ENTRY_INFO );
  409. memcpy ( pbBuffer + pcei->dchResource,
  410. pce->abResource, pce->cbResource );
  411. cbBuffer -= pce->cbResource;
  412. if ( pce->cbPassword > cbBuffer )
  413. {
  414. dwErr = ERROR_MORE_DATA;
  415. break;
  416. }
  417. pcei->dchPassword = pcei->dchResource + pcei->cbResource;
  418. memcpy ( pbBuffer + pcei->dchPassword,
  419. pce->abResource + pce->cbResource,
  420. pce->cbPassword );
  421. } while ( FALSE );
  422. //
  423. // Clean up
  424. //
  425. if ( pce )
  426. {
  427. LocalFree ( pce );
  428. pce = NULL;
  429. }
  430. return dwErr;
  431. }
  432. DWORD
  433. FindNewestFile (
  434. IN OUT CHAR* SourceName
  435. )
  436. {
  437. CHAR szCurFile[ MAX_PATH + 1 ];
  438. HANDLE SourceHandle;
  439. LARGE_INTEGER SourceFileTime, NextFileTime;
  440. WIN32_FIND_DATAA SourceFileData;
  441. SourceHandle = FindFirstFileA ( SourceName, &SourceFileData );
  442. if ( INVALID_HANDLE_VALUE == SourceHandle )
  443. {
  444. return ERROR_FILE_NOT_FOUND;
  445. }
  446. SourceFileTime.LowPart = SourceFileData.ftLastWriteTime.dwLowDateTime;
  447. SourceFileTime.HighPart = SourceFileData.ftLastWriteTime.dwHighDateTime;
  448. strcpy ( szCurFile, SourceFileData.cFileName );
  449. do
  450. {
  451. if ( !FindNextFileA (SourceHandle, &SourceFileData) )
  452. {
  453. break;
  454. }
  455. NextFileTime.LowPart = SourceFileData.ftLastWriteTime.dwLowDateTime;
  456. NextFileTime.HighPart = SourceFileData.ftLastWriteTime.dwHighDateTime;
  457. if ( NextFileTime.QuadPart > SourceFileTime.QuadPart )
  458. {
  459. SourceFileTime.LowPart = NextFileTime.LowPart;
  460. SourceFileTime.HighPart = NextFileTime.HighPart;
  461. strcpy ( szCurFile, SourceFileData.cFileName );
  462. }
  463. } while ( TRUE );
  464. strcpy ( SourceName, "\\" );
  465. strcat ( SourceName, szCurFile );
  466. //
  467. // Clean up
  468. //
  469. FindClose ( SourceHandle );
  470. return ERROR_SUCCESS;
  471. }
  472. VOID
  473. DeleteAllPwls (
  474. VOID
  475. )
  476. {
  477. CHAR szWindir[ MAX_PATH + 1 ];
  478. PCSTR pszPath = NULL;
  479. DEBUGMSGA ((S_DBG_RAS, "DeleteAllPwls"));
  480. do
  481. {
  482. //
  483. // Whistler bug: 427175 427176 PREFIX
  484. //
  485. if ( !GetWindowsDirectoryA ( szWindir, MAX_PATH ) ) {break;}
  486. DEBUGMSGA ((S_DBG_RAS, "GetWindowsDirectoryA %s", szWindir ));
  487. pszPath = JoinPathsA (szWindir, S_PWLDIR);
  488. if (!pszPath) {break;}
  489. if (DeleteDirectoryContentsA (pszPath))
  490. {
  491. if (RemoveDirectoryA (pszPath))
  492. {
  493. DEBUGMSGA ((S_DBG_RAS, "DeleteAllPwls: Success!"));
  494. }
  495. ELSE_DEBUGMSGA ((S_DBG_RAS, "Could not delete the tree %s.", pszPath));
  496. }
  497. ELSE_DEBUGMSGA ((S_DBG_RAS, "Could not delete the contents of %s.", pszPath));
  498. } while ( FALSE );
  499. //
  500. // Clean up
  501. //
  502. if (pszPath)
  503. {
  504. FreePathStringA (pszPath);
  505. }
  506. return;
  507. }
  508. //
  509. // Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,Domain,
  510. // Passwrds to not be migrated for DUN
  511. //
  512. BOOL
  513. StrCpyAFromWUsingAnsiEncoding(
  514. LPSTR pszDst,
  515. LPCWSTR pszSrc,
  516. DWORD dwDstChars
  517. )
  518. {
  519. DWORD cb;
  520. cb = WideCharToMultiByte(
  521. CP_ACP, 0, pszSrc, -1,
  522. pszDst, dwDstChars, NULL, NULL );
  523. if (cb == 0)
  524. {
  525. DEBUGMSGA ((S_DBG_RAS, "StrCpyAFromWUsingAnsiEncoding fail"));
  526. return TRUE;
  527. }
  528. // Success
  529. return FALSE;
  530. }
  531. //
  532. // Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,Domain,
  533. // Passwrds to not be migrated for DUN
  534. //
  535. BOOL
  536. StrCpyWFromAUsingAnsiEncoding(
  537. WCHAR* pszDst,
  538. LPCSTR pszSrc,
  539. DWORD dwDstChars
  540. )
  541. {
  542. DWORD cb;
  543. *pszDst = L'\0';
  544. cb = MultiByteToWideChar( CP_ACP, 0, pszSrc, -1, pszDst, dwDstChars );
  545. if (cb == 0)
  546. {
  547. DEBUGMSGA ((S_DBG_RAS, "StrCpyWFromAUsingAnsiEncoding fail"));
  548. return TRUE;
  549. }
  550. // Success
  551. return FALSE;
  552. }
  553. VOID
  554. CopyAndTruncate (
  555. LPSTR lpszDest,
  556. LPCSTR lpszSrc,
  557. UINT cbDest,
  558. BOOL flag
  559. )
  560. {
  561. strncpy ( lpszDest, lpszSrc, cbDest - 1 );
  562. //
  563. // strncpyf() won't null-terminate if src > dest
  564. //
  565. lpszDest[ cbDest - 1 ] = '\0';
  566. if ( flag )
  567. {
  568. CharUpperBuffA ( lpszDest, cbDest - 1 );
  569. CharToOemA ( lpszDest, lpszDest );
  570. }
  571. }
  572. DWORD
  573. OpenPWL (
  574. CHAR* Username,
  575. CHAR* Password,
  576. BOOL flag
  577. )
  578. {
  579. DWORD dwErr = ERROR_SUCCESS;
  580. do
  581. {
  582. CopyAndTruncate ( g_szPWLUsername, Username,
  583. sizeof( g_szPWLUsername ), flag );
  584. CopyAndTruncate ( g_szPWLPassword, Password,
  585. sizeof( g_szPWLPassword ), flag );
  586. ZeroMemory ( &g_hdrPlaintext, sizeof(g_hdrPlaintext) );
  587. ZeroMemory ( &g_hdrEncrypted, sizeof(g_hdrEncrypted) );
  588. dwErr = OpenCacheFile ( );
  589. if ( dwErr )
  590. {
  591. DEBUGMSGA ((S_DBG_RAS, "OpenCacheFile fail"));
  592. break;
  593. }
  594. dwErr = LoadPlaintextHeader ( );
  595. if ( dwErr )
  596. {
  597. DEBUGMSGA ((S_DBG_RAS, "LoadPlaintextHeader fail"));
  598. break;
  599. }
  600. if ( g_hdrPlaintext.ulSig == PLAINTEXT_SIGNATURE )
  601. {
  602. DEBUGMSGA ((S_DBG_RAS, "PLAINTEXT_SIGNATURE fail"));
  603. dwErr = IERR_BadSig;
  604. break;
  605. }
  606. if ( g_hdrPlaintext.ulSig != NEW_PLAINTEXT_SIGNATURE )
  607. {
  608. DEBUGMSGA ((S_DBG_RAS, "NEW_PLAINTEXT_SIGNATURE fail"));
  609. dwErr = IERR_BadSig;
  610. break;
  611. }
  612. dwErr = LoadEncryptedHeader ( );
  613. if ( dwErr )
  614. {
  615. DEBUGMSGA ((S_DBG_RAS, "LoadEncryptedHeader fail"));
  616. break;
  617. }
  618. dwErr = ValidateEncryptedHeader ( );
  619. if ( dwErr )
  620. {
  621. DEBUGMSGA ((S_DBG_RAS, "ValidateEncryptedHeader fail"));
  622. break;
  623. }
  624. } while ( FALSE );
  625. return dwErr;
  626. }
  627. DWORD
  628. FindPWLString (
  629. IN CHAR* EntryName,
  630. IN CHAR* ConnUser,
  631. IN OUT CHAR* Output
  632. )
  633. {
  634. CHAR resource[ MAX_PATH * 2 ];
  635. DWORD dwErr = ERROR_SUCCESS;
  636. DWORD cbCopied = 0;
  637. LPBYTE pcei = NULL;
  638. do
  639. {
  640. // Allocate a buffer for the cache entry info
  641. //
  642. if ( ( pcei = (LPBYTE )LocalAlloc ( LMEM_FIXED,
  643. sizeof( CACHE_ENTRY_INFO ) +
  644. ( RAS_MaxPortName + 1 ) +
  645. ( MAX_PATH + 1 ) ) ) == NULL )
  646. {
  647. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  648. break;
  649. }
  650. //
  651. // Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,Domain,
  652. // Passwrds to not be migrated for DUN
  653. //
  654. _snprintf(resource, sizeof(resource) - 1,
  655. S_RESOURCEMASK2, EntryName, ConnUser);
  656. DEBUGMSGA ((S_DBG_RAS, "FindPWLString: %s", resource));
  657. dwErr = FindPWLResource ( resource, (WORD )strlen( resource ), pcei,
  658. sizeof( CACHE_ENTRY_INFO ) + ( RAS_MaxPortName + 1 ) +
  659. ( MAX_PATH + 1 ), PCE_MISC );
  660. if ( dwErr )
  661. {
  662. dwErr = ERROR_INVALID_PASSWORD;
  663. break;
  664. }
  665. cbCopied = min( MAX_PATH,((CACHE_ENTRY_INFO* )pcei)->cbPassword );
  666. // Copy a non null-terminated string for password and terminate it with
  667. // a null character
  668. //
  669. if ( !cbCopied )
  670. {
  671. dwErr = ERROR_INVALID_PASSWORD;
  672. break;
  673. }
  674. memcpy ( Output,
  675. pcei+(((CACHE_ENTRY_INFO*)pcei)->dchPassword),
  676. cbCopied );
  677. Output[ cbCopied ] = '\0';
  678. } while ( FALSE );
  679. // Clean up
  680. //
  681. if ( pcei )
  682. {
  683. ZeroMemory ( pcei, sizeof( CACHE_ENTRY_INFO ) +
  684. ( RAS_MaxPortName + 1 ) +
  685. ( MAX_PATH + 1 ) );
  686. LocalFree ( pcei );
  687. pcei = NULL;
  688. }
  689. return dwErr;
  690. }
  691. BOOL
  692. MigrateEntryCreds (
  693. IN OUT PRAS_DIALPARAMS prdp,
  694. IN PCTSTR pszEntryName,
  695. IN PCTSTR pszUserName,
  696. IN PDWORD pdwFlag
  697. )
  698. {
  699. CHAR szEntryName[RAS_MaxPortName + 1];
  700. CHAR szUserName[UNLEN + 1];
  701. CHAR szConnUser[UNLEN + 1];
  702. CHAR szPassword[MAX_PATH * 2];
  703. do
  704. {
  705. ZeroMemory ( szEntryName, sizeof(szEntryName) );
  706. ZeroMemory ( szUserName, sizeof(szUserName) );
  707. ZeroMemory ( szConnUser, sizeof(szConnUser) );
  708. ZeroMemory ( szPassword, sizeof(szPassword) );
  709. //
  710. // Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,Domain,
  711. // Passwrds to not be migrated for DUN
  712. //
  713. if ( StrCpyAFromWUsingAnsiEncoding ( szEntryName, pszEntryName,
  714. sizeof (szEntryName) ) ||
  715. StrCpyAFromWUsingAnsiEncoding ( szUserName, pszUserName,
  716. sizeof (szUserName) ) ||
  717. StrCpyAFromWUsingAnsiEncoding ( szConnUser, prdp->DP_UserName,
  718. sizeof (szConnUser) ) )
  719. {
  720. DEBUGMSGA ((S_DBG_RAS, "MigrateEntryCreds: Init Conversion Fail" ));
  721. break;
  722. }
  723. if (OpenPWL ( szUserName, "", TRUE ))
  724. {
  725. DEBUGMSGA ((S_DBG_RAS, "MigrateEntryCreds: OpenPWL fail"));
  726. break;
  727. }
  728. if (FindPWLString ( szEntryName, szConnUser, szPassword ))
  729. {
  730. DEBUGMSGA ((S_DBG_RAS, "MigrateEntryCreds: FindPWLString fail"));
  731. break;
  732. }
  733. if (StrCpyWFromAUsingAnsiEncoding (prdp->DP_Password, szPassword,
  734. PWLEN ))
  735. {
  736. DEBUGMSGA ((S_DBG_RAS, "MigrateEntryCreds: Password Conversion Fail" ));
  737. break;
  738. }
  739. DEBUGMSGA ((S_DBG_RAS, "MigrateEntryCreds success"));
  740. *pdwFlag |= DLPARAMS_MASK_PASSWORD;
  741. } while ( FALSE );
  742. //
  743. // Clean up
  744. //
  745. ZeroMemory( szPassword, sizeof( szPassword ) );
  746. if ( g_hFile )
  747. {
  748. CloseHandle ( g_hFile );
  749. g_hFile = NULL;
  750. }
  751. if (*pdwFlag)
  752. {
  753. // Success
  754. *pdwFlag |= DLPARAMS_MASK_OLDSTYLE;
  755. return FALSE;
  756. }
  757. else
  758. {
  759. return TRUE;
  760. }
  761. }