Bug 1008778 - Respect Security Zone settings when the download manager marks a downloaded file. r=paolo

This commit is contained in:
Masatoshi Kimura 2014-05-15 06:58:35 +09:00
parent b679a28c6d
commit c5e2b269d2
3 changed files with 66 additions and 15 deletions

View File

@ -7,7 +7,7 @@
interface nsIURI;
interface nsIFile;
[scriptable, uuid(314A0972-E6E3-413A-8BD4-2C052BCB2C74)]
[scriptable, uuid(9f556e4a-d9b3-46c3-9f8f-d0db1ac6c8c1)]
interface mozIDownloadPlatform : nsISupports
{
/**
@ -36,4 +36,24 @@ interface mozIDownloadPlatform : nsISupports
*/
void downloadDone(in nsIURI aSource, in nsIFile aTarget,
in ACString aContentType, in boolean aIsPrivate);
/**
* Security Zone constants. Used by mapUrlToZone().
*/
const unsigned long ZONE_MY_COMPUTER = 0;
const unsigned long ZONE_INTRANET = 1;
const unsigned long ZONE_TRUSTED = 2;
const unsigned long ZONE_INTERNET = 3;
const unsigned long ZONE_RESTRICTED = 4;
/**
* Proxy for IInternetSecurityManager::MapUrlToZone().
*
* Windows only.
*
* @param aURL
* URI of the download
* @return Security Zone corresponding to aURL.
*/
unsigned long mapUrlToZone(in AString aURL);
};

View File

@ -79,14 +79,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gApplicationReputationService",
"@mozilla.org/downloads/application-reputation-service;1",
Ci.nsIApplicationReputationService);
/**
* 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");
});
XPCOMUtils.defineLazyServiceGetter(this, "volumeService",
"@mozilla.org/telephony/volume-service;1",
"nsIVolumeService");
@ -583,13 +575,25 @@ this.DownloadIntegration = {
// The stream created in this way is forward-compatible with all the
// current and future versions of Windows.
if (this._shouldSaveZoneInformation()) {
let zone;
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();
zone = gDownloadPlatform.mapUrlToZone(aDownload.source.url);
} catch (e) {
// Default to Internet Zone if mapUrlToZone failed for
// whatever reason.
zone = Ci.mozIDownloadPlatform.ZONE_INTERNET;
}
try {
// Don't write zone IDs for Local, Intranet, or Trusted sites
// to match Windows behavior.
if (zone >= Ci.mozIDownloadPlatform.ZONE_INTERNET) {
let streamPath = aDownload.target.path + ":Zone.Identifier";
let stream = yield OS.File.open(streamPath, { create: true });
try {
yield stream.write(new TextEncoder().encode("[ZoneTransfer]\r\nZoneId=" + zone + "\r\n"));
} finally {
yield stream.close();
}
}
} catch (ex) {
// If writing to the stream fails, we ignore the error and continue.

View File

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DownloadPlatform.h"
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsIURI.h"
#include "nsIFile.h"
@ -14,6 +15,7 @@
#ifdef XP_WIN
#include <shlobj.h>
#include <urlmon.h>
#include "nsILocalFileWin.h"
#endif
@ -146,3 +148,28 @@ nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget,
return NS_OK;
}
nsresult DownloadPlatform::MapUrlToZone(const nsAString& aURL,
uint32_t* aZone)
{
#ifdef XP_WIN
nsRefPtr<IInternetSecurityManager> inetSecMgr;
if (FAILED(CoCreateInstance(CLSID_InternetSecurityManager, NULL,
CLSCTX_ALL, IID_IInternetSecurityManager,
getter_AddRefs(inetSecMgr)))) {
return NS_ERROR_UNEXPECTED;
}
DWORD zone;
if (inetSecMgr->MapUrlToZone(PromiseFlatString(aURL).get(),
&zone, 0) != S_OK) {
return NS_ERROR_UNEXPECTED;
} else {
*aZone = zone;
}
return NS_OK;
#else
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}