mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
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).
This commit is contained in:
@@ -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
|
||||
|
||||
167
examples/libvirt_auth.c
Normal file
167
examples/libvirt_auth.c
Normal file
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user