Following on from the issue of certificate management, is the issue of
authentication. This hasn't been an issue thus far, because Xen has zero
authentication. I'm not planning to make this same mistake with the QEMU
management daemon though - its going to have a secure data transport and
real authentication from day-1. Thus we need to consider how authentication
is exposed at the libvirt client API layer.
First off, there are many possible authentication approaches:
- Username + password
- Username + one time key
- Username + password digest
- Kerberos tickets
- x509 certificates
- ...etc
So of these require prompting the user for data (eg username / password),
others will pick up their credentials from known sources (eg, the keberos
ticket cache file in /tmp/krbXXX), or have to be provided ahead of time
as part of the transport layer securit protocol (eg the x509 certificate
file).
We don't have to consider the latter case, since that's taken care of by
the certificate management API - unless we want to figure out a more
unified API, but I'm not sure it would be particularly sane.
The interesting case from an API point of view is the first, which requires
prompting the user for data. This is pretty much the PAM approach, with the
added complication that you're in the middle of a network protocol and you
may have several wire messages going back & forth, each time requesting
more pieces of info. ie you can't possibly gather the neccessary info ahead
of time.
So we need some form of callback to collect the neccessary auth data. The
network protocol equivalent of PAM is SASL. This actually has a number
of different types of callback function yuou can register, depending on
what sort of data you're prepared to provide as a client
- Challenge / response:
- const char *challenge
- const char *prompt
- const char *defresult,
- const char **result,
- unsigned *len
- Password, username, language
- const char **result
- unsigned *len
- AUthentication realm
- const char **availrealms,
- const char **result
There are a few more auth callback types defined in SASL spec, which I've
omitted here for brevity.
We could map this onto an API something like this:
enum {
VIR_CONN_AUTH_PASSWORD,
VIR_CONN_AUTH_USERNAME,
VIR_CONN_AUTH_LANG,
VIR_CONN_AUTH_CHALLENGE,
VIR_CONN_AUTH_REALM,
} virConnectAuthToken;
typedef int (virConnectAuthCBSimple)(const char **result, unsigned *len);
typedef int (virConnectAuthCBPrompt)(const char *challenge, const char *prompt,
const char *defresult,
const char *result, unsigned *len);
typedef int (virConnetAuthCBRealm)(const char **availrealms, const char *result);
typedef struct {
int token;
union {
virConnectAuthCBSimple simple;
virConnectAuthCBPrompt prompt;
virConnectAuthCBRealm realm;
} cb;
} virConnectAuthCallback;
int virConnectSetAuthCallbacks(virConnectAuthCallback *cbs, int ncbs);
Now, of course not everything is going to be SASL based - Xen may well end
up using TLS/SSL + HTTP Basic auth. There's a couple of other HTTP related
auth protocols too. They are all basically a subset of SASL provides, so the
above API ought to be sufficient to serve their auth needs too.
Finally, one could simply say, this is all rather complicated, why don't
we just use a simple username+password for everything. While this would
be nice from a coding POV, I think we need to be forward looking and
ensure we're setup to cope with things like Kerberos single-sign-on.
This is why I'm looking at SASL for the QEMU authentication process - if
you use libsasl.so you're app doesn't even need to know what auth method
it is using - the admin can simple create an appropriate config file
for sasl, and bingo you're fully kerberized & single sign-on capable.
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules:
http://search.cpan.org/~danberr/ -=|
|=- Projects:
http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|