Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* Any copyright is dedicated to the Public Domain.
2 * http://creativecommons.org/publicdomain/zero/1.0/
3 */
5 #ifdef XP_WIN
6 # include <windows.h>
7 # include <wintrust.h>
8 # include <tlhelp32.h>
9 # include <softpub.h>
10 # include <direct.h>
11 # include <io.h>
12 typedef WCHAR NS_tchar;
13 # define NS_main wmain
14 # define F_OK 00
15 # define W_OK 02
16 # define R_OK 04
17 # define stat _stat
18 # define NS_T(str) L ## str
19 # define NS_tsnprintf(dest, count, fmt, ...) \
20 { \
21 int _count = count - 1; \
22 _snwprintf(dest, _count, fmt, ##__VA_ARGS__); \
23 dest[_count] = L'\0'; \
24 }
25 # define NS_taccess _waccess
26 # define NS_tchdir _wchdir
27 # define NS_tfopen _wfopen
28 # define NS_tstrcmp wcscmp
29 # define NS_ttoi _wtoi
30 # define NS_tstat _wstat
31 # define NS_tgetcwd _wgetcwd
32 # define LOG_S "%S"
34 #include "../common/updatehelper.h"
36 #else
37 # include <unistd.h>
38 # define NS_main main
39 typedef char NS_tchar;
40 # define NS_T(str) str
41 # define NS_tsnprintf snprintf
42 # define NS_taccess access
43 # define NS_tchdir chdir
44 # define NS_tfopen fopen
45 # define NS_tstrcmp strcmp
46 # define NS_ttoi atoi
47 # define NS_tstat stat
48 # define NS_tgetcwd getcwd
49 # define NS_tfputs fputs
50 # define LOG_S "%s"
51 #endif
53 #include "mozilla/NullPtr.h"
54 #include <stdlib.h>
55 #include <stdio.h>
56 #include <string.h>
57 #include <sys/types.h>
58 #include <sys/stat.h>
60 #ifndef MAXPATHLEN
61 # ifdef PATH_MAX
62 # define MAXPATHLEN PATH_MAX
63 # elif defined(MAX_PATH)
64 # define MAXPATHLEN MAX_PATH
65 # elif defined(_MAX_PATH)
66 # define MAXPATHLEN _MAX_PATH
67 # elif defined(CCHMAXPATH)
68 # define MAXPATHLEN CCHMAXPATH
69 # else
70 # define MAXPATHLEN 1024
71 # endif
72 #endif
74 static void
75 WriteMsg(const NS_tchar *path, const char *status)
76 {
77 FILE* outFP = NS_tfopen(path, NS_T("wb"));
78 if (!outFP)
79 return;
81 fprintf(outFP, "%s\n", status);
82 fclose(outFP);
83 outFP = nullptr;
84 }
86 static bool
87 CheckMsg(const NS_tchar *path, const char *expected)
88 {
89 if (NS_taccess(path, F_OK)) {
90 return false;
91 }
93 FILE *inFP = NS_tfopen(path, NS_T("rb"));
94 if (!inFP) {
95 return false;
96 }
98 struct stat ms;
99 if (fstat(fileno(inFP), &ms)) {
100 return false;
101 }
103 char *mbuf = (char *) malloc(ms.st_size + 1);
104 if (!mbuf) {
105 return false;
106 }
108 size_t r = ms.st_size;
109 char *rb = mbuf;
110 size_t c = fread(rb, sizeof(char), 50, inFP);
111 r -= c;
112 rb += c;
113 if (c == 0 && r) {
114 return false;
115 }
116 mbuf[ms.st_size] = '\0';
117 rb = mbuf;
119 fclose(inFP);
120 inFP = nullptr;
121 return strcmp(rb, expected) == 0;
122 }
124 #ifdef XP_WIN
125 /**
126 * Verifies the trust of the specified file path.
127 *
128 * @param filePath The file path to check.
129 * @return ERROR_SUCCESS if successful, or the last error code otherwise.
130 */
131 DWORD
132 VerifyCertificateTrustForFile(LPCWSTR filePath)
133 {
134 // Setup the file to check.
135 WINTRUST_FILE_INFO fileToCheck;
136 ZeroMemory(&fileToCheck, sizeof(fileToCheck));
137 fileToCheck.cbStruct = sizeof(WINTRUST_FILE_INFO);
138 fileToCheck.pcwszFilePath = filePath;
140 // Setup what to check, we want to check it is signed and trusted.
141 WINTRUST_DATA trustData;
142 ZeroMemory(&trustData, sizeof(trustData));
143 trustData.cbStruct = sizeof(trustData);
144 trustData.pPolicyCallbackData = nullptr;
145 trustData.pSIPClientData = nullptr;
146 trustData.dwUIChoice = WTD_UI_NONE;
147 trustData.fdwRevocationChecks = WTD_REVOKE_NONE;
148 trustData.dwUnionChoice = WTD_CHOICE_FILE;
149 trustData.dwStateAction = 0;
150 trustData.hWVTStateData = nullptr;
151 trustData.pwszURLReference = nullptr;
152 // no UI
153 trustData.dwUIContext = 0;
154 trustData.pFile = &fileToCheck;
156 GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
157 // Check if the file is signed by something that is trusted.
158 return WinVerifyTrust(nullptr, &policyGUID, &trustData);
159 }
161 #endif
163 int NS_main(int argc, NS_tchar **argv)
164 {
166 if (argc < 3) {
167 fprintf(stderr, \
168 "\n" \
169 "Application Update Service Test Helper\n" \
170 "\n" \
171 "Usage: WORKINGDIR INFILE OUTFILE -s SECONDS [FILETOLOCK]\n" \
172 " or: WORKINGDIR LOGFILE [ARG2 ARG3...]\n" \
173 " or: signature-check filepath\n" \
174 " or: setup-symlink dir1 dir2 file symlink\n" \
175 " or: remove-symlink dir1 dir2 file symlink\n" \
176 " or: check-symlink symlink\n" \
177 "\n" \
178 " WORKINGDIR \tThe relative path to the working directory to use.\n" \
179 " INFILE \tThe relative path from the working directory for the file to\n" \
180 " \tread actions to perform such as finish.\n" \
181 " OUTFILE \tThe relative path from the working directory for the file to\n" \
182 " \twrite status information.\n" \
183 " SECONDS \tThe number of seconds to sleep.\n" \
184 " FILETOLOCK \tThe relative path from the working directory to an existing\n" \
185 " \tfile to open exlusively.\n" \
186 " \tOnly available on Windows platforms and silently ignored on\n" \
187 " \tother platforms.\n" \
188 " LOGFILE \tThe relative path from the working directory to log the\n" \
189 " \tcommand line arguments.\n" \
190 " ARG2 ARG3...\tArguments to write to the LOGFILE after the preceding command\n" \
191 " \tline arguments.\n" \
192 "\n" \
193 "Note: All paths must be relative.\n" \
194 "\n");
195 return 1;
196 }
198 if (!NS_tstrcmp(argv[1], NS_T("check-signature"))) {
199 #ifdef XP_WIN
200 if (ERROR_SUCCESS == VerifyCertificateTrustForFile(argv[2])) {
201 return 0;
202 } else {
203 return 1;
204 }
205 #else
206 // Not implemented on non-Windows platforms
207 return 1;
208 #endif
209 }
211 if (!NS_tstrcmp(argv[1], NS_T("setup-symlink"))) {
212 #ifdef XP_UNIX
213 NS_tchar path[MAXPATHLEN];
214 NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
215 NS_T("%s/%s"), NS_T("/tmp"), argv[2]);
216 mkdir(path, 0755);
217 NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
218 NS_T("%s/%s/%s"), NS_T("/tmp"), argv[2], argv[3]);
219 mkdir(path, 0755);
220 NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
221 NS_T("%s/%s/%s/%s"), NS_T("/tmp"), argv[2], argv[3], argv[4]);
222 FILE * file = NS_tfopen(path, NS_T("w"));
223 if (file) {
224 NS_tfputs(NS_T("test"), file);
225 fclose(file);
226 }
227 symlink(path, argv[5]);
228 NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
229 NS_T("%s/%s"), NS_T("/tmp"), argv[2]);
230 if (argc > 6 && !NS_tstrcmp(argv[6], NS_T("change-perm"))) {
231 chmod(path, 0644);
232 }
233 return 0;
234 #else
235 // Not implemented on non-Unix platforms
236 return 1;
237 #endif
238 }
240 if (!NS_tstrcmp(argv[1], NS_T("remove-symlink"))) {
241 #ifdef XP_UNIX
242 NS_tchar path[MAXPATHLEN];
243 NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
244 NS_T("%s/%s"), NS_T("/tmp"), argv[2]);
245 chmod(path, 0755);
246 NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
247 NS_T("%s/%s/%s/%s"), NS_T("/tmp"), argv[2], argv[3], argv[4]);
248 unlink(path);
249 NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
250 NS_T("%s/%s/%s"), NS_T("/tmp"), argv[2], argv[3]);
251 rmdir(path);
252 NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
253 NS_T("%s/%s"), NS_T("/tmp"), argv[2]);
254 rmdir(path);
255 return 0;
256 #else
257 // Not implemented on non-Unix platforms
258 return 1;
259 #endif
260 }
262 if (!NS_tstrcmp(argv[1], NS_T("check-symlink"))) {
263 #ifdef XP_UNIX
264 struct stat ss;
265 lstat(argv[2], &ss);
266 return S_ISLNK(ss.st_mode) ? 0 : 1;
267 #else
268 // Not implemented on non-Unix platforms
269 return 1;
270 #endif
271 }
273 if (!NS_tstrcmp(argv[1], NS_T("wait-for-service-stop"))) {
274 #ifdef XP_WIN
275 const int maxWaitSeconds = NS_ttoi(argv[3]);
276 LPCWSTR serviceName = argv[2];
277 DWORD serviceState = WaitForServiceStop(serviceName, maxWaitSeconds);
278 if (SERVICE_STOPPED == serviceState) {
279 return 0;
280 } else {
281 return serviceState;
282 }
283 #else
284 // Not implemented on non-Windows platforms
285 return 1;
286 #endif
287 }
289 if (!NS_tstrcmp(argv[1], NS_T("wait-for-application-exit"))) {
290 #ifdef XP_WIN
291 const int maxWaitSeconds = NS_ttoi(argv[3]);
292 LPCWSTR application = argv[2];
293 DWORD ret = WaitForProcessExit(application, maxWaitSeconds);
294 if (ERROR_SUCCESS == ret) {
295 return 0;
296 } else if (WAIT_TIMEOUT == ret) {
297 return 1;
298 } else {
299 return 2;
300 }
301 #else
302 // Not implemented on non-Windows platforms
303 return 1;
304 #endif
305 }
307 int i = 0;
309 if (NS_tchdir(argv[1]) != 0) {
310 return 1;
311 }
313 // File in use test helper section
314 if (!NS_tstrcmp(argv[4], NS_T("-s"))) {
315 NS_tchar *cwd = NS_tgetcwd(nullptr, 0);
316 NS_tchar inFilePath[MAXPATHLEN];
317 NS_tsnprintf(inFilePath, sizeof(inFilePath)/sizeof(inFilePath[0]),
318 NS_T("%s/%s"), cwd, argv[2]);
319 NS_tchar outFilePath[MAXPATHLEN];
320 NS_tsnprintf(outFilePath, sizeof(outFilePath)/sizeof(outFilePath[0]),
321 NS_T("%s/%s"), cwd, argv[3]);
323 int seconds = NS_ttoi(argv[5]);
324 #ifdef XP_WIN
325 HANDLE hFile = INVALID_HANDLE_VALUE;
326 if (argc == 7) {
327 hFile = CreateFileW(argv[6],
328 DELETE | GENERIC_WRITE, 0,
329 nullptr, OPEN_EXISTING, 0, nullptr);
330 if (hFile == INVALID_HANDLE_VALUE) {
331 WriteMsg(outFilePath, "error_locking");
332 return 1;
333 }
334 }
336 WriteMsg(outFilePath, "sleeping");
337 while (!CheckMsg(inFilePath, "finish\n") && i++ <= seconds) {
338 Sleep(1000);
339 }
341 if (argc == 7) {
342 CloseHandle(hFile);
343 }
344 #else
345 WriteMsg(outFilePath, "sleeping");
346 while (!CheckMsg(inFilePath, "finish\n") && i++ <= seconds) {
347 sleep(1);
348 }
349 #endif
350 WriteMsg(outFilePath, "finished");
351 return 0;
352 }
354 // Command line argument test helper section
355 NS_tchar logFilePath[MAXPATHLEN];
356 NS_tsnprintf(logFilePath, sizeof(logFilePath)/sizeof(logFilePath[0]),
357 NS_T("%s"), argv[2]);
359 FILE* logFP = NS_tfopen(logFilePath, NS_T("wb"));
360 for (i = 1; i < argc; ++i) {
361 fprintf(logFP, LOG_S "\n", argv[i]);
362 }
364 fclose(logFP);
365 logFP = nullptr;
367 return 0;
368 }