麻烦编写Firefox添加(注册观察员,Javascript)



我正在为firefox编写一个插件,但是我似乎在通道方面有一些问题。我正试图写一个程序,接收一个网站的证书信息,并保存在一个特定的格式。它没有收集到我需要的信息。下面是我的代码:(抱歉在那里放了很多东西,但这都是必要的。)

 const {Cc,Ci,Cu} = require("chrome");
 let console = (Cu.import("resource://gre/modules/devtools/Console.jsm", {})).console;
 console.log("Importing console.n");
 // Cu.import("resource://gre/modules/XPCOMUtils.jsm");
this._loadHandler = function(e) {myExtension.onPageLoad(e); };
var utils = require('sdk/window/utils');
var gBrowser = utils.getMostRecentBrowserWindow().getBrowser();
gBrowser.addEventListener("load", this._loadHandler, true);
// We register an observer on page load, through page load event listener. Is this round-about?
//  Can we register it directly?
var myExtension = {
onPageLoad: function(aEvent) {
var doc = aEvent.originalTarget; // doc is document that triggered "onload" event
var i = 0;
console.log("Page has been loaded.n");
this.registerObserver("http-on-examine-response");
this.initialized = true;
},
onPageUnload: function(aEvent) {
    console.log("Page has been unloaded.n");
    this.unregisterObserver("http-on-examine-response");
},
registerObserver: function(topic) {
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(this, topic, false);
console.log("Observer Registered.n");
},
unregisterObserver: function(topic) {
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.removeObserver(this, topic);
console.log("Observer Unregistered.n");
},
//Observation Function
observe: function(channel, topic, data) {
console.log("Running Observe....n");
this.examine_cert(channel);
},
examine_cert: function(channel) {
channel.QueryInterface(Ci.nsIHttpChannel);
//Assigns the channel of the http resource in the host port
var host = channel.URI.hostPort;
//Checks for security info
var si = channel.securityInfo;
if (!si){
    console.log("No securityInfo for "+ host +" , returningn");
    return;
}
//Gets Certificates status
si.QueryInterface(Ci.nsISSLStatusProvider);
var st = si.SSLStatus;
if (!st){
    console.log(st + "n");
    console.log("No SSLStatus for "+ host +" , returningn");
    return; 
}
st.QueryInterface(Ci.nsISSLStatus);
var cert = st.serverCert;
if (!cert){
    console.log("No serverCert for "+ host +" , returningn");
    return;
}
// by now we must have a non-empty cert, print it and the status
console.log( "status: " + st + "n");
console.log( "cert  : " + cert.commonName + "n");
//certobj.ciphername = st.cipherName;  // apparently, parsed out of cert when SSLStatus is made
//certobj.keyLength = st.keyLength;
//certobj.secretKeyLength = st.secretKeyLength;
},
// Recursively descend into the object, looking for displayName matching re;
//   also, validate objects as we go.
findASN1Object: function (struc, re) {
    if (!struc){
        console.log("nCertificate does not have a valid structure.n");
        return;
    }
// Shortcut: object with displayName matching re found, return it immediately
    if (re.test(struc.displayName)) return struc;
    var s = Ci;
    try {
        s = struc.QueryInterface(Ci.nsIASN1Sequence);
    }
    catch (e) {
    console.log("nCertificate failed nsIASN1Sequence conversionn");
}
    if ( !s || ! s.isValidContainer) {
        console.log("nCertificate does not have a valid container.n");
        return;
    }
// check all the objects recursively
    for (var i=0; i<s.ASN1Objects.length; i++) {
        struc = s.ASN1Objects.queryElementAt(i, Ci.nsIASN1Object);
        var res = this.findASN1Object(struc, re);
        if (res) return res;
    }
},
//------ Object containment:
//   nsIHttpChannel > securityInfo (nsISSLStatusProvider) > SSLStatus (nsISSLStatus) > serverCert (nsIX509Cert) 

fillCertObj: function(obj, cert) {
    obj.cert = cert;
    console.log("nCert:" + cert + "n");
    obj.notBefore = cert.validity.notBefore;
    obj.notAfter = cert.validity.notAfter;
    if (cert.issuer) {
        obj.issuerMd5Fingerprint = cert.issuer.md5Fingerprint;
        obj.issuerSha1Fingerprint = cert.issuer.sha1Fingerprint;
    } 
else {
        //console.log("no issuer: "+ [cert.commonName, cert.issuer, cert.sha1Fingerprint]); 
    console.log("nThe Certificate doesn't have an Issuer.n");
    }
    var keys = ["commonName", "organization", "organizationalUnit", "serialNumber","emailAddress",
                "issuerCommonName", "issuerOrganization", "issuerOrganizationUnit","md5Fingerprint", "sha1Fingerprint" ];
    for (var i in keys){
        obj[keys[i]] = cert[keys[i]];
    }
    obj.subjectAltName = [];
    var san = this.findASN1Object(cert.ASN1Structure, /^Certificate Subject Alt Name$/);
    if (san) {
        //this.log("SAN:", [san.displayName, san.displayValue]); 
        var m, re = /DNS Name: ((?:*.)?[a-z0-9.-]+)/g;
    //                       *.smth1.smth2.smth3....smthn where smth has only a-z,0-9,or -   or
    //                       smth1.smth2.smth3....smthn where smth has only a-z,0-9,or -  
    // push domain names contained in displayValue onto the list subjectAltName
    while (m = re.exec(san.displayValue))
    obj.subjectAltName.push(m[1]);
    }
console.log("Filled Certificate.n");
},
init_cert: function(){ 
var certobj = this.newCertObj();
//certobj.host = host;
//certobj.ciphername = st.cipherName;
//certobj.keyLength = st.keyLength;
//certobj.secretKeyLength = st.secretKeyLength;
//this.fillCertObj(certobj.now, cert);
console.log(certobj);
},
newCertObj: function() { 
console.log("Creating Empty Certificate.n");
    return {
    flags: 0,
    host: "",
    warn: {},
    now: {
            commonName: "",
        organization: "",
        organizationalUnit: "",
        serialNumber: "",
        emailAddress: "",
        notBefore: "",
        notAfter: "",
        issuerCommonName: "",
        issuerOrganization: "",
        issuerOrganizationUnit: "",
        md5Fingerprint: "",
        sha1Fingerprint: "",
        issuerMd5Fingerprint: "",
        issuerSha1Fingerprint: "",
        cert: null,
        },
    old: {
            commonName: "",
        organization: "",
        organizationalUnit: "",
        serialNumber: "",
        emailAddress: "",
        notBefore: "",
        notAfter: "",
        issuerCommonName: "",
        issuerOrganization: "",
        issuerOrganizationUnit: "",
        md5Fingerprint: "",
        sha1Fingerprint: "",
        issuerMd5Fingerprint: "",
        issuerSha1Fingerprint: "",
        cert: null,
        },
    };
},

}

在页面加载时注册和取消注册observer是不明智的,因为它会从任何地方捕获http请求。所以在启动插件时注册它,在关闭/卸载插件时注销它。

你应该检查loadContext,看看是哪个窗口/标签/框架/ajax/背景发出请求。有关loadContext的更多信息,请参阅此处:https://stackoverflow.com/a/25223307/1828637

但是无论如何,这应该按照你的方式工作意思是页面加载时使用reg页面卸载时使用unreg页面

 const {
    Cc, Ci, Cu
 } = require("chrome");
 let console = (Cu.import("resource://gre/modules/devtools/Console.jsm", {})).console;
 console.log("Importing console.n");
 // Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 this._loadHandler = function(e) {
    myExtension.onPageLoad(e);
 };
 var utils = require('sdk/window/utils');
 var gBrowser = utils.getMostRecentBrowserWindow().getBrowser();
 gBrowser.addEventListener("load", this._loadHandler, true);
 // We register an observer on page load, through page load event listener. Is this round-about?
 //  Can we register it directly?
 var myExtension = {
    observers: {
        'http-on-examine-response': {
            observe: function(aSubject, aTopic, aData) {
                console.log("Running Observe....n");
                myExtension.examine_cert(aSubject);
            },
            reg: function() {
                Services.obs.addObserver(myExtension.observers['http-on-examine-response'], 'http-on-examine-response', false);
            },
            unreg: function() {
                Services.obs.removeObserver(myExtension.observers['http-on-examine-response'], 'http-on-examine-response');
            }
        }
    },
    onPageLoad: function(aEvent) {
        var doc = aEvent.originalTarget; // doc is document that triggered "onload" event
        var i = 0;
        console.log("Page has been loaded.n");
        myExtension.observers['http-on-examine-response'].reg();
        this.initialized = true;
    },
    onPageUnload: function(aEvent) {
        console.log("Page has been unloaded.n");
        myExtension.observers['http-on-examine-response'].unreg();
    },
    examine_cert: function(channel) {
        channel.QueryInterface(Ci.nsIHttpChannel);
        //Assigns the channel of the http resource in the host port
        var host = channel.URI.hostPort;
        //Checks for security info
        var si = channel.securityInfo;
        if (!si) {
            console.log("No securityInfo for " + host + " , returningn");
            return;
        }
        //Gets Certificates status
        si.QueryInterface(Ci.nsISSLStatusProvider);
        var st = si.SSLStatus;
        if (!st) {
            console.log(st + "n");
            console.log("No SSLStatus for " + host + " , returningn");
            return;
        }
        st.QueryInterface(Ci.nsISSLStatus);
        var cert = st.serverCert;
        if (!cert) {
            console.log("No serverCert for " + host + " , returningn");
            return;
        }
        // by now we must have a non-empty cert, print it and the status
        console.log("status: " + st + "n");
        console.log("cert  : " + cert.commonName + "n");
        //certobj.ciphername = st.cipherName;  // apparently, parsed out of cert when SSLStatus is made
        //certobj.keyLength = st.keyLength;
        //certobj.secretKeyLength = st.secretKeyLength;
    },
    // Recursively descend into the object, looking for displayName matching re;
    //   also, validate objects as we go.
    findASN1Object: function(struc, re) {
        if (!struc) {
            console.log("nCertificate does not have a valid structure.n");
            return;
        }
        // Shortcut: object with displayName matching re found, return it immediately
        if (re.test(struc.displayName)) return struc;
        var s = Ci;
        try {
            s = struc.QueryInterface(Ci.nsIASN1Sequence);
        } catch (e) {
            console.log("nCertificate failed nsIASN1Sequence conversionn");
        }
        if (!s || !s.isValidContainer) {
            console.log("nCertificate does not have a valid container.n");
            return;
        }
        // check all the objects recursively
        for (var i = 0; i < s.ASN1Objects.length; i++) {
            struc = s.ASN1Objects.queryElementAt(i, Ci.nsIASN1Object);
            var res = this.findASN1Object(struc, re);
            if (res) return res;
        }
    },
    //------ Object containment:
    //   nsIHttpChannel > securityInfo (nsISSLStatusProvider) > SSLStatus (nsISSLStatus) > serverCert (nsIX509Cert) 

    fillCertObj: function(obj, cert) {
        obj.cert = cert;
        console.log("nCert:" + cert + "n");
        obj.notBefore = cert.validity.notBefore;
        obj.notAfter = cert.validity.notAfter;
        if (cert.issuer) {
            obj.issuerMd5Fingerprint = cert.issuer.md5Fingerprint;
            obj.issuerSha1Fingerprint = cert.issuer.sha1Fingerprint;
        } else {
            //console.log("no issuer: "+ [cert.commonName, cert.issuer, cert.sha1Fingerprint]); 
            console.log("nThe Certificate doesn't have an Issuer.n");
        }
        var keys = ["commonName", "organization", "organizationalUnit", "serialNumber", "emailAddress",
            "issuerCommonName", "issuerOrganization", "issuerOrganizationUnit", "md5Fingerprint", "sha1Fingerprint"
        ];
        for (var i in keys) {
            obj[keys[i]] = cert[keys[i]];
        }
        obj.subjectAltName = [];
        var san = this.findASN1Object(cert.ASN1Structure, /^Certificate Subject Alt Name$/);
        if (san) {
            //this.log("SAN:", [san.displayName, san.displayValue]); 
            var m, re = /DNS Name: ((?:*.)?[a-z0-9.-]+)/g;
            //                       *.smth1.smth2.smth3....smthn where smth has only a-z,0-9,or -   or
            //                       smth1.smth2.smth3....smthn where smth has only a-z,0-9,or -  
            // push domain names contained in displayValue onto the list subjectAltName
            while (m = re.exec(san.displayValue))
                obj.subjectAltName.push(m[1]);
        }
        console.log("Filled Certificate.n");
    },
    init_cert: function() {
        var certobj = this.newCertObj();
        //certobj.host = host;
        //certobj.ciphername = st.cipherName;
        //certobj.keyLength = st.keyLength;
        //certobj.secretKeyLength = st.secretKeyLength;
        //this.fillCertObj(certobj.now, cert);
        console.log(certobj);
    },
    newCertObj: function() {
        console.log("Creating Empty Certificate.n");
        return {
            flags: 0,
            host: "",
            warn: {},
            now: {
                commonName: "",
                organization: "",
                organizationalUnit: "",
                serialNumber: "",
                emailAddress: "",
                notBefore: "",
                notAfter: "",
                issuerCommonName: "",
                issuerOrganization: "",
                issuerOrganizationUnit: "",
                md5Fingerprint: "",
                sha1Fingerprint: "",
                issuerMd5Fingerprint: "",
                issuerSha1Fingerprint: "",
                cert: null,
            },
            old: {
                commonName: "",
                organization: "",
                organizationalUnit: "",
                serialNumber: "",
                emailAddress: "",
                notBefore: "",
                notAfter: "",
                issuerCommonName: "",
                issuerOrganization: "",
                issuerOrganizationUnit: "",
                md5Fingerprint: "",
                sha1Fingerprint: "",
                issuerMd5Fingerprint: "",
                issuerSha1Fingerprint: "",
                cert: null,
            },
        };
    },
 }

最后,为什么要在伪类myExtension中包装?当做插件sdk或引导插件时,你不必再这样做了。

让事情变得更简单,这样你就不必跟踪你所处的范围了。

最新更新