location: Ask user to authorize applications

While we could have implemented this already a while ago, this would
have been a completely false security mechanism since we had no way of
reliably identifying applications. Since now with xdg-app, we can at least
reliably identify bundled applications, let's give users a choice of
which applications in particular they are OK with giving location data
to.

While we still can't reliably identify system (non-xdg-app) applications,
it seems extremely unlikely we'll ever be able to do that (at least not
in the near future) so we'll have to trust them to not lie about their
IDs.

Next release of geoclue will take the ID of bundled application directly
from corresponding xdg-app metadata so bundled applications can't simply
lie about their IDs.

https://bugzilla.gnome.org/show_bug.cgi?id=762119
This commit is contained in:
Zeeshan Ali (Khattak) 2016-02-15 19:50:25 +00:00
parent 34fc454764
commit a1e8c79d38

View File

@ -80,6 +80,8 @@ var XdgAppIface = '<node> \
</interface> \ </interface> \
</node>'; </node>';
const PermissionStore = Gio.DBusProxy.makeProxyWrapper(XdgAppIface);
const Indicator = new Lang.Class({ const Indicator = new Lang.Class({
Name: 'LocationIndicator', Name: 'LocationIndicator',
Extends: PanelMenu.SystemIndicator, Extends: PanelMenu.SystemIndicator,
@ -117,24 +119,26 @@ const Indicator = new Lang.Class({
this._onSessionUpdated(); this._onSessionUpdated();
this._onMaxAccuracyLevelChanged(); this._onMaxAccuracyLevelChanged();
this._connectToGeoclue(); this._connectToGeoclue();
this._connectToPermissionStore();
}, },
get MaxAccuracyLevel() { get MaxAccuracyLevel() {
return this._getMaxAccuracyLevel(); return this._getMaxAccuracyLevel();
}, },
// We (and geoclue) have currently no way to reliably identifying apps so AuthorizeAppAsync: function(params, invocation) {
// for now, lets just authorize all apps as long as they provide a valid let [desktopId, reqAccuracyLevel] = params;
// desktop ID. We also ensure they don't get more accuracy than global max.
AuthorizeApp: function(desktop_id, reqAccuracyLevel) {
var appSystem = Shell.AppSystem.get_default();
var app = appSystem.lookup_app(desktop_id + ".desktop");
if (app == null) {
return [false, 0];
}
let allowedAccuracyLevel = clamp(reqAccuracyLevel, 0, this._getMaxAccuracyLevel()); let authorizer = new AppAuthorizer(desktopId,
return [true, allowedAccuracyLevel]; reqAccuracyLevel,
this._permStoreProxy,
this._getMaxAccuracyLevel());
authorizer.authorize(Lang.bind(this, function(accuracyLevel) {
let ret = (accuracyLevel != GeoclueAccuracyLevel.NONE);
invocation.return_value(GLib.Variant.new('(bu)',
[ret, accuracyLevel]));
}));
}, },
_syncIndicator: function() { _syncIndicator: function() {
@ -245,7 +249,24 @@ const Indicator = new Lang.Class({
let unpacked = properties.deep_unpack(); let unpacked = properties.deep_unpack();
if ("InUse" in unpacked) if ("InUse" in unpacked)
this._syncIndicator(); this._syncIndicator();
} },
_connectToPermissionStore: function() {
this._permStoreProxy = null;
new PermissionStore(Gio.DBus.session,
'org.freedesktop.XdgApp',
'/org/freedesktop/XdgApp/PermissionStore',
Lang.bind(this, this._onPermStoreProxyReady));
},
_onPermStoreProxyReady: function(proxy, error) {
if (error != null) {
log(error.message);
return;
}
this._permStoreProxy = proxy;
},
}); });
function clamp(value, min, max) { function clamp(value, min, max) {