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.

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