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.

373 lines
11 KiB

  1. #include <wininetp.h>
  2. #define SZ_COOKIE_EXPORT_HEADER "# Internet Explorer cookie file, exported for Netscape browsers."
  3. #define IE_LOCAL_PREFIX "~~local~~"
  4. #define IE_COOKIE_PREFIX "Cookie:"
  5. void FileTimeToDosTime( FILETIME ft, DWORD* pTime_t);
  6. struct CACHE_ENTRY_INFO_BUFFER : public INTERNET_CACHE_ENTRY_INFO
  7. {
  8. BYTE _ab[MAX_CACHE_ENTRY_INFO_SIZE];
  9. };
  10. //****************************************************
  11. //
  12. // FileOutputStream - utility
  13. //
  14. class FileOutputStream
  15. {
  16. public:
  17. FileOutputStream()
  18. : m_hFile(INVALID_HANDLE_VALUE), m_fError(FALSE), m_dwLastError(0)
  19. {
  20. }
  21. ~FileOutputStream()
  22. {
  23. if( m_hFile != INVALID_HANDLE_VALUE)
  24. CloseHandle( m_hFile);
  25. }
  26. BOOL Load( LPCTSTR szFilename, BOOL fAppend)
  27. {
  28. m_hFile = CreateFile( szFilename, GENERIC_WRITE | GENERIC_READ, 0, NULL,
  29. fAppend ? OPEN_ALWAYS : CREATE_ALWAYS,
  30. FILE_ATTRIBUTE_NORMAL, NULL);
  31. if( m_hFile == INVALID_HANDLE_VALUE)
  32. {
  33. m_fError = TRUE;
  34. m_dwLastError = GetLastError();
  35. return FALSE;
  36. }
  37. if( fAppend
  38. && SetFilePointer( m_hFile, 0, NULL, FILE_END) == 0xFFFFFFFF)
  39. {
  40. m_fError = TRUE;
  41. m_dwLastError = GetLastError();
  42. return FALSE;
  43. }
  44. return TRUE;
  45. }
  46. BOOL DumpStr( LPCSTR szString, DWORD cbSize)
  47. {
  48. DWORD dwTemp;
  49. if( m_fError == TRUE)
  50. return FALSE;
  51. if( WriteFile( m_hFile, szString, cbSize, &dwTemp, NULL) == TRUE)
  52. {
  53. return TRUE;
  54. }
  55. else
  56. {
  57. m_fError = TRUE;
  58. m_dwLastError = GetLastError();
  59. return FALSE;
  60. }
  61. }
  62. BOOL WriteBool( BOOL fBool)
  63. {
  64. if( fBool == TRUE)
  65. return DumpStr( "TRUE", sizeof("TRUE") - 1);
  66. else
  67. return DumpStr( "FALSE", sizeof("FALSE") - 1);
  68. }
  69. BOOL WriteTab()
  70. {
  71. return DumpStr( "\t", sizeof('\t'));
  72. }
  73. BOOL WriteNSNewline()
  74. {
  75. return DumpStr( "\r\n\r\n", sizeof("\r\n\r\n") - 1);
  76. }
  77. BOOL IsError()
  78. {
  79. return m_fError;
  80. }
  81. private:
  82. HANDLE m_hFile;
  83. BOOL m_fError;
  84. DWORD m_dwLastError;
  85. };
  86. //****************************************************
  87. //
  88. // ExportCookieFile
  89. //
  90. // per-line format of Netscape cookie file
  91. //DOMAIN \t is_given_domain(TRUE|FALSE) \t PATH \t secure(TRUE|FALSE) \t time_t(EXPIRES) \t NAME \t VALUE
  92. BOOLAPI ExportCookieFileW( IN LPCWSTR szFilename, IN BOOL fAppend)
  93. {
  94. MEMORYPACKET mpFilename;
  95. ALLOC_MB(szFilename,0,mpFilename);
  96. if (!mpFilename.psStr)
  97. {
  98. return FALSE;
  99. }
  100. UNICODE_TO_ANSI(szFilename,mpFilename);
  101. return ExportCookieFileA( mpFilename.psStr, fAppend);
  102. };
  103. BOOLAPI ExportCookieFileA( IN LPCSTR szFilename, IN BOOL fAppend)
  104. {
  105. BOOL retVal = FALSE;
  106. CHAR* cursor;
  107. DWORD dwTemp;
  108. FileOutputStream outFile;
  109. CACHE_ENTRY_INFO_BUFFER *pcei = new CACHE_ENTRY_INFO_BUFFER;
  110. if (pcei == NULL)
  111. goto doneExportCookieFile;
  112. DWORD cbCeiSize = sizeof(*pcei);
  113. HANDLE hEnumeration = FindFirstUrlCacheEntry( IE_COOKIE_PREFIX, pcei, &cbCeiSize);
  114. if( hEnumeration == NULL)
  115. goto doneExportCookieFile;
  116. if( outFile.Load( szFilename, fAppend) != TRUE)
  117. goto doneExportCookieFile;
  118. if( !fAppend)
  119. {
  120. outFile.DumpStr( SZ_COOKIE_EXPORT_HEADER, sizeof(SZ_COOKIE_EXPORT_HEADER) - 1);
  121. outFile.WriteNSNewline();
  122. }
  123. if( outFile.IsError() == TRUE)
  124. goto doneExportCookieFile;
  125. // enumerate over the cookie cache entries.
  126. //Each cache entry will have a file which contains multiple cookies,
  127. //so inside this loop we will be enumerating over individual cookies.
  128. do
  129. {
  130. CHAR* pFileBuf = NULL;
  131. DWORD cbFileBufSize;
  132. CHAR* pDomain;
  133. //Generate the DOMAIN for all the cookies in this entry
  134. // example Urls in pEntry:
  135. // "Cookie:[email protected]/"
  136. // "Cookie:t-franks@~~local~~/c:\local\path\"
  137. // The correspondingDomain entry in NS cookie.txt:
  138. // "amazon.com"
  139. // "" -> local paths are empty strings to NS
  140. cursor = pcei->lpszSourceUrlName;
  141. while( *cursor != '@' && *cursor != '\0')
  142. cursor++;
  143. if( *cursor != '@')
  144. goto doneWithEntryOnExportCookie;
  145. pDomain = ++cursor;
  146. if( StrCmpN( pDomain, IE_LOCAL_PREFIX, sizeof(IE_LOCAL_PREFIX) - 1) != 0)
  147. {
  148. // if we have a non-local domain, clip off the path.
  149. while( *cursor != '/' && *cursor != '\0')
  150. cursor++;
  151. if( *cursor != '/')
  152. goto doneWithEntryOnExportCookie;
  153. *cursor = '\0';
  154. }
  155. else
  156. {
  157. // Else local cookies have a blank domain in the Netscape cookie files.
  158. pDomain[0] = '\0';
  159. }
  160. // load the attached file and enumerate through the contained cookies.
  161. if( (pcei->lpszLocalFileName == NULL)
  162. || (ReadFileToBuffer( pcei->lpszLocalFileName, (BYTE**)&pFileBuf, &cbFileBufSize)
  163. != TRUE))
  164. {
  165. goto doneWithEntryOnExportCookie;
  166. }
  167. CHAR* pFileCursor;
  168. pFileCursor = pFileBuf;
  169. while( pFileCursor < pFileBuf + cbFileBufSize)
  170. {
  171. CHAR *pszName, *pszValue, *pszHash, *pszFlags,
  172. *pszExpireTimeLow, *pszExpireTimeHigh,
  173. *pszLastTimeHigh, *pszLastTimeLow,
  174. *pszDelimiter;
  175. FILETIME ftExpire;
  176. DWORD dwFlags;
  177. // Get the first token (cookie name).
  178. pszName = StrTokEx(&pFileCursor, "\n");
  179. if (!pszName) // Cookie name.
  180. {
  181. // Normal termination of the parse.
  182. goto doneWithEntryOnExportCookie;
  183. }
  184. // Parse the rest of the cookie
  185. if( *pFileCursor == '\n')
  186. {
  187. pszValue = pFileCursor;
  188. *pszValue = '\0';
  189. pFileCursor++;
  190. }
  191. else
  192. pszValue = StrTokEx(&pFileCursor, "\n"); // Cookie value.
  193. pszHash = StrTokEx(&pFileCursor, "\n"); // Combo of domain and path.
  194. pszFlags = StrTokEx(&pFileCursor, "\n"); // Cookie flags.
  195. pszExpireTimeLow = StrTokEx(&pFileCursor, "\n"); // Expire time.
  196. pszExpireTimeHigh = StrTokEx(&pFileCursor, "\n");
  197. pszLastTimeLow = StrTokEx(&pFileCursor, "\n"); // Last Modified time.
  198. pszLastTimeHigh = StrTokEx(&pFileCursor, "\n");
  199. pszDelimiter = StrTokEx(&pFileCursor, "\n"); // Delimiter should be "*"
  200. // Abnormal termination of parse.
  201. if (!pszDelimiter || pszDelimiter[0] != '*')
  202. {
  203. INET_ASSERT(FALSE);
  204. goto doneWithEntryOnExportCookie;
  205. }
  206. // Get the expire time.
  207. ftExpire.dwLowDateTime = atoi(pszExpireTimeLow);
  208. ftExpire.dwHighDateTime = atoi(pszExpireTimeHigh);
  209. // Get the flags
  210. dwFlags = atoi(pszFlags);
  211. // If this is a session cookie, its non-persistent
  212. //and shouldn't be saved to file.
  213. // (session cookies shouldn't be in the index file, anyhow)
  214. INET_ASSERT( (dwFlags & COOKIE_SESSION) == 0 ? TRUE : FALSE);
  215. if( (dwFlags & COOKIE_SESSION) != 0)
  216. continue;
  217. // process parsed contents.
  218. CHAR* pszNSPath;
  219. DWORD timetExpire;
  220. // Example IE cookie file:
  221. // pszHash = "amazon.com/main/"
  222. // pszHash = "~~local~~/c:\local\path\"
  223. // corresponding Netscape path format:
  224. // pszNSPath = "/main/"
  225. // pszNSPath = "/c|/local/path/"
  226. cursor = pszHash;
  227. // move to the first '/'
  228. while( *cursor != '/' && *cursor != '\0')
  229. cursor++;
  230. if( *cursor != '/')
  231. continue;
  232. pszNSPath = cursor;
  233. // If this is a path on the Hard Disk, turn the '\\'s to '/'s
  234. //and ':'s to '|'s. (to conform with funky NS format)
  235. if( StrCmpN( pszHash, IE_LOCAL_PREFIX, sizeof(IE_LOCAL_PREFIX) - 1) == 0)
  236. {
  237. while( *cursor != '\0')
  238. {
  239. if( *cursor == '\\')
  240. *cursor = '/';
  241. if( *cursor == ':')
  242. *cursor = '|';
  243. cursor++;
  244. }
  245. }
  246. // convert to Netscape time format
  247. FileTimeToDosTime( ftExpire, &timetExpire);
  248. outFile.DumpStr( pDomain, lstrlen( pDomain));
  249. outFile.WriteTab();
  250. outFile.WriteBool( TRUE);
  251. outFile.WriteTab();
  252. outFile.DumpStr( pszNSPath, lstrlen( pszNSPath));
  253. outFile.WriteTab();
  254. outFile.WriteBool( (dwFlags & COOKIE_SECURE) != 0 ? TRUE : FALSE);
  255. outFile.WriteTab();
  256. CHAR expireBuffer[16];
  257. wsprintf( expireBuffer, "%lu", timetExpire);
  258. outFile.DumpStr( expireBuffer, lstrlen( expireBuffer));
  259. outFile.WriteTab();
  260. outFile.DumpStr( pszName, lstrlen( pszName));
  261. outFile.WriteTab();
  262. outFile.DumpStr( pszValue, lstrlen( pszValue));
  263. outFile.WriteNSNewline();
  264. }
  265. doneWithEntryOnExportCookie:
  266. if( pFileBuf != NULL)
  267. delete [] pFileBuf;
  268. if( outFile.IsError() == TRUE)
  269. goto doneExportCookieFile;
  270. }
  271. while( FindNextUrlCacheEntry( hEnumeration, pcei, &(cbCeiSize = sizeof(*pcei))));
  272. retVal = TRUE;
  273. doneExportCookieFile:
  274. if (pcei)
  275. delete pcei;
  276. if( hEnumeration != NULL)
  277. FindCloseUrlCache( hEnumeration);
  278. return retVal;
  279. }
  280. // reverse of part of transformation in InternetTimeFromTime_t
  281. // A filetime is the numbers of 100 ns since Jan 1, 1601, while
  282. //a dostime is the number of seconds since Jan 1, 1970.
  283. void FileTimeToDosTime( FILETIME ft, DWORD* pTime_t)
  284. {
  285. //dwl1970Offset is the number of ns from 1601 to 1970
  286. const DWORDLONG dwl1970Offset = 0x019dae9064bafa80;
  287. DWORDLONG lVal;
  288. lVal = ft.dwLowDateTime;
  289. lVal |= Int64ShllMod32( Int64ShllMod32( ft.dwHighDateTime, 16), 16 );
  290. *pTime_t = (DWORD)((lVal - dwl1970Offset) / 10000000);
  291. return;
  292. }