hi all... this is a "RFC" type email as i start meandering my way towards selective locking down of access of DataEngines to scripted Plasmoids (JS and QML at least anyways). there is very little that can be done with C++ plasmoids since it is native code running which means all bets are off anyways. Ruby and Python are little better with their broad access to system libraries via bindings, so this primarily concerns our desire to sandbox what can be: JS and QML.
so .. the aim is to make it so that given a random assortment of DataEngines, Services and Plasmoids, we can control what individual Plasmoids have access to. initially i'm going to concentrate on a per-engine basis and think later (if at all) about per-source access control. (Services are not shared, so that isn't an issue here) == Determining Need == there are a few possibilities on how to determine whether or not a Plasmoid needs a given DataEngine: a) advertise which engines it uses in its .desktop file Pros: * we can determine prior to loading or even installing whether or not we can service this Plasmoid * it would make setting up a whitelist based system very easy * we could bug the user _once_ about which services the Plasmoid will wish to access prior to running it * this is the system we use for Extensions Cons: * it means by-hand bookkeeping on the part of the Plasmoid developer -> all engines/services requested would have to show up in the .desktop file b) intercept all calls to dataEngine() / service() and figure out if the Plasmoid really, indeed, should have access to them Pros: * validation code needs to be in the getters anyways, so less code to write (ok, this is a weak "pro" :) * largely transparent to the Plasmoid writer Cons: * would mean interupting execution of the app, and possibly interupting the user, everytime a new DataEngine/Service gets used * can't know prior to install and run what the Plasmoid wants to do in both cases, a whitelist recording system needs to be developed, though that is a pretty simple key/value store that KConfig should be able to handle just fine. i'm leaning towards solution (a). == Defining Access Conditions == now the big question: what DataEngines/Services can be accessed under what terms? here are the scenarios i can currently foresee as being useful: some DataEngines are completely harmless and should require no verification at all. it would suck to show every access to every DataEngine for every Plasmoid as that just seems .. well .. a bit over the top. some may be security sensitive and completely off-limits to any scripted Plasmoid, left only to the installed system itself. some will need to have user agreement or some other system configuration to allow access. this category might include things like access to powermanagement, the phone dialer, etc. still others may require that the plasmoid has been successfully signed by a certain GPG key before using. i've toyed with the idea of approving categories of things like "can access the network" and then a DataEngine/Service advertising that they require network access. but as i chased that idea through, it seemed not only overly broad but probably not as useful as "access my Twitter account". what DataEngines could do, however, is advertise that they use, e.g., network services and that can be used as an aid in helping one decide whether or not to allow access to that engine: "The <foo> app is requesting access to the following services: Network access: * Microblogging Hardware awareness: * Network status" this data should be stored in the DataEngine/Service's .desktop file. these keys might include: X-Plasma-Access=[OnApproval|Open|GPG] OnApproval would be the default (for safety reasons) and then rely on the Comment as well as optional categories being present in the .desktop file. Open would mean "anyone can use this, i'm safe!" GPG would mean "requires a GPG key" X-Plasma-AccessCategory=[Network|Hardware|...] this list needs further definitions X-Plasma-AccessKeys=[list of approved gpg keys] == Storing Access Priveleges == this should be kept KISS until we need something more: a single INI filethat looks like something like this: [org.kde.superPlasmoid] DataEnginesApproved=org.kde.foo,..,.. DataEnginesDenied=org.kde.blarg,.. ServicesApproved=..,.. ServicesDenied=..,.. == Preventing Plasmoids From Breaking The System == where to store access priveleges is a more interesting question than it would appear at first blush. a plasmoid that has the LocalIO extension could currently access this file and possibly even write to it if it is in the user's dir. assuming the approval app runs non-priveleged and as the same user then we have an issue. one possibility is to off-limits the location that this file is stored. this would be easy enough to do in the bindings, though QML might give us an issue here as QML, it turns out, has a gigantic security hole that allows any file to be accessed anywhere on the system. ah well.. something to address in QML2 perhaps. *looks at Qt devs* there's also the issue, however, of .desktop file cascade. if a DataEngine's .desktop file is stored in /usr and the user adds one with the same name and path in `kde4-config --localprefix` then they can override what happens there. not great. one option would be to _only_ parse the system installed .desktop file. this would potentially suck for kiosk systems with multiple layers of directories, however. this could possibly be worked around by either looking for it manually and picking the "nearest" not-in-the-homedir path (which leaves open the possibility for an environment variable to be tweaked to add a path in a writable dir that isn't the homedir; which could be closed by requiring the path not be writable by the user; which would break many dev installs .. ah well :) ... or we could just not care and say "there is one set of security definitions, system-wide, for any given DataEngine .. and they live in the install dir". this would still allow per-user definitions, but it would be largely in the hands of the user (or the sys admin using kiosk). this is fine for DataEngines and Services installed system-wide, but if we have DataEngines and Services installed in the user's dir, say via network download, we're right back to square one. so i'm thinking that we just don't allow random file access to anything in $KDEHOME at all, not even via LocalIO. that closes off the entire vector for routing around the system and leaves the implementation code simple. thoughts? -- Aaron J. Seigo humru othro a kohnu se GPG Fingerprint: 8B8B 2209 0C6F 7C47 B1EA EE75 D6B7 2EB1 A7F1 DB43 KDE core developer sponsored by Qt Development Frameworks
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Plasma-devel mailing list Plasma-devel@kde.org https://mail.kde.org/mailman/listinfo/plasma-devel