diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2012-10-13 12:57:12 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2012-10-13 20:54:07 +0100 |
commit | d83d17e9dbfb24496a0841fc2aed436181ca0341 (patch) | |
tree | d6e0bfc2ff4a694f731d47e6c8d386d5b61b02ce /examples | |
parent | 07d0546f5d210d1cee048de8d42bdf58302f0d93 (diff) | |
download | libguestfs-d83d17e9dbfb24496a0841fc2aed436181ca0341.tar.gz libguestfs-d83d17e9dbfb24496a0841fc2aed436181ca0341.tar.xz libguestfs-d83d17e9dbfb24496a0841fc2aed436181ca0341.zip |
New APIs: Model libvirt authentication events through the API.
This commit models libvirt authentication events through the API,
adding one new event (GUESTFS_EVENT_LIBVIRT_AUTH) and several new
APIs:
guestfs_set_libvirt_supported_credentials
guestfs_get_libvirt_requested_credentials
guestfs_get_libvirt_requested_credential_prompt
guestfs_get_libvirt_requested_credential_challenge
guestfs_get_libvirt_requested_credential_defresult
guestfs_set_libvirt_requested_credential
See the documentation and example which shows how to use the new API.
This commit also changes existing calls to virConnectOpen* within the
library so that the new API is used.
Also included is an example (but not a test, because it's hard to see
how to automatically test the libvirt API).
Diffstat (limited to 'examples')
-rw-r--r-- | examples/Makefile.am | 13 | ||||
-rw-r--r-- | examples/libvirt_auth.c | 167 |
2 files changed, 179 insertions, 1 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am index a7c9903c..bf2db45d 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -32,7 +32,7 @@ CLEANFILES = \ noinst_PROGRAMS = create_disk display_icon inspect_vm if HAVE_LIBVIRT -noinst_PROGRAMS += copy_over +noinst_PROGRAMS += copy_over libvirt_auth endif if HAVE_HIVEX noinst_PROGRAMS += virt-dhcp-address @@ -52,6 +52,17 @@ copy_over_CFLAGS = \ copy_over_LDADD = \ $(top_builddir)/src/libguestfs.la \ $(LIBVIRT_LIBS) + +libvirt_auth_SOURCES = libvirt_auth.c +libvirt_auth_CFLAGS = \ + -DGUESTFS_WARN_DEPRECATED=1 \ + -I$(top_srcdir)/src -I$(top_builddir)/src \ + $(LIBVIRT_CFLAGS) \ + -pthread \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) +libvirt_auth_LDADD = \ + $(top_builddir)/src/libguestfs.la \ + $(LIBVIRT_LIBS) endif create_disk_SOURCES = create_disk.c diff --git a/examples/libvirt_auth.c b/examples/libvirt_auth.c new file mode 100644 index 00000000..f0b8bbb7 --- /dev/null +++ b/examples/libvirt_auth.c @@ -0,0 +1,167 @@ +/* Example of using the libvirt authentication event-driven API. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <guestfs.h> + +static void +usage (void) +{ + fprintf (stderr, + "Usage:\n" + "\n" + " libvirt_auth URI domain\n" + "\n" + "where:\n" + "\n" + " URI is the libvirt URI, eg. qemu+libssh2://USER@localhost/system\n" + " domain is the name of the guest\n" + "\n" + "Example:\n" + "\n" + " libvirt_auth 'qemu+libssh2://USER@localhost/system' 'foo'\n" + "\n" + "would connect (read-only) to libvirt URI given and open the guest\n" + "called 'foo' and list some information about its filesystems.\n" + "\n" + "The important point of this example is that any libvirt authentication\n" + "required to connect to the server should be done.\n" + "\n"); +} + +static void auth_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len); + +int +main (int argc, char *argv[]) +{ + const char *uri, *dom; + guestfs_h *g; + const char *creds[] = { "authname", "passphrase", + "echoprompt", "noechoprompt", NULL }; + int r, eh; + char **filesystems; + size_t i; + + if (argc != 3) { + usage (); + exit (EXIT_FAILURE); + } + uri = argv[1]; + dom = argv[2]; + + g = guestfs_create (); + if (!g) + exit (EXIT_FAILURE); + + r = guestfs_set_libvirt_supported_credentials (g, (char **) creds); + if (r == -1) + exit (EXIT_FAILURE); + + /* Set up the event handler. */ + eh = guestfs_set_event_callback (g, auth_callback, + GUESTFS_EVENT_LIBVIRT_AUTH, 0, NULL); + if (eh == -1) + exit (EXIT_FAILURE); + + /* Add the named domain. */ + r = guestfs_add_domain (g, dom, + GUESTFS_ADD_DOMAIN_LIBVIRTURI, uri, + -1); + if (r == -1) + exit (EXIT_FAILURE); + + /* Launch and do some simple inspection. */ + r = guestfs_launch (g); + if (r == -1) + exit (EXIT_FAILURE); + + filesystems = guestfs_list_filesystems (g); + + for (i = 0; filesystems[i] != NULL; i += 2) { + printf ("%s:%s is a %s filesystem\n", + dom, filesystems[i], filesystems[i+1]); + free (filesystems[i]); + free (filesystems[i+1]); + } + free (filesystems); + + exit (EXIT_SUCCESS); +} + +static void +auth_callback (guestfs_h *g, + void *opaque, + uint64_t event, + int event_handle, + int flags, + const char *buf, size_t buf_len, + const uint64_t *array, size_t array_len) +{ + char **creds; + size_t i; + char *prompt; + char *reply = NULL; + size_t replylen; + char *pass; + ssize_t len; + int r; + + printf ("libvirt_auth.c: authentication required for libvirt URI '%s'\n\n", + buf); + + /* Ask libguestfs what credentials libvirt is demanding. */ + creds = guestfs_get_libvirt_requested_credentials (g); + if (creds == NULL) + exit (EXIT_FAILURE); + + /* Now ask the user for answers. */ + for (i = 0; creds[i] != NULL; ++i) + { + printf ("libvirt_auth.c: credential '%s'\n", creds[i]); + + if (strcmp (creds[i], "authname") == 0 || + strcmp (creds[i], "echoprompt") == 0) { + prompt = guestfs_get_libvirt_requested_credential_prompt (g, i); + if (prompt && strcmp (prompt, "") != 0) + printf ("%s: ", prompt); + free (prompt); + + len = getline (&reply, &replylen, stdin); + if (len == -1) { + perror ("getline"); + exit (EXIT_FAILURE); + } + if (len > 0 && reply[len-1] == '\n') + reply[--len] = '\0'; + + r = guestfs_set_libvirt_requested_credential (g, i, reply, len); + if (r == -1) + exit (EXIT_FAILURE); + } else if (strcmp (creds[i], "passphrase") == 0 || + strcmp (creds[i], "noechoprompt") == 0) { + prompt = guestfs_get_libvirt_requested_credential_prompt (g, i); + if (prompt && strcmp (prompt, "") != 0) + printf ("%s: ", prompt); + free (prompt); + + pass = getpass (""); + if (pass == NULL) { + perror ("getpass"); + exit (EXIT_FAILURE); + } + len = strlen (pass); + + r = guestfs_set_libvirt_requested_credential (g, i, pass, len); + if (r == -1) + exit (EXIT_FAILURE); + } + + free (creds[i]); + } + + free (reply); + free (creds); +} |