This sample of code helped me a lot! Here is the phypOpen function I rewrited based on your code: http://pastebin.com/f65912242 - I did a lot of tests with my HMC here and everything seemed to be working fine. The prompt for the password and the use of the public key. I also did use the virRaiseError() to adjust all the error messages into libvirt pattern. the modified function I made based on your sample code. Thanks for the help. []'s Em Ter, 2009-05-05 às 21:50 +0100, Daniel P. Berrange escreveu: > On Tue, May 05, 2009 at 04:06:12PM -0300, Eduardo Otubo wrote: > > Hello all, > > > > I'll start using virConnectAuthPtr to handle the authentication proccess > > at the phyp driver I'm wrinting > > <https://www.redhat.com/archives/libvir-list/2009-April/msg00493.html> > > and I have some doubts in my mind: > > > > 1) What are the types of authentication that 'int *credtype' can hold? > > And who fills it with the information I'll need? > > These are all defined in libvirt.h - we basically copied the SASL > credential types > > VIR_CRED_USERNAME = 1, /* Identity to act as */ > VIR_CRED_AUTHNAME = 2, /* Identify to authorize as */ > VIR_CRED_LANGUAGE = 3, /* RFC 1766 languages, comma separated */ > VIR_CRED_CNONCE = 4, /* client supplies a nonce */ > VIR_CRED_PASSPHRASE = 5, /* Passphrase secret */ > VIR_CRED_ECHOPROMPT = 6, /* Challenge response */ > VIR_CRED_NOECHOPROMPT = 7, /* Challenge response */ > VIR_CRED_REALM = 8, /* Authentication realm */ > VIR_CRED_EXTERNAL = 9, /* Externally managed credential */ > > The client application filles in the data in virConnectAuth struct, > providing the function callback pointer, an opaque data blob (cddata) > and the list of credential types it knows how to handle. > > > 2) Once known the credential type, I need to use the function pointer > > 'virConnectAuthCallbackPtr cb' to get the information whatever it is, > > right? I mean, it can be a password, a pubkey or anything else, right? > > Is there a callback able to handle password or pubkeys? > > Yep, once your driver knows what credentials it needs to collect, it > should check to see if the client has declared it supports the required > credentials. If it does, then the driver should populate an array of > virConnectCredential objects detailing what credentials needs to be > collected. The callback is then invoked, and the client app will collect > the credentials, putting the results in the 'result' / resultlen fields. > > When the callback returns, the driver can get the credentials fro mthe > result/resultlen field - though it should check the callback return > status to see if the client app had any errors. > > > 3) And finally I'll be able to use the 'void *cbdata' to manage the > > authentication in my way. In my case, using libssh. In fact, in the end > > of the process, I'll just need a password or a key to get things > > working. > > The 'cbdata' field is something used by the client app. Both a password > or private key passphrase would map to VIR_CRED_PASSPHRASE credential > type. You'd just have a different prompt / challenge > > > There is no driver authenticatin agaist ssh channel, that's why I got so > > confused with this topic. > > > > I don't know if my thoughts are pretty clear here. But I would like to > > confirm the information 2 and 3, and check how 1 works. Could anyone > > help me? > > Let me give you a close-to-working example that tries to illustrate > the general idea from the driver point of view. > > First off, libvirt.so provides a generic callback that works for command > line based apps, and knows how to collect credentials of type > > static int virConnectCredTypeDefault[] = { > VIR_CRED_AUTHNAME, > VIR_CRED_ECHOPROMPT, > VIR_CRED_REALM, > VIR_CRED_PASSPHRASE, > VIR_CRED_NOECHOPROMPT, > VIR_CRED_EXTERNAL, > }; > > static virConnectAuth virConnectAuthDefault = { > virConnectCredTypeDefault, > sizeof(virConnectCredTypeDefault)/sizeof(int), > virConnectAuthCallbackDefault, > NULL, > }; > > > This is what virsh uses when connecting to libvirt > > ctl->conn = virConnectOpenAuth(ctl->name, virConnectAuthPtrDefault, 0) > > > > Now, in your Phyp driver, lets assume at some point in time libssh tells > it wants a username+password. > > These will map to VIR_CRED_AUTHNAME and VIR_CRED_PASSPHRASE, so first > step is to ensure the callback passed in by the client app supports > these > > static virDrvOpenStatus phypOpen(virConnectPtr conn, > virConnectAuthPtr auth, > int flags) { > > .... start ssh conection ... > > if (need password) { > int i; > int hasPassphrase = 0 > int hasAuthname = 0; > /* The creds we're about to ask the application for... */ > virConnectCredentials creds[] = { > { VIR_CRED_AUTHNAME, "Enter username:", "Username", NULL, NULL, 0 }, > { VIR_CRED_PASSPHRASE, "Enter password:", "Password", NULL, NULL, 0 }, > }; > > /* If no auth callback info was provided, must fail now */ > if (!auth || !auth->cb) { > virPhypRaiseError(conn, VIR_ERR_AUTH_FAILED, "%s", > _("no authentication callback provided")); > return VIR_OPEN_FAILED; > } > > /* Check if desired credentials are supported */ > for (i = 0 ; i < auth.ncredtype ; i++) { > if (auth.credtype[i] == VIR_CRED_AUTHNAME) > hasAuthName = 1; > if (auth.credtype[i] == VIR_CRED_PASSPHRASE) > hasPassphrase = 1; > } > if (!hasPassphrase || !hasAuthname) { > virPhypRaiseError(conn, VIR_ERR_AUTH_FAILED, "%s", > _("required credentials are not supported")); > return VIR_OPEN_FAILED; > } > > > /* Credential supported, to try to get them from user */ > int res = (auth->cb)(creds, ARRAY_CARDINALITY(creds), auth->cbdata); > > if (res < 0) { > virPhypRaiseError(conn, VIR_ERR_AUTH_FAILED, "%s", > _("unable to fetch credentials")); > return VIR_OPEN_FAILED; > } > > char *username = creds[0]->result; > char *password = creds[1]->result; > .... give these back to libssh now .... > } > > > This example code is quite inflexible & hardcoded to the specifics of > getting a username + password. Depending on libssh's API you may want > or need todo things slightly differently. For example, you probably > won't need to actually prompt for username, since I imagine you're > getting that from the connection URI directly. > > You may have to try several credentials in turn, requiring multiple > invocations of the callback. For example, first time you may prompt > for a passphrase for a SSH private key. If private key auth fails, > you may then continue onto password based auth, and need to prompt > for login password. So in that cae you'd be invoking the callback > twice asking for different types of data each time. > > Also, don't assume that the 'result' field is NULL terminated, or > that 'result' is even non-NULL - sanity check this data you get > back from the client app before using it. > > Regards, > Daniel -- Eduardo Otubo Software Engineer Linux Technology Center IBM Systems & Technology Group Mobile: +55 19 8135 0885 otubo@xxxxxxxxxxxxxxxxxx -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list