On 10/08/2010 12:03 PM, Patrick Ohly wrote:
On Fri, 2010-10-08 at 08:28 +0100, Alberto Mardegan wrote:
On 10/07/2010 02:09 PM, Patrick Ohly wrote:
        * Define "Google" account. Done by writing a
          accounts-provider-plugin. Where is that API defined? How is such
          a plugin installed? Is there an example?

The API is defined in libaccounts-ui, which is still stuck in the Nokia internal
legal processes to be open-sourced, we are all waiting. :-/

So we have Accounts&SSO in MeeGo 1.1, but we cannot use it? That can't
have been the intention. Please confirm and I'll escalate this :-/

No, it's not exactly like that. The accounts API are perfectly usable without libaccounts-ui; this library (which for the time being is missing from MeeGo) is helpful to write account provider and service plugins and to load them. But I think that here a step back is needed because your following questions and later messages hint that we have a different idea of this "accounts UI".

The accounts UI I'm talking about is one application which allows you to create/edit accounts. It is plugin based, because the process of creating/editing accounts can be quite different for different providers -- if all plugins are developed by a single entity, then their UI will be quite similar to each other, but if we allow any third-party developer to write a plugin for his own service, then we want to give him as much freedom as possible to design the UI as he feels like. To manage this plugin mechanism, in Harmattan (Maemo6) we created libaccounts-ui, which defines an API for writing account plugins. But this library is not necessary to create accounts in MeeGo. It is a library which uses libMeeGoTouch for the UI parts, libaccounts-qt for creating the account and libsignon-qt for securely storing the account credentials.

This centralized accounts UI replaces the accounts UI otherwise present in other apps. You won't create your e-mail accounts from the e-mail application and the chat account from the messaging application anymore; instead, there'll be ways in this apps to invoke the centralized accounts UI and create all your different types of accounts in there.

But of course, this is just the design we have in Maemo6 -- it's the design that inspired the development of libaccounts-{glib,qt}, which allows storing an account's settings in a single place, no matter what kind of account it is. I would strongly advise application developers to follow this centralized accounts UI concept, and that's why we are getting libaccounts-ui opensourced -- but it's not the only possible way.

Still, if you want to escalate the issue of having libaccounts-ui available, you have all my support, because I think it's worth it and it should be in Nokia interest that MeeGo doesn't take a totally different approach for the accounts UI.

How is the API specific to the UI? I understand that advanced use cases
(drawing your own widgets, for example) may have to depend on some UI
specific extensions, but isn't the common functionality UI independent?

libaccounts-ui is based on libMeeGoTouch. But indeed we could relax the public API and make it work with any QGraphicsWidget. The plugin UI needs to be embedded in the invoker application, or at least chained to it by the window manager -- so it cannot be completely UI agnostic.

In some cases the plugin could be just an XML file that describes various
parameters of the account creation process;

This is the part which I would expect to work regardless whether a MTF,
Qt, or<whatever>  implementation of the UI is used.

Well, the code which builds the UI out of the XML is part of libaccounts-ui. So, yes, the XMl file is UI agnostic, but libaccounts-ui cannot be.

  and actually it will be the very
same file as the libaccounts-{qt,glib} provider files.

Do we have examples of those or documentation for them?

I guess you mean examples of the extended format. The basic one, used by libaccounts-{qt,glib} can be as simple as this:
http://gitorious.org/accounts-sso/accounts-glib/blobs/master/tests/MyProvider.provider

A full example could be this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE provider>
<provider version="1.0" id="google-test">
    <name>Google(test)</name>
    <description>Example google provider</description>
    <icon>icon-l-google</icon>
    <sign-up-link>www.google.com</sign-up-link>
    <account-setup>
        <authsession>
            <method name="google" token="all">
                <mechanism name="ClientLogin" token="me"/>
                    <tokens>token1, token2</tokens>
                <mechanism name="AuthSub"/>
            </method>
            <method name="password" token="nobody">
            </method>
            <realms>
                <realm>youtube.com</realm>
                <realm>google.com</realm>
            </realms>
        </authsession>
        <authdomain separator="@" default_domain="gmail.com"/>
    </account-setup>
</provider>


This is an example of a provider plugin for Google.com. It could have a way to open the browser to the sing-up-link for creating new remote accounts, and a way to store the credentials and secure the IdentityInfo by letting applications holding the "nobody" token to use the "password" authentication method, while allowing applications holding tokens "token1" and "token2" (in the context of the MeeGo security framework) to use the credentials for SSO with a hypothetical "google" authentication plugin. (note that however ATM SSO doesn't allow such a fine-grained ACL: we have it only per identity, and not per identity/method -- but it could come)

I would only write an
account provider plugin, if I want the example.com account to be created with
the MeeGo accounts UI; or if I don't even want to have it in the accounts UI but
have it all inside my ExampleApp, then I can avoid writing any plugins at all
(but I can still use libaccounts-{qt,glib} for storage, if I want to).

Let's focus on this aspect, as it seems to be what might already work in
MeeGo 1.1. Coming back to our example, if multiple apps want to share a
Google account, could each app simply create that account using the
libaccounts-{qt,glib} if it doesn't exist yet at the time when the app
settings need it? Then the second app to run can reuse the account and
the credentials entered earlier?

Yes, this is also possible.

They would need to agree on some common parameters I suppose (like
account name), allow the "password" method and make that account
available to others, right?

They don't need to allow the "password" method. Let's say that generally, the process that stores the accounts credentials into SSO should either not restrict access to the identity at all, or know the security tokens of the possible clients. Or then if an unauthorize app were to use the identity, the security framework should ask the user to trust the application.

Is there some example code, or can you point out the relevant methods?

To create an account, it's as simple as calling:

// "MyProvider" doesn't need to exist for this to work
Accounts::Account *account = manager->createAccount("MyProvider");
account->setEnabled(true);
account->sync();

Then you can open ~/.accounts/accounts.db with a SQLite client.

Now, back to your questions: the client app uses libsignon-{qt,glib} to
authenticate. Depending on the authentication method it wants to use, it will
get a different response; if it uses SASL it will get the SASL response that it
will need to forward to the server, if it uses some web authentication method it
will probably get a token to be used in some REST API, for example, or if it
uses the "password" plugin it will get the password.
The user will not be involved in all this, if the credentials are stored in the
SSO DB.

So if method "password" is used, the client of libsignon will get the
password entered by the user directly, without any verification whether
it is valid?

Exactly. But the accounts UI (or better, the account-provider-plugin) could validate the credentials before saving the account.

Would it be possible to extend the "password" plugin (or write a
derivative) which takes the username/password and tries to use it in a
GET with a specific URL, as specified in the account settings? If there
is a page which uses HTTP authentication and returns an HTTP error
status when that fails, then such an extension would be fairly easy to
write and might apply to multiple different web sites. Not sure whether
Google has such a page, though.

I think yes; this could be another mechanism in the password plugin.

Is the framework already handling incorrectly type passwords, for
example by invoking signon-ui again?

Yes. If the applications receives an error when authenticating, it can force signond to first invoke signon-ui when trying to authenticate again. Check the UIPolicy field in the SessionData.

        * Implement signon-ui daemon. API definition, skeleton example?

TODO. Our internal implementation in Nokia will not be opened; instead, we'll
work on a completely open one for MeeGo.

This becomes off-topic for MeeGo-dev, but do you have a schedule for
this? We probably can live without the account UI, but for the use case
described above we need a password dialog.

You are right, signon-ui is badly needed. And unfortunately, the work has not been allocated yet. We are still trying to get a bugzilla component for accounts & SSO...

One question that I kept wondering about in the context of actually
securing the system against hostile apps: how do we prevent an app from
popping up a dialog which mimics the one used by signon-ui?

The user could easily be spoofed into entering his credentials thinking
that they'll be stored securely, which in fact he is handing them to an
app which might not even be allowed to use the account, much less get
the password as plain text.

The window manager could have some facilities for this.

[...]
This info is rather static, so I think one could even use the filesystem for
that. For instance, we could have a directory /usr/share/browser/services/ which
contains files named after the domain name, for instance google.com, flickr.com,
and the google.com could contain this XML:
[...]

Maintaining this mapping as part of the MeeGo system installation sounds
like a maintenance problem to me. Certainly some predefined URLs will be
useful, but I can imagine that a browser user might want to extend the
list by associating additional URLs with existing accounts. Just my 2
cents.

No, why?

If I create a service in example.com, I would write one rpm which contains:
- the XML file for the account-provider-plugin, to allow creating accounts for example.com on the device; - the XML file for the browser mapping for my domain, so that if you have created an account for example.com in the device, then logging into my site from the browser wouldn't ask for password (and vice-versa)

These files wouldn't be provided/maintained by the browser, but by the service provider.

Authentication plugins can come with a -devel package containing some additional
headers which subclass the SessionData and extend it with some additional
fields, specific to the authentication method. The password plugin has this
extra Secret field.

This doesn't seem to be packaged in MeeGo at this time:

# zypper search signon | grep password
i | libsignon-passwordplugin | Plain Password plugin for Single Sign On      | 
package
# rpm -q -l libsignon-passwordplugin
/usr/lib/signon/libpasswordplugin.so

No surprise that I haven't found it ;-)

Sorry, I just noticed that the Secret is indeed part of the basic SessionData, that's why the password plugin doesn't ship any extra includes. See:
http://gitorious.org/accounts-sso/signon/blobs/master/lib/SignOn/sessiondata.h
(note how the SIGNON_SESSION_DECLARE_PROPERTY macro is defined)

Ciao,
  Alberto

--
http://blog.mardy.it <- geek in un lingua international!
_______________________________________________
MeeGo-dev mailing list
[email protected]
http://lists.meego.com/listinfo/meego-dev

Reply via email to