From ddbbc6e53dfb98d48b37467ea97c87339cd32380 Mon Sep 17 00:00:00 2001 From: Garner Lee Date: Wed, 27 Aug 2014 14:41:00 +0200 Subject: [PATCH] Bug 979767 - Part 1: Messages and Permissions. Supporting web application triggering based on HCI event EVT_TRANSACTION. r=fabrice --- b2g/installer/package-manifest.in | 2 + dom/apps/src/PermissionsTable.jsm | 5 + .../SystemMessagePermissionsChecker.jsm | 3 + .../HCIEventTransactionSystemMessage.manifest | 2 + ...entTransactionSystemMessageConfigurator.js | 114 ++++++++++++++++++ dom/nfc/moz.build | 2 + 6 files changed, 128 insertions(+) create mode 100644 dom/nfc/messages/HCIEventTransactionSystemMessage.manifest create mode 100644 dom/nfc/messages/HCIEventTransactionSystemMessageConfigurator.js diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 04cd74b9ad1..1636ed37f49 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -563,6 +563,8 @@ @BINPATH@/components/SystemMessageInternal.js @BINPATH@/components/SystemMessageManager.js @BINPATH@/components/SystemMessageManager.manifest +@BINPATH@/components/HCIEventTransactionSystemMessage.manifest +@BINPATH@/components/HCIEventTransactionSystemMessageConfigurator.js @BINPATH@/components/Activities.manifest @BINPATH@/components/ActivityProxy.js diff --git a/dom/apps/src/PermissionsTable.jsm b/dom/apps/src/PermissionsTable.jsm index d40a2810f49..f648ca4996d 100644 --- a/dom/apps/src/PermissionsTable.jsm +++ b/dom/apps/src/PermissionsTable.jsm @@ -354,6 +354,11 @@ this.PermissionsTable = { geolocation: { privileged: DENY_ACTION, certified: ALLOW_ACTION }, + "nfc-hci-events": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, "speaker-control": { app: DENY_ACTION, privileged: ALLOW_ACTION, diff --git a/dom/messages/SystemMessagePermissionsChecker.jsm b/dom/messages/SystemMessagePermissionsChecker.jsm index 6cc8a819da9..ffdf2c45cc1 100644 --- a/dom/messages/SystemMessagePermissionsChecker.jsm +++ b/dom/messages/SystemMessagePermissionsChecker.jsm @@ -108,6 +108,9 @@ this.SystemMessagePermissionsTable = { "cdma-info-rec-received": { "mobileconnection": [] }, + "nfc-hci-event-transaction": { + "nfc-hci-events": [] + }, "nfc-manager-tech-discovered": { "nfc-manager": [] }, diff --git a/dom/nfc/messages/HCIEventTransactionSystemMessage.manifest b/dom/nfc/messages/HCIEventTransactionSystemMessage.manifest new file mode 100644 index 00000000000..a8ed858a134 --- /dev/null +++ b/dom/nfc/messages/HCIEventTransactionSystemMessage.manifest @@ -0,0 +1,2 @@ +component {b501edd0-28bd-11e4-8c21-0800200c9a66} HCIEventTransactionSystemMessageConfigurator.js +contract @mozilla.org/dom/system-messages/configurator/nfc-hci-event-transaction;1 {b501edd0-28bd-11e4-8c21-0800200c9a66} diff --git a/dom/nfc/messages/HCIEventTransactionSystemMessageConfigurator.js b/dom/nfc/messages/HCIEventTransactionSystemMessageConfigurator.js new file mode 100644 index 00000000000..7168a5aa7b6 --- /dev/null +++ b/dom/nfc/messages/HCIEventTransactionSystemMessageConfigurator.js @@ -0,0 +1,114 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Promise.jsm"); + +XPCOMUtils.defineLazyServiceGetter(this, "appsService", + "@mozilla.org/AppsService;1", + "nsIAppsService"); + +let DEBUG = false; +function debug(aMsg) { + if (DEBUG) { + dump("-- HCIEventTransactionSystemMessageConfigurator.js " + Date.now() + " : " + aMsg + "\n"); + } +} + +/** + * nsISystemMessagesConfigurator implementation. + */ +function HCIEventTransactionSystemMessageConfigurator() { + debug("HCIEventTransactionSystemMessageConfigurator"); +} + +HCIEventTransactionSystemMessageConfigurator.prototype = { + get mustShowRunningApp() { + debug("mustShowRunningApp returning true"); + return true; + }, + + shouldDispatch: function shouldDispatch(aManifestURL, aPageURL, aType, aMessage, aExtra) { + let deferred = Promise.defer(); + debug("message to dispatch: " + JSON.stringify(aMessage)); + debug("aManifest url: " + aManifestURL); + if(!aMessage) { + return deferred.resolve(false); + } + let aid = this._byteAIDToHex(aMessage.aid); + let seName = aMessage.seName; + + appsService.getManifestFor(aManifestURL) + .then((aManifest) => this._checkAppManifest(seName, aid, aManifest)) + .then(() => { + // FIXME: Bug 884594: Access Control Enforcer + // Here we will call ace.isAllowed function which will also return + // a Promise, for now we're just resolving shouldDispatch promise + debug("dispatching message"); + deferred.resolve(true); + }) + .catch(() => { + // if the Promise chain was broken we don't dispatch the message + debug("not dispatching"); + deferred.resolve(false); + }); + + return deferred.promise; + }, + + // we might be doing some async hash computations here, returning + // a resolved/rejected promise for now so we can easily fit the method + // into a Promise chain + _checkAppManifest: function _checkAppManifest(aSeName, aAid, aManifest) { + debug("aManifest " + JSON.stringify(aManifest)); + + let hciRules = aManifest["secure_element_access"] || []; + let matchingRule = hciRules.find((rule) => { + rule = rule.toUpperCase(); + if(rule === "*" || rule === (aSeName + "/" + aAid)) { + return true; + } + + let isMatching = (match, element) => { + if(match === "*") { + return true; + } + if(match.charAt(match.length - 1) === '*') { + return element.indexOf(match.substr(0,match.length - 1)) === 0; + } + + return match === element; + }; + + return isMatching(rule.split('/')[0], aSeName) && + isMatching(rule.split('/')[1], aAid); + }); + + return (matchingRule) ? Promise.resolve() : Promise.reject(); + }, + + // FIXME: there is probably something which does this + _byteAIDToHex: function _byteAIDToHex(uint8arr) { + if (!uint8arr) { + return ""; + } + + var hexStr = ""; + for (var i = 0; i < uint8arr.length; i++) { + var hex = (uint8arr[i] & 0xff).toString(16); + hex = (hex.length === 1) ? '0' + hex : hex; + hexStr += hex; + } + return hexStr.toUpperCase(); + }, + + classID: Components.ID("{b501edd0-28bd-11e4-8c21-0800200c9a66}"), + QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesConfigurator]) +} + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HCIEventTransactionSystemMessageConfigurator]); diff --git a/dom/nfc/moz.build b/dom/nfc/moz.build index 30f266b47ab..8512343ca56 100644 --- a/dom/nfc/moz.build +++ b/dom/nfc/moz.build @@ -34,6 +34,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_NFC']: EXTRA_COMPONENTS += [ 'gonk/Nfc.js', 'gonk/Nfc.manifest', + 'messages/HCIEventTransactionSystemMessage.manifest', + 'messages/HCIEventTransactionSystemMessageConfigurator.js', ] EXTRA_JS_MODULES += [ 'gonk/nfc_consts.js',