extensionSystem: Replace manifest system with a more direct approach

For security reasons, we shouldn't allow the Shell to download and install
any extension URL.

https://bugzilla.gnome.org/show_bug.cgi?id=658612
This commit is contained in:
Jasper St. Pierre 2011-09-12 14:16:03 -04:00
parent 52273b6c03
commit d5e6ea6ebd
2 changed files with 22 additions and 43 deletions

View File

@ -11,6 +11,8 @@ const Soup = imports.gi.Soup;
const Config = imports.misc.config; const Config = imports.misc.config;
const API_VERSION = 1;
const ExtensionState = { const ExtensionState = {
ENABLED: 1, ENABLED: 1,
DISABLED: 2, DISABLED: 2,
@ -28,6 +30,10 @@ const ExtensionType = {
PER_USER: 2 PER_USER: 2
}; };
const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
const REPOSITORY_URL_INFO = REPOSITORY_URL_BASE + '/extension-info/';
const _httpSession = new Soup.SessionAsync(); const _httpSession = new Soup.SessionAsync();
// The unfortunate state of gjs, gobject-introspection and libsoup // The unfortunate state of gjs, gobject-introspection and libsoup
@ -92,50 +98,23 @@ function versionCheck(required, current) {
return false; return false;
} }
function installExtensionFromManifestURL(uuid, url) { function installExtensionFromUUID(uuid, version_tag) {
_httpSession.queue_message( let meta = { uuid: uuid,
Soup.Message.new('GET', url), state: ExtensionState.DOWNLOADING,
function(session, message) { error: '' };
if (message.status_code != Soup.KnownStatusCode.OK) {
logExtensionError(uuid, 'downloading manifest: ' + message.status_code.toString());
return;
}
let manifest; extensionMeta[uuid] = meta;
try {
manifest = JSON.parse(message.response_body.data);
} catch (e) {
logExtensionError(uuid, 'parsing: ' + e.toString());
return;
}
if (uuid != manifest['uuid']) { _signals.emit('extension-state-changed', meta);
logExtensionError(uuid, 'manifest: manifest uuids do not match');
return;
}
let meta = extensionMeta[uuid] = { uuid: uuid, let params = { version_tag: version_tag,
state: ExtensionState.DOWNLOADING, shell_version: Config.PACKAGE_VERSION,
error: '' }; api_version: API_VERSION.toString() };
_signals.emit('extension-state-changed', meta); let url = REPOSITORY_URL_DOWNLOAD.format(uuid);
let message = Soup.form_request_new_from_hash('GET', url, params);
installExtensionFromManifest(manifest, meta); _httpSession.queue_message(message,
});
}
function installExtensionFromManifest(manifest, meta) {
let uuid = manifest['uuid'];
let name = manifest['name'];
if (!versionCheck(manifest['shell-version'], Config.PACKAGE_VERSION)) {
meta.state = ExtensionState.OUT_OF_DATE;
logExtensionError(uuid, 'version: ' + name + ' is not compatible with current GNOME Shell version', meta.state);
return;
}
let url = manifest['__installer'];
_httpSession.queue_message(Soup.Message.new('GET', url),
function(session, message) { function(session, message) {
gotExtensionZipFile(session, message, uuid); gotExtensionZipFile(session, message, uuid);
}); });

View File

@ -46,7 +46,7 @@ const GnomeShellIface = {
outSignature: '' outSignature: ''
}, },
{ name: 'InstallRemoteExtension', { name: 'InstallRemoteExtension',
inSignature: 's', inSignature: 'ss',
outSignature: '' outSignature: ''
} }
], ],
@ -174,8 +174,8 @@ GnomeShell.prototype = {
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions); global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
}, },
InstallRemoteExtension: function(uuid, url) { InstallRemoteExtension: function(uuid, version_tag) {
ExtensionSystem.installExtensionFromManifestURL(uuid, url); ExtensionSystem.installExtensionFromUUID(uuid, version_tag);
}, },
get OverviewActive() { get OverviewActive() {
@ -189,7 +189,7 @@ GnomeShell.prototype = {
Main.overview.hide(); Main.overview.hide();
}, },
ApiVersion: 1, ApiVersion: ExtensionSystem.API_VERSION,
ShellVersion: Config.PACKAGE_VERSION, ShellVersion: Config.PACKAGE_VERSION,