mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 909022 - Mark all executables as coming from the Internet zone on Windows. r=enn
This commit is contained in:
parent
4ff4e8810b
commit
cadfff357d
@ -147,6 +147,13 @@ pref("browser.helperApps.alwaysAsk.force", false);
|
||||
pref("browser.helperApps.neverAsk.saveToDisk", "");
|
||||
pref("browser.helperApps.neverAsk.openFile", "");
|
||||
|
||||
#ifdef XP_WIN
|
||||
// By default, security zone information is stored in the Alternate Data Stream
|
||||
// of downloaded executable files on Windows. This preference allows disabling
|
||||
// this feature, and thus the associated system-level execution prompts.
|
||||
pref("browser.download.saveZoneInformation", true);
|
||||
#endif
|
||||
|
||||
// xxxbsmedberg: where should prefs for the toolkit go?
|
||||
pref("browser.chrome.toolbar_tips", true);
|
||||
// 0 = Pictures Only, 1 = Text Only, 2 = Pictures and Text
|
||||
|
@ -66,6 +66,14 @@ XPCOMUtils.defineLazyGetter(this, "gParentalControlsService", function() {
|
||||
return null;
|
||||
});
|
||||
|
||||
/**
|
||||
* ArrayBufferView representing the bytes to be written to the "Zone.Identifier"
|
||||
* Alternate Data Stream to mark a file as coming from the Internet zone.
|
||||
*/
|
||||
XPCOMUtils.defineLazyGetter(this, "gInternetZoneIdentifier", function() {
|
||||
return new TextEncoder().encode("[ZoneTransfer]\r\nZoneId=3\r\n");
|
||||
});
|
||||
|
||||
const Timer = Components.Constructor("@mozilla.org/timer;1", "nsITimer",
|
||||
"initWithCallback");
|
||||
|
||||
@ -389,15 +397,46 @@ this.DownloadIntegration = {
|
||||
* @rejects JavaScript exception if any of the operations failed.
|
||||
*/
|
||||
downloadDone: function(aDownload) {
|
||||
try {
|
||||
return Task.spawn(function () {
|
||||
#ifdef XP_WIN
|
||||
// On Windows, we mark any executable file saved to the NTFS file system
|
||||
// as coming from the Internet security zone. We do this by writing to
|
||||
// the "Zone.Identifier" Alternate Data Stream directly, because the Save
|
||||
// method of the IAttachmentExecute interface would trigger operations
|
||||
// that may cause the application to hang, or other performance issues.
|
||||
// The stream created in this way is forward-compatible with all the
|
||||
// current and future versions of Windows.
|
||||
if (Services.prefs.getBoolPref("browser.download.saveZoneInformation")) {
|
||||
let file = new FileUtils.File(aDownload.target.path);
|
||||
if (file.isExecutable()) {
|
||||
try {
|
||||
let streamPath = aDownload.target.path + ":Zone.Identifier";
|
||||
let stream = yield OS.File.open(streamPath, { create: true });
|
||||
try {
|
||||
yield stream.write(gInternetZoneIdentifier);
|
||||
} finally {
|
||||
yield stream.close();
|
||||
}
|
||||
} catch (ex) {
|
||||
// If writing to the stream fails, we ignore the error and continue.
|
||||
// The Windows API error 123 (ERROR_INVALID_NAME) is expected to
|
||||
// occur when working on a file system that does not support
|
||||
// Alternate Data Streams, like FAT32, thus we don't report this
|
||||
// specific error.
|
||||
if (!(ex instanceof OS.File.Error) || ex.winLastError != 123) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
gDownloadPlatform.downloadDone(NetUtil.newURI(aDownload.source.url),
|
||||
new FileUtils.File(aDownload.target.path),
|
||||
aDownload.contentType, aDownload.source.isPrivate);
|
||||
aDownload.contentType,
|
||||
aDownload.source.isPrivate);
|
||||
this.downloadDoneCalled = true;
|
||||
return Promise.resolve();
|
||||
} catch(ex) {
|
||||
return Promise.reject(ex);
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -432,12 +471,14 @@ this.DownloadIntegration = {
|
||||
let deferred = Task.spawn(function DI_launchDownload_task() {
|
||||
let file = new FileUtils.File(aDownload.target.path);
|
||||
|
||||
// Ask for confirmation if the file is executable. We do this here,
|
||||
// instead of letting the caller handle the prompt separately in the user
|
||||
// interface layer, for two reasons. The first is because of its security
|
||||
// nature, so that add-ons cannot forget to do this check. The second is
|
||||
// that the system-level security prompt, if enabled, would be displayed
|
||||
// at launch time in any case.
|
||||
#ifndef XP_WIN
|
||||
// Ask for confirmation if the file is executable, except on Windows where
|
||||
// the operating system will show the prompt based on the security zone.
|
||||
// We do this here, instead of letting the caller handle the prompt
|
||||
// separately in the user interface layer, for two reasons. The first is
|
||||
// because of its security nature, so that add-ons cannot forget to do
|
||||
// this check. The second is that the system-level security prompt would
|
||||
// be displayed at launch time in any case.
|
||||
if (file.isExecutable() && !this.dontOpenFileAndFolder) {
|
||||
// We don't anchor the prompt to a specific window intentionally, not
|
||||
// only because this is the same behavior as the system-level prompt,
|
||||
@ -449,6 +490,7 @@ this.DownloadIntegration = {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// In case of a double extension, like ".tar.gz", we only
|
||||
// consider the last one, because the MIME service cannot
|
||||
|
Loading…
Reference in New Issue
Block a user