Полезная информация

Хотите узнать больше о расширениях? Посмотрите ролики, рассказывающие о работе с расширениями Firefox.

№103-08-2016 12:07:20

banbot
Moderator
 
Группа: Moderators
Зарегистрирован: 23-12-2007
Сообщений: 5149
UA: Firefox 51.0

Как отключить проверку цифровых подписей в дополнениях Firefox

Начиная с версии 48, Firefox игнорирует параметр xpinstall.signatures.required, который в значении false отключал проверку цифровых подписей дополнений. Пользователи столкнулись с проблемой: дополнения, не имеющие цифровой подписи, после обновления до 48-й версии были принудительно отключены. Разработан новый способ отключения проверки цифровых подписей для успешной работы дополнений, у которых цифровая подпись отсутствует.

Если после нижеуказанных действий дополнения всё ещё не работают, удалите их и установите заново.

Создайте текстовый файл:

  • Для версии 102 и выше:

    Выделить код

    Код:

    //
    try {(jsval => {
    	var dbg, gref, genv = func => {
    		var sandbox = new Cu.Sandbox(g, {freshCompartment: true});
    		Cc["@mozilla.org/jsdebugger;1"].createInstance(Ci.IJSDebugger).addClass(sandbox);
    		(dbg = new sandbox.Debugger()).addDebuggee(g);
    		gref = dbg.makeGlobalObjectReference(g);
    		return (genv = func => func && gref.makeDebuggeeValue(func).environment)(func);
    	}
    	var g = Cu.getGlobalForObject(jsval), o = g.Object, {freeze} = o, disleg;
    
    	var AC = "AppConstants", uac = `resource://gre/modules/${AC}.`;
    	var lexp = () => lockPref("extensions.experiments.enabled", true);
    	if (o.isFrozen(o)) { // Fx 102.0b7+
    		lexp(); disleg = true;
    		var env, def = g.ChromeUtils.defineModuleGetter;
    		g.ChromeUtils.defineModuleGetter = (...args) => {
    			try {
    				genv();
    				dbg.addDebuggee(globalThis);
    				var e = dbg.getNewestFrame().older.environment;
    				var obj = e.parent.type == "object" && e.parent.object;
    				if (obj && obj.class.startsWith("N")) // JSM, NSVO
    					obj.unsafeDereference().Object = {
    						freeze: ac => (ac.MOZ_REQUIRE_SIGNING = false) || freeze(ac)
    					};
    				else env = e; // ESM, Lexy "var"(?)
    			}
    			catch(ex) {Cu.reportError(ex);}
    			(g.ChromeUtils.defineModuleGetter = def)(...args);
    		}
    		ChromeUtils.import(uac + "jsm");
    		// (?)
    		env && env.setVariable(AC, gref.makeDebuggeeValue(freeze(o.assign(
    			new o(), env.getVariable(AC).unsafeDereference(), {MOZ_REQUIRE_SIGNING: false}
    		))));
    	}
    	else o.freeze = obj => {
    		if (!Components.stack.caller.filename.startsWith(uac)) return freeze(obj);
    		obj.MOZ_REQUIRE_SIGNING = false;
    
    		if ((disleg = "MOZ_ALLOW_ADDON_SIDELOAD" in obj)) lexp();
    		else
    			obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true,
    			lockPref("extensions.legacy.enabled", true);
    
    		return (o.freeze = freeze)(obj);
    	}
    	lockPref("xpinstall.signatures.required", false);
    	lockPref("extensions.langpacks.signatures.required", false);
    
    	var useDbg = true, xpii = "resource://gre/modules/addons/XPIInstall.jsm";
    	if (Ci.nsINativeFileWatcherService) { // Fx < 100
    		jsval = Cu.import(xpii, {});
    		var shouldVerify = jsval.shouldVerifySignedState;
    		if (shouldVerify.length == 1)
    			useDbg = false,
    			jsval.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon);
    	}
    	if (useDbg) {
    		jsval = g.ChromeUtils.import(xpii);
    
    		var env = genv(jsval.XPIInstall.installTemporaryAddon);
    		var ref = name => {try {return env.find(name).getVariable(name).unsafeDereference();} catch {}}
    		jsval.XPIDatabase = (ref("lazy") || {}).XPIDatabase || ref("XPIDatabase");
    
    		var proto = ref("Package").prototype;
    		var verify = proto.verifySignedState;
    		proto.verifySignedState = function(id) {
    			return id ? {cert: null, signedState: undefined} : verify.apply(this, arguments);
    		}
    		dbg.removeAllDebuggees();
    	}
    	if (disleg) jsval.XPIDatabase.isDisabledLegacy = () => false;
    })(
    	"permitCPOWsInScope" in Cu ? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu
    );}
    catch(ex) {Cu.reportError(ex);}

  • Для версии 99 и выше:

    Выделить код

    Код:

    //
    try {(nsvo => {
    	var g = Cu.getGlobalForObject(nsvo), o = g.Object, {freeze} = o, NEW;
    	o.freeze = obj => {
    		if (Components.stack.caller.filename != "resource://gre/modules/AppConstants.jsm")
    			return freeze(obj);
    		obj.MOZ_REQUIRE_SIGNING = false;
    		if ((NEW = "MOZ_ALLOW_ADDON_SIDELOAD" in obj))
    			lockPref("extensions.experiments.enabled", true);
    		else
    			obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true,
    			lockPref("extensions.legacy.enabled", true);
    
    		return (o.freeze = freeze)(obj);
    	}
    	lockPref("xpinstall.signatures.required", false);
    	lockPref("extensions.langpacks.signatures.required", false);
    
    	nsvo = Cu.import("resource://gre/modules/addons/XPIInstall.jsm", {});
    	var shouldVerify = nsvo.shouldVerifySignedState;
    	if (shouldVerify.length == 1)
    		nsvo.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon);
    	else {
    		var {Services} = g.ChromeUtils.import("resource://gre/modules/Services.jsm");
    		var subst = "pkg-proto-patch-tmp-script";
    		var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
    		var func = async proto => Object.assign(proto, eval(
    			`({${proto.verifySignedState}})`.replace("(!", "(addonId || !")
    		));
    		var code = encodeURIComponent(`(${func})(Package.prototype);`);
    		rph.setSubstitution(subst, Services.io.newURI("data:," + code));
    		Services.scriptloader.loadSubScript(`resource://${subst}/`, nsvo);
    		rph.setSubstitution(subst, null);
    	}
    	if (NEW) nsvo.XPIDatabase.isDisabledLegacy = () => false;
    })(
    	"permitCPOWsInScope" in Cu
    		? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu
    );}
    catch(ex) {Cu.reportError(ex);}

    Для версии 60 и выше:

    Выделить код

    Код:

    //
    try {(code => {
        var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
        var jsval, evl = true, re = e => Cu.reportError(e), imp = name => {try {
            return Cu.import(`resource://gre/modules/addons/${name}.jsm`, {});
        } catch(ex) {}}
        if ((jsval = imp("AddonSettings"))) {
            jsval.AddonSettings = {ADDON_SIGNING: false, REQUIRE_SIGNING: false, ALLOW_LEGACY_EXTENSIONS: true};
            try {evl = jsval.eval("this") === jsval;} catch(ex) {evl = false;}
        }
        var jsvals = ["XPIProvider", "XPIInstall"].map(imp).filter(i => i);
        jsvals[0].AddonSettings && lockPref("extensions.allow-non-mpc-extensions", true);
        jsvals[0].signaturesNotRequired = true;
    
        if (evl) return jsvals.forEach(jsval => {try {jsval.eval(code);} catch(ex) {re(ex);}});
    
        var sl = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
        Cu.importGlobalProperties(["URL", "Blob"]); var url = URL.createObjectURL(new Blob([(code)]));
        jsvals.forEach(jsval => {try {sl.loadSubScript(url, jsval);} catch(ex) {re(ex);}});
    
    })(String.raw`((vzss, pckg) => {
        var trueDesc = {enumerable: true, value: true};
        typeof Extension == "function" && Object.defineProperty(Extension.prototype, "experimentsAllowed", trueDesc);
        "AddonInternal" in this && Object.defineProperty(AddonInternal.prototype, "providesUpdatesSecurely", trueDesc);
        this.isDisabledLegacy = () => false;
        if ("XPIDatabase" in this) this.XPIDatabase.isDisabledLegacy = () => false;
        try {SIGNED_TYPES.clear();} catch(ex) {};
    
        if (!vzss && !pckg) return;
    
        var re = /\x06\x03U\x04\x03..(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)0\x82\x02"0\r\x06\t/i;
        var getUUID = () => {
            var gen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
            return (getUUID = () => gen.generateUUID().toString())();
        }
        var getIdFromString = str => {
            var match = str && str.match(re);
            return match ? match[1] : getUUID();
        }
        var getState = arg => ({
            signedState: AddonManager.SIGNEDSTATE_NOT_REQUIRED,
            cert: typeof arg == "object" ? arg : {commonName: arg}
        });
        var checkAddon = addon => {
            if (addon.id || (
                "_installLocation" in addon
                    ? addon._installLocation.name == KEY_APP_TEMPORARY
                    : addon.location.isTemporary
            ))
                return getState(null);
        }
        var getRoot = () =>
            !AppConstants.MOZ_REQUIRE_SIGNING && Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false)
                ? Ci.nsIX509CertDB.AddonsStageRoot : Ci.nsIX509CertDB.AddonsPublicRoot;
    
        if (vzss) {
            var getURI = file => {
                var jsval = Cu.import("resource://gre/modules/addons/XPIProvider.jsm", {});
                return (getURI = file => jsval.getURIForResourceInFile(file, "META-INF/mozilla.rsa"))(file);
            }
            var getIdFromFile = file => {
                var str, is = {close() {}}, sis = {close() {}};
                try {
                    is = Services.io.newChannelFromURIWithLoadInfo(getURI(file), null).open();
                    sis = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
                    sis.init(is);
                    str = sis.readBytes(sis.available());
                } catch(ex) {}
                sis.close(); is.close();
                return getIdFromString(str);
            }
            this.verifyZipSignedState = function verifyZipSignedState(aFile, aAddon) {
                var res = checkAddon(aAddon);
                return res ? Promise.resolve(res) : new Promise(resolve => {
                    var callback = {openSignedAppFileFinished(rv, zipReader, cert) {
                        zipReader && zipReader.close();
                        resolve(getState(cert || getIdFromFile(aFile)));
                    }};
                    gCertDB.openSignedAppFileAsync(getRoot(), aFile, callback.wrappedJSObject = callback);
                });
            }
        }
    
        if (pckg) Package.prototype.verifySignedState = function verifySignedState(addon) {
            var res = checkAddon(addon);
            return res ? Promise.resolve(res) : new Promise(resolve =>
                this.verifySignedStateForRoot(addon, getRoot()).then(({cert}) => {
                    if (cert)
                        resolve(getState(cert));
                    else
                        this.readBinary("META-INF", "mozilla.rsa").then(
                            buffer => resolve(getState(
                                getIdFromString(String.fromCharCode(...new Uint8Array(buffer)))
                            )),
                            () => resolve(getState(getUUID()))
                        );
                }, Cu.reportError)
            );
        }
    })(
        "verifyZipSignedState" in this, typeof Package == "function"
    );`)} catch(err) {
        err.message != "Components is not defined" && Components.utils.reportError(err);
    }

  • Для версий 57-59:

    Выделить код

    Код:

    //
    try {(code => {
        var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
        var jsval, evl = true, re = e => Cu.reportError(e), imp = name => {try {
            return Cu.import(`resource://gre/modules/addons/${name}.jsm`, {});
        } catch(ex) {}}
        if ((jsval = imp("AddonSettings"))) {
            jsval.AddonSettings = {ADDON_SIGNING: false, REQUIRE_SIGNING: false, ALLOW_LEGACY_EXTENSIONS: true};
            try {evl = jsval.eval("this") === jsval;} catch(ex) {evl = false;}
        }
        lockPref("extensions.allow-non-mpc-extensions", true);
        var jsvals = ["XPIProvider", "XPIInstall"].map(imp).filter(i => i);
    
        if (evl) return jsvals.forEach(jsval => {try {jsval.eval(code);} catch(ex) {re(ex);}});
    
        var sl = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
        Cu.importGlobalProperties(["URL", "Blob"]); var url = URL.createObjectURL(new Blob([(code)]));
        jsvals.forEach(jsval => {try {sl.loadSubScript(url, jsval);} catch(ex) {re(ex);}});
    
    })(String.raw`
        try {SIGNED_TYPES.clear();} catch(ex) {};
        "verifyZipSignedState" in this && (signedState => {
            var re = /\x06\x03U\x04\x03\x14[\s\S](\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)0\x82\x02"0\r\x06\t/i;
            var getUUID = () => {
                var gen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
                return (getUUID = () => gen.generateUUID().toString())();
            }
            var getURI = file => {
                var jsval = Cu.import("resource://gre/modules/addons/XPIProvider.jsm", {});
                return (getURI = file => jsval.getURIForResourceInFile(file, "META-INF/mozilla.rsa"))(file);
            }
            var getId = file => {
                var result, is = {close() {}}, sis = {close() {}};
                try {
                    is = Services.io.newChannelFromURIWithLoadInfo(getURI(file), null).open();
                    sis = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
                    sis.init(is); var str = sis.readBytes(sis.available());
                    var match = str.match(re); if (match) result = match[1];
                } catch(ex) {}
                sis.close(); is.close();
                return result || getUUID();
            }
            verifyZipSignedState = function verifyZipSignedState(aFile, aAddon) {
                if (aAddon.id || aAddon._installLocation.name == KEY_APP_TEMPORARY)
                    return Promise.resolve({signedState, cert: null});
                var root = !AppConstants.MOZ_REQUIRE_SIGNING && Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false)
                    ? Ci.nsIX509CertDB.AddonsStageRoot : Ci.nsIX509CertDB.AddonsPublicRoot;
                return new Promise(resolve => {
                    var callback = {openSignedAppFileFinished(rv, zipReader, cert) {
                        zipReader && zipReader.close();
                        resolve({signedState, cert: cert || {commonName: getId(aFile)}});
                    }};
                    gCertDB.openSignedAppFileAsync(root, aFile, callback.wrappedJSObject = callback);
                });
            }
        })(AddonManager.SIGNEDSTATE_NOT_REQUIRED);
    `)} catch(err) {Components.utils.reportError(err);}

  • Для версий 55 и 56:

    Выделить код

    Код:

    //
    ["Provider", "Install"].forEach(name => {try {
        Components.utils.import(`resource://gre/modules/addons/XPI${name}.jsm`, {})
            .eval("SIGNED_TYPES.clear(); this;").eval(String.raw`"verifyZipSignedState" in this && (uuidg => {
                var signedState = AddonManager.SIGNEDSTATE_NOT_REQUIRED;
                var re = /\x06\x03U\x04\x03\x14[\s\S](\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)0\x82\x02"0\r\x06\t/i;
                var bsp = Cu.getGlobalForObject(XPIProvider), til = bsp.eval("TemporaryInstallLocation");
                var getId = file => {
                    var result, is = {close() {}}, sis = {close() {}};
                    var uri = bsp.getURIForResourceInFile(file, "META-INF/mozilla.rsa");
                    try {
                        is = Services.io.newChannelFromURIWithLoadInfo(uri, null).open();
                        sis = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
                        sis.init(is); var str = sis.readBytes(sis.available());
                        var match = str.match(re); if (match) result = match[1];
                    } catch(ex) {}
                    sis.close(); is.close();
                    return result || uuidg.generateUUID().toString();
                }
                verifyZipSignedState = function verifyZipSignedState(aFile, aAddon) {
                    if (aAddon.id || aAddon._installLocation == til)
                        return Promise.resolve({signedState, cert: null});
                    var root = !AppConstants.MOZ_REQUIRE_SIGNING && Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false)
                        ? Ci.nsIX509CertDB.AddonsStageRoot : Ci.nsIX509CertDB.AddonsPublicRoot;
                    return new Promise(resolve => {
                        var callback = {openSignedAppFileFinished(rv, zipReader, cert) {
                            zipReader && zipReader.close();
                            resolve({signedState, cert: cert || {commonName: getId(aFile)}});
                        }};
                        gCertDB.openSignedAppFileAsync(root, aFile, callback.wrappedJSObject = callback);
                    });
                }
            })(Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator));`);
    } catch(ex) {}});

  • Для версии 54 и ниже:

    Выделить код

    Код:

    //
    try {
    Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {})
    .eval("SIGNED_TYPES.clear()");
    }
    catch(ex) {}

переименуйте его в config.js (js - вместо txt, переименуйте расширение) и перенесите в папку установки Firefox: C:\Program Files\Mozilla Firefox

Создайте ещё один текстовый файл:

  • Для версии 62 и выше:

    Выделить код

    Код:

    pref("general.config.obscure_value", 0);
    pref("general.config.filename", "config.js");
    pref("general.config.sandbox_enabled", false);

  • Для версии 61 и ниже:

    Выделить код

    Код:

    pref("general.config.obscure_value", 0);
    pref("general.config.filename", "config.js");

    переименуйте его в config-prefs.js и перенесите в папку: C:\Program Files\Mozilla Firefox\defaults\pref

Kyogre пишет

при наличии этих двух файлов присутствует и отрицательный эффект - невозможно установить/обновить некоторые расширения и Firefox выдает ошибку "это дополнение не может быть установлено так как оно по-видимому повреждено". При возникновении этой ошибки закройте Firefox, удалите эти два файла (предварительно сделайте резервную копию файлов!) и запустите Firefox. Установите нужное вам дополнение, закройте Firefox и верните эти файлы обратно в папки.

lbfgnmabdq пишет

Ошибка при установке некоторых дополнений бывает также такая "Download failed. Please check your connection.".
digisingerr.jpg
При убирании файлов config-prefs.js и config.js ошибка пропадает, и дополнение успешно устанавливается. Проверялось на Firefox 52.9 ESR.


Do you feel lucky, punk?

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]