0

我正在嘗試做一個擴展,將與本機通訊主機chrome-token-signing溝通。我使用金雅拓智能卡讀卡器。我安裝了擴展,當我退出或放入任何字符串時,它會返回一個cmd窗口。我有消息日誌TEST: ERROR {"message":"Error when communicating with the native messaging host."} 我需要做一些事情 我已經安裝在註冊表中的主機像HKEY_LOCAL_MACHINE\software\Google\Chrome\NativeMessagingHosts\ee.ria.esteid和價值C:\Users\dev\Desktop\chrome-token-signing\host-windows\ee.ria.esteid.json鉻標記簽署擴展

原生應用的manifest.json:

{ 
"name": "ee.ria.esteid", 
"description": "Give signatures with your eID on the web", 
"path": "chrome-token-signing.exe", 
"type": "stdio", 
"allowed_origins": [ 
"chrome-extension://ckjefchnfjhjfedoccjbhjpbncimppeg/" 
] 
} 

的manifest.json的延伸 {

"name": "Token signing", 
    "version": "0.0.24", 
    "minimum_chrome_version": "40.0", 
    "manifest_version": 2, 
    "description": "Use your eID smart card on the web", 
    "icons": { 
    "48": "icon48.png", 
    "128": "icon128.png" 
    }, 
    "content_scripts": [{ 
    "matches": ["*://*/*", "file:///*"], 
    "exclude_matches": ["*://www.overdrive.com/*"], 
    "js": ["content.js"], 
    "run_at": "document_end", 
    "all_frames": true 
    }], 
    "background": { 
    "scripts": ["background.js"] 
    }, 
    "permissions": ["nativeMessaging"], 
    "applications": { 
    "gecko": { 
    "id": "{443830f0-1fff-4f9a-aa1e-444bafbc7319}" 
    } 
    } 
    } 

background.js

var NO_NATIVE_URL = "https://open-eid.github.io/chrome-token- signing/missing.html"; 

var HELLO_URL = "https://open-eid.github.io/chrome-token-signing/hello.html"; 

    var DEVELOPER_URL = "https://github.com/open-eid/chrome-token- signing/wiki/DeveloperTips"; 

    var NATIVE_HOST = "ee.ria.esteid"; 

    var K_SRC = "src"; 
    var K_ORIGIN = "origin"; 
    var K_NONCE = "nonce"; 
    var K_RESULT = "result"; 
    var K_TAB = "tab"; 
    var K_EXTENSION = "extension"; 

    // Stores the longrunning ports per tab 
    // Used to route all request from a tab to the same host instance 
    var ports = {}; 

    // Probed to false if host component is OK. 
    var missing = true; 

    console.log("Background page activated"); 

    // XXX: probe test, because connectNative() does not allow to check the presence 
    // of native component for some reason 
     typeof chrome.runtime.onStartup !== 'undefined' &&  chrome.runtime.onStartup.addListener(function() { 
    // Also probed for in onInstalled() 
    _testNativeComponent().then(function(result) { 
if (result === "ok") { 
    missing = false; 
} 
    }); 
    }); 
    // Force kill of native process 
    // Becasue Port.disconnect() does not work 
    function _killPort(tab) { 
    if (tab in ports) { 
    console.log("KILL " + tab); 
    // Force killing with an empty message 
    ports[tab].postMessage({}); 
} 
} 

    // Check if native implementation is OK resolves with "ok", "missing" or "forbidden" 
    function _testNativeComponent() { 
    return new Promise(function(resolve, reject) { 
chrome.runtime.sendNativeMessage(NATIVE_HOST, {}, function(response) { 
    if (!response) { 
     console.log("TEST: ERROR " + JSON.stringify(chrome.runtime.lastError)); 
     // Try to be smart and do some string matching 
     var permissions = "Access to the specified native messaging host is forbidden."; 
     var missing = "Specified native messaging host not found."; 
     if (chrome.runtime.lastError.message === permissions) { 
      resolve("forbidden") 
     } else if (chrome.runtime.lastError.message === missing) { 
      resolve("missing"); 
     } else { 
      resolve("missing"); 
     } 
    } else { 
     console.log("TEST: " + JSON.stringify(response)); 
     if (response["result"] === "invalid_argument") { 
      resolve("ok"); 
     } else { 
      resolve("missing"); // TODO: something better here 
     } 
    } 
     }); 
     }); 
     } 

    // When extension is installed, check for native component or direct to helping page 
    typeof chrome.runtime.onInstalled !== 'undefined' && chrome.runtime.onInstalled.addListener(function(details) { 
    if (details.reason === "install" || details.reason === "update") { 
_testNativeComponent().then(function(result) { 
     var url = null; 
     if (result === "ok" && details.reason === "install") { 
      // Also set the flag, onStartup() shall be called only 
      // on next startup 
      missing = false; 
      // TODO: Add back HELLO page on install 
      // once there is a nice tutorial 
      url = HELLO_URL; 
     } else if (result === "forbidden") { 
      url = DEVELOPER_URL; 
     } else if (result === "missing"){ 
      url = NO_NATIVE_URL; 
     } 
     if (url) { 
      chrome.tabs.create({'url': url + "?" + details.reason}); 
     } 
     }); 
      } 
      }); 
    // When message is received from page send it to native 
    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { 
if(sender.id !== chrome.runtime.id && sender.extensionId !== chrome.runtime.id) { 
console.log('WARNING: Ignoring message not from our extension'); 
// Not our extension, do nothing 
return; 
} 
if (sender.tab) { 
// Check if page is DONE and close the native component without doing anything else 
if (request["type"] === "DONE") { 
    console.log("DONE " + sender.tab.id); 
    if (sender.tab.id in ports) { 
     // FIXME: would want to use Port.disconnect() here 
     _killPort(sender.tab.id); 
    } 
} else { 
    request[K_TAB] = sender.tab.id; 
    if (missing) { 
     _testNativeComponent().then(function(result) { 
      if (result === "ok") { 
       missing = false; 
       _forward(request); 
      } else { 
       return _fail_with (request, "no_implementation"); 
      } 
     }); 
    } else { 
     // TODO: Check if the URL is in allowed list or not 
     // Either way forward to native currently 
     _forward(request); 
    } 
} 
} 
    }); 

// Send the message back to the originating tab 
function _reply(tab, msg) { 
msg[K_SRC] = "background.js"; 
msg[K_EXTENSION] = chrome.runtime.getManifest().version; 
chrome.tabs.sendMessage(tab, msg); 
} 

// Fail an incoming message if the underlying implementation is not 
    // present 
    function _fail_with(msg, result) { 
var resp = {}; 
resp[K_NONCE] = msg[K_NONCE]; 
resp[K_RESULT] = result; 
_reply(msg[K_TAB], resp); 
    } 
// Forward a message to the native component 
function _forward(message) { 
    var tabid = message[K_TAB]; 
console.log("SEND " + tabid + ": " + JSON.stringify(message)); 
// Open a port if necessary 
    if(!ports[tabid]) { 
// For some reason there does not seem to be a way to detect missing components from longrunning ports 
// So we probe before opening a new port. 
console.log("OPEN " + tabid + ": " + NATIVE_HOST); 
// create a new port 
var port = chrome.runtime.connectNative(NATIVE_HOST); 
// XXX: does not indicate anything for some reason. 
if (!port) { 
    console.log("OPEN ERROR: " + JSON.stringify(chrome.runtime.lastError)); 
} 
port.onMessage.addListener(function(response) { 
    if (response) { 
     console.log("RECV "+tabid+": " + JSON.stringify(response)); 
     _reply(tabid, response); 
    } else { 
     console.log("ERROR "+tabid+": " + JSON.stringify(chrome.runtime.lastError)); 
     _fail_with(message, "technical_error"); 
    } 
}); 
port.onDisconnect.addListener(function() { 
    console.log("QUIT " + tabid); 
    delete ports[tabid]; 
    // TODO: reject all pending promises for tab, if any 
}); 
ports[tabid] = port; 
ports[tabid].postMessage(message); 
} else { 
// Port already open 
ports[tabid].postMessage(message); 
} 
    } 

content.js

/* 
* Chrome token signing extension 
* 
* This library is free software; you can redistribute it and/or 
* modify it under the terms of the GNU Lesser General Public 
* License as published by the Free Software Foundation; either 
* version 2.1 of the License, or (at your option) any later version. 
* 
* This library is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
* Lesser General Public License for more details. 
* 
* You should have received a copy of the GNU Lesser General Public 
* License along with this library; if not, write to the Free Software 
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
*/ 
var inuse = false; 
    // Forward the message from page.js to background.js 
    window.addEventListener("message", function(event) { 
// We only accept messages from ourselves 
if (event.source !== window) 
    return; 

// and forward to extension 
if (event.data.src && (event.data.src === "page.js")) { 
    event.data["origin"] = location.origin; 
    chrome.runtime.sendMessage(event.data, function(response) {}); 

    // Only add unload handler if extension has been used 
    if (!inuse) { 
     // close the native component if page unloads 
     window.addEventListener("beforeunload", function(event) { 
      chrome.runtime.sendMessage({src: 'page.js', type: 'DONE'}); 
     }, false); 
     inuse = true; 
    } 
} 
    }, false); 

// post messages from extension to page 
    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { 
window.postMessage(request, '*'); 
}); 

// inject content of page.js to the DOM of every page 
// FIXME: maybe not ? 
var s = document.createElement('script'); 
s.type = 'text/javascript'; 
s.innerHTML='// Promises \n\ 
var _eid_promises = {}; \n\ 
// Turn the incoming message from extension \n\ 
// into pending Promise resolving \n\ 
window.addEventListener("message", function(event) { \n\ 
if(event.source !== window) return; \n\ 
if(event.data.src && (event.data.src === "background.js")) { \n\ 
    console.log("Page received: "); \n\ 
    console.log(event.data); \n\ 
    // Get the promise \n\ 
    if(event.data.nonce) { \n\ 
     var p = _eid_promises[event.data.nonce]; \n\ 
     // resolve \n\ 
     if(event.data.result === "ok") { \n\ 
      if(event.data.signature !== undefined) { \n\ 
       p.resolve({hex: event.data.signature}); \n\ 
      } else if(event.data.version !== undefined) { \n\ 
       p.resolve(event.data.extension + "/" + event.data.version); \n\ 
      } else if(event.data.cert !== undefined) { \n\ 
       p.resolve({hex: event.data.cert}); \n\ 
      } else { \n\ 
       console.log("No idea how to handle message"); \n\ 
       console.log(event.data); \n\ 
      } \n\ 
     } else { \n\ 
      // reject \n\ 
      p.reject(new Error(event.data.result)); \n\ 
     } \n\ 
     delete _eid_promises[event.data.nonce]; \n\ 
    } else { \n\ 
     console.log("No nonce in event msg"); \n\ 
    } \n\ 
} \n\ 
}, false); \n\ 
\n\ 
\n\ 
function TokenSigning() { \n\ 
function nonce() { \n\ 
    var val = ""; \n\ 
    var hex = "abcdefghijklmnopqrstuvwxyz"; \n\ 
    for(var i = 0; i < 16; i++) val += hex.charAt(Math.floor(Math.random() * hex.length)); \n\ 
    return val; \n\ 
} \n\ 
\n\ 
function messagePromise(msg) { \n\ 
    return new Promise(function(resolve, reject) { \n\ 
     // amend with necessary metadata \n\ 
     msg["nonce"] = nonce(); \n\ 
     msg["src"] = "page.js"; \n\ 
     // send message \n\ 
     window.postMessage(msg, "*"); \n\ 
     // and store promise callbacks \n\ 
     _eid_promises[msg.nonce] = { \n\ 
      resolve: resolve, \n\ 
      reject: reject \n\ 
     }; \n\ 
    }); \n\ 
    } \n\ 
this.getCertificate = function(options) { \n\ 
    var msg = {type: "CERT", lang: options.lang}; \n\ 
    console.log("getCertificate()"); \n\ 
    return messagePromise(msg); \n\ 
}; \n\ 
this.sign = function(cert, hash, options) { \n\ 
    var msg = {type: "SIGN", cert: cert.hex, hash: hash.hex, hashtype: hash.type, lang: options.lang}; \n\ 
    console.log("sign()"); \n\ 
    return messagePromise(msg); \n\ 
}; \n\ 
this.getVersion = function() { \n\ 
    console.log("getVersion()"); \n\ 
    return messagePromise({ \n\ 
     type: "VERSION" \n\ 
    }); \n\ 
}; \n\ 
}'; 
    (document.head || document.documentElement).appendChild(s); 

page.js

/* 
    * Chrome token signing extension 
    * 
    * This library is free software; you can redistribute it and/or 
    * modify it under the terms of the GNU Lesser General Public 
    * License as published by the Free Software Foundation; either 
    * version 2.1 of the License, or (at your option) any later version. 
    * 
    * This library is distributed in the hope that it will be useful, 
    * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
    * Lesser General Public License for more details. 
    * 
    * You should have received a copy of the GNU Lesser General Public 
    * License along with this library; if not, write to the Free Software 
    * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
    */ 
    // Promises 
    var _eid_promises = {}; 
    // Turn the incoming message from extension 
    // into pending Promise resolving 
    window.addEventListener("message", function(event) { 
if(event.source !== window) return; 
if(event.data.src && (event.data.src === "background.js")) { 
    console.log("Page received: "); 
    console.log(event.data); 
    // Get the promise 
    if(event.data.nonce) { 
     var p = _eid_promises[event.data.nonce]; 
     // resolve 
     if(event.data.result === "ok") { 
      if(event.data.signature !== undefined) { 
       p.resolve({hex: event.data.signature}); 
      } else if(event.data.version !== undefined) { 
       p.resolve(event.data.extension + "/" + event.data.version); 
      } else if(event.data.cert !== undefined) { 
       p.resolve({hex: event.data.cert}); 
      } else { 
       console.log("No idea how to handle message"); 
       console.log(event.data); 
      } 
     } else { 
      // reject 
      p.reject(new Error(event.data.result)); 
     } 
     delete _eid_promises[event.data.nonce]; 
    } else { 
     console.log("No nonce in event msg"); 
    } 
} 
    }, false); 
function TokenSigning() { 
function nonce() { 
    var val = ""; 
    var hex = "abcdefghijklmnopqrstuvwxyz"; 
    for(var i = 0; i < 16; i++) val += hex.charAt(Math.floor(Math.random() * hex.length)); 
    return val; 
} 

function messagePromise(msg) { 
    return new Promise(function(resolve, reject) { 
     // amend with necessary metadata 
     msg["nonce"] = nonce(); 
     msg["src"] = "page.js"; 
     // send message 
     window.postMessage(msg, "*"); 
     // and store promise callbacks 
     _eid_promises[msg.nonce] = { 
      resolve: resolve, 
      reject: reject 
     }; 
    }); 
} 
this.getCertificate = function(options) { 
    var msg = {type: "CERT", lang: options.lang}; 
    console.log("getCertificate()"); 
    return messagePromise(msg); 
}; 
this.sign = function(cert, hash, options) { 
    var msg = {type: "SIGN", cert: cert.hex, hash: hash.hex, hashtype: hash.type, lang: options.lang}; 
    console.log("sign()"); 
    return messagePromise(msg); 
}; 
this.getVersion = function() { 
    console.log("getVersion()"); 
    return messagePromise({ 
     type: "VERSION" 
    }); 
}; 
    } 

當我運行擴展我: enter image description here

當我whrite somethig或點擊2次,輸入觸摸或關閉CMD我有這樣的:enter image description here

+0

安裝擴展後,你的瀏覽器會自動打開一個網頁? github.com的一個頁面應該打開。 – kundrata

+0

是的,我有這個網頁:https://open-eid.github.io/chrome-token-signing/missing.html?update –

+0

你可以看看chrome:// extensions /的背景頁面日誌,並在這裏粘貼什麼是說? – kundrata

回答

0

我有這樣一個enter image description here

,當我點擊調用標誌我有徵(+)卡嗒一聲在簽署SHA-256:413140d54372f9baf481d4c54e2d5c7bcf28fd6087000280e07976121dd54af2和cmd窗口出現這樣enter image description here

當我關閉CMD我有這樣一個

enter image description here 當我把任何東西放在cmd我有這樣的一個enter image description here