Network transparancy api review.

Rob Scheepmaker r.scheepmaker at student.utwente.nl
Tue Jun 23 19:05:31 CEST 2009


Hello everybody,

Now that my network transparency project has come to a point where 
Plasma::Service's can actually be published and accessed, including message 
signing and authorization (well, there's still an often happening random crash 
which will probably be fun to solve but except for that :p). I thought it 
would be a good idea to have a round of API review.
You can find the current public api at http://pastebin.ca/1471270
I'll try to give an overview of how you're supposed to use it...

* Accessing a plasma service:

connect(Plasma::AccessManager::self(), 			             
SIGNAL(serviceAccessFinished(Plasma::ServiceAccessJob*)),
            this, SLOT(serviceReady(Plasma::ServiceAccessJob*)));
KUrl url("plasma://hostname:4000/nowplaying");
Plasma::AccessManager::self()->accessService(url);

void ServiceExplorer::serviceReady(Plasma::ServiceAccessJob* job) {
      Plasma::Service *service = job->service();
      //from here on, just use service like you would use an ordinary Service.
}

* Publishing a plasma service:

service->publish();
//.... that all :p

* Implementing a plasma shell, that doesn't do remote access:

Plasma::AuthorizationManager::self()->setAuthorizationInterface(new 
Plasma::DenyAllAuthorization());

* Or implement a shell that does remote access and for example want's to ask 
users through notifications if an access attempt is allowed. Implement an 
authorizationinterface with:

void DenyAllAuthorization::authorize(AuthorizationRule *rule)
{
    showNotification(rule->description());
    //handle the user interaction and when finished do something like:
    rule->setRules(AuthorizationRule::Allow);
    rule->setRules(AuthorizationRule::Deny);
    //allow all users access to this particular service.
    rule->setRules(AuthorizationRule::Allow | AuthorizationRule::AllUsers);
    //allow this particular user access to all services.
    rule->setRules(AuthorizationRule::Deny | AuthorizationRule::AllServices);
    //allow everybody access to everything! You get the idea..
    rule->setRules(AuthorizationRule::Allow | AuthorizationRule::AllUsers | 
AuthorizationRule::AllServices);    
}

that's basically all public api that I implemented till now. For DataEngine 
access and Remote Applet the idea is to implement just plasma::services that 
allow access to a dataengine or sends over a plasma package with it's current 
configuration included. I can then just add support for setting destinations 
of certain dataengines in Plasma::Package, so that dataEngine returns a 
dataengine that connects to a remote dataengine when needed. All this barely 
needs additional publicapi: just an accessPlasmoid() is basically all extra 
public api that's needed for that. Only service discovery needs some public 
api in accessmanager, but I planned to keep that quite similar to dnssd, since 
that will be the first supported method anyway.

* About identifying remote machines.
I'm not 100% fan of the way I currently identify remote machines. Currently 
I'm sending the callers hostname along with every package. We see if we've got 
a publickey belonging to that hostname, if not, we obtain one by accessing the 
service at plasma://hostname:4000/publickeyservice. This key can then be used 
to validate messages, though it would still be up the the user to check if the 
public key is actually beloning to the machine he thinks it belongs to (CA 
signed certificates wouldn't really be an option for us, I guess). Not only 
that: hostnames can change, are not even guaranteed to be unique, and this 
approach won't work when the caller is behind a NAT. 
Then it dawned on me that I could just as well use the public key as primary 
means of identifying someone. Then the public key would just be sent along
every message, together with a string that describes that machine (could be 
hostname by default, but maybe also configurable in plasma config). We can 
then give a warning (in maybe a authorizeKey function in 
AuthorizationInterface) when a new key arrives, or somebody's description 
(hostname or something else) already belongs to another key (a bit like the 
warnings ssh gives you when the server's publickey changed, or you connect 
with a server for the first time). This would however still require the user 
to pay attention to what messages say, and to be 100% secure you'll still 
always have to check the publickey, be it only once for each host.
All this might not be a big problem in practice since the most common usecases 
are probably use on the local network, where the user knows very well that he 
did (or didn't) just used his netbook to access the nowplaying applet, or 
using a pre setup list of allowed keys in more enterprisy environments. But 
still I would like this to be solid security wise and would like your opinion.

Some wild idea I've had recently, but, while maybe interesting, is atm still 
just a wild idea is to make publickeys a bit more 'visual'. How often do you 
check the public key signature when logging into a server for the first time? 
That's because it's a PITA to scan that long string of numbers and letters to 
see if they're identical. But when reading about how the air theme positions 
circles predictable randomly in front of the applets to make them easily 
recognizable, couldn't we translate a public key fingerprint into something 
very visual and that way easier recognizable? A fractal with random parameters 
based on the public key so the same public key always produces the exact same 
fractal? A very large high res photo where a small cut out is shown from 
determined by the publickey? So that the user can see: "ey, my netbook is 
supposed to have an image of a chicken, and not of a sunflower, somebody is 
doing something nasty". Anyway, probably very impractical, but I thought I'd 
just throw it out here.

Looking forward to feedback on what I have so far.

Regards,
Rob





More information about the Plasma-devel mailing list