summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2009-07-29 12:35:27 +0100
committerDaniel P. Berrange <berrange@redhat.com>2009-07-29 12:35:27 +0100
commitbc55a8d75773e347d9ba579dccfe438ec3a34eae (patch)
treeab03ed2567a53c5f3cba949d9ae5b816aa4bafdf /src
parent852825ae5e817421abcf4c6b7be4ab9dab96a333 (diff)
downloadvirt-viewer-bc55a8d75773e347d9ba579dccfe438ec3a34eae.tar.gz
virt-viewer-bc55a8d75773e347d9ba579dccfe438ec3a34eae.tar.xz
virt-viewer-bc55a8d75773e347d9ba579dccfe438ec3a34eae.zip
Add support for libvirt graphical auth
Diffstat (limited to 'src')
-rw-r--r--src/auth.c212
-rw-r--r--src/auth.glade16
-rw-r--r--src/auth.h8
-rw-r--r--src/util.h1
-rw-r--r--src/viewer.c25
5 files changed, 204 insertions, 58 deletions
diff --git a/src/auth.c b/src/auth.c
index 88afd7f..a7f8c96 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -25,19 +25,72 @@
#include <vncdisplay.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
+#include <string.h>
#include "auth.h"
-void viewer_auth_vnc_credentials(GtkWidget *vnc, GValueArray *credList)
+
+static int
+viewer_auth_collect_credentials(const char *type,
+ const char *address,
+ char **username,
+ char **password)
{
GtkWidget *dialog = NULL;
- const char **data;
+ GladeXML *creds = viewer_load_glade("auth.glade", "auth");
+ GtkWidget *credUsername;
+ GtkWidget *credPassword;
+ GtkWidget *promptUsername;
+ GtkWidget *promptPassword;
+ GtkWidget *labelMessage;
+ int response;
+ char *message;
+
+ dialog = glade_xml_get_widget(creds, "auth");
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
+
+ labelMessage = glade_xml_get_widget(creds, "message");
+ credUsername = glade_xml_get_widget(creds, "cred-username");
+ promptUsername = glade_xml_get_widget(creds, "prompt-username");
+ credPassword = glade_xml_get_widget(creds, "cred-password");
+ promptPassword = glade_xml_get_widget(creds, "prompt-password");
+
+ gtk_widget_set_sensitive(credUsername, username != NULL);
+ gtk_widget_set_sensitive(promptUsername, username != NULL);
+ gtk_widget_set_sensitive(credPassword, password != NULL);
+ gtk_widget_set_sensitive(promptPassword, password != NULL);
+
+ message = g_strdup_printf("Authentication is required for the %s connection to:\n\n"
+ "<b>%s</b>\n\n",
+ type,
+ address ? address : "<unknown>");
+
+ gtk_label_set_markup(GTK_LABEL(labelMessage), message);
+ g_free(message);
+
+ gtk_widget_show_all(dialog);
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_hide(dialog);
+
+ if (response == GTK_RESPONSE_OK) {
+ if (username)
+ *username = g_strdup(gtk_entry_get_text(GTK_ENTRY(credUsername)));
+ if (password)
+ *password = g_strdup(gtk_entry_get_text(GTK_ENTRY(credPassword)));
+ }
+
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+
+ return response == GTK_RESPONSE_OK ? 0 : -1;
+}
+
+void viewer_auth_vnc_credentials(GtkWidget *vnc, GValueArray *credList, char **vncAddress)
+{
+ char *username = NULL, *password = NULL;
gboolean wantPassword = FALSE, wantUsername = FALSE;
int i;
- DEBUG_LOG("Got credential request for %d credential(s)", credList->n_values);
-
- data = g_new0(const char *, credList->n_values);
+ DEBUG_LOG("Got VNC credential request for %d credential(s)", credList->n_values);
for (i = 0 ; i < credList->n_values ; i++) {
GValue *cred = g_value_array_get_nth(credList, i);
@@ -49,70 +102,129 @@ void viewer_auth_vnc_credentials(GtkWidget *vnc, GValueArray *credList)
wantPassword = TRUE;
break;
case VNC_DISPLAY_CREDENTIAL_CLIENTNAME:
- data[i] = "libvirt";
+ break;
default:
- break;
+ DEBUG_LOG("Unsupported credential type %d", g_value_get_enum(cred));
+ vnc_display_close(VNC_DISPLAY(vnc));
+ goto cleanup;
}
}
if (wantUsername || wantPassword) {
- GladeXML *creds = viewer_load_glade("auth.glade", "auth");
- GtkWidget *credUsername;
- GtkWidget *credPassword;
- GtkWidget *promptUsername;
- GtkWidget *promptPassword;
- int response;
-
- dialog = glade_xml_get_widget(creds, "auth");
- gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
-
- credUsername = glade_xml_get_widget(creds, "cred-username");
- promptUsername = glade_xml_get_widget(creds, "prompt-username");
- credPassword = glade_xml_get_widget(creds, "cred-password");
- promptPassword = glade_xml_get_widget(creds, "prompt-password");
-
- gtk_widget_set_sensitive(credUsername, wantUsername);
- gtk_widget_set_sensitive(promptUsername, wantUsername);
- gtk_widget_set_sensitive(credPassword, wantPassword);
- gtk_widget_set_sensitive(promptPassword, wantPassword);
-
- gtk_widget_show_all(dialog);
- response = gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_hide(dialog);
-
- if (response == GTK_RESPONSE_OK) {
- for (i = 0 ; i < credList->n_values ; i++) {
- GValue *cred = g_value_array_get_nth(credList, i);
- switch (g_value_get_enum(cred)) {
- case VNC_DISPLAY_CREDENTIAL_USERNAME:
- data[i] = gtk_entry_get_text(GTK_ENTRY(credUsername));
- break;
- case VNC_DISPLAY_CREDENTIAL_PASSWORD:
- data[i] = gtk_entry_get_text(GTK_ENTRY(credPassword));
- break;
- }
- }
- }
+ int ret = viewer_auth_collect_credentials("VNC", vncAddress ? *vncAddress : NULL,
+ wantUsername ? &username : NULL,
+ wantPassword ? &password : NULL);
+
+ if (ret < 0) {
+ vnc_display_close(VNC_DISPLAY(vnc));
+ goto cleanup;
+ }
}
for (i = 0 ; i < credList->n_values ; i++) {
GValue *cred = g_value_array_get_nth(credList, i);
- if (data[i]) {
+ switch (g_value_get_enum(cred)) {
+ case VNC_DISPLAY_CREDENTIAL_USERNAME:
+ if (!username ||
+ vnc_display_set_credential(VNC_DISPLAY(vnc),
+ g_value_get_enum(cred),
+ username)) {
+ DEBUG_LOG("Failed to set credential type %d", g_value_get_enum(cred));
+ vnc_display_close(VNC_DISPLAY(vnc));
+ }
+ break;
+ case VNC_DISPLAY_CREDENTIAL_PASSWORD:
+ if (!password ||
+ vnc_display_set_credential(VNC_DISPLAY(vnc),
+ g_value_get_enum(cred),
+ password)) {
+ DEBUG_LOG("Failed to set credential type %d", g_value_get_enum(cred));
+ vnc_display_close(VNC_DISPLAY(vnc));
+ }
+ break;
+ case VNC_DISPLAY_CREDENTIAL_CLIENTNAME:
if (vnc_display_set_credential(VNC_DISPLAY(vnc),
g_value_get_enum(cred),
- data[i])) {
+ "libvirt")) {
DEBUG_LOG("Failed to set credential type %d", g_value_get_enum(cred));
vnc_display_close(VNC_DISPLAY(vnc));
}
- } else {
+ break;
+ default:
DEBUG_LOG("Unsupported credential type %d", g_value_get_enum(cred));
vnc_display_close(VNC_DISPLAY(vnc));
}
}
- g_free(data);
- if (dialog)
- gtk_widget_destroy(GTK_WIDGET(dialog));
+ cleanup:
+ g_free(username);
+ g_free(password);
}
+
+int
+viewer_auth_libvirt_credentials(virConnectCredentialPtr cred,
+ unsigned int ncred,
+ void *cbdata)
+{
+ char **username = NULL, **password = NULL;
+ const char *uri = cbdata;
+ int i;
+ int ret = -1;
+
+ DEBUG_LOG("Got libvirt credential request for %d credential(s)", ncred);
+
+ for (i = 0 ; i < ncred ; i++) {
+ switch (cred[i].type) {
+ case VIR_CRED_USERNAME:
+ case VIR_CRED_AUTHNAME:
+ username = &cred[i].result;
+ break;
+ case VIR_CRED_PASSPHRASE:
+ password = &cred[i].result;
+ break;
+ default:
+ DEBUG_LOG("Unsupported libvirt credential %d", cred[i].type);
+ return -1;
+ }
+ }
+
+ if (username || password) {
+ ret = viewer_auth_collect_credentials("libvirt", uri,
+ username, password);
+ if (ret < 0)
+ goto cleanup;
+ } else {
+ ret = 0;
+ }
+
+ for (i = 0 ; i < ncred ; i++) {
+ switch (cred[i].type) {
+ case VIR_CRED_AUTHNAME:
+ case VIR_CRED_USERNAME:
+ case VIR_CRED_PASSPHRASE:
+ if (cred[i].result)
+ cred[i].resultlen = strlen(cred[i].result);
+ else
+ cred[i].resultlen = 0;
+ DEBUG_LOG("Got '%s' %d %d", cred[i].result, cred[i].resultlen, cred[i].type);
+ break;
+ }
+ }
+
+ cleanup:
+ DEBUG_LOG("Return %d", ret);
+ return ret;
+}
+
+
+
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/src/auth.glade b/src/auth.glade
index 2e443fc..bf58452 100644
--- a/src/auth.glade
+++ b/src/auth.glade
@@ -13,6 +13,18 @@
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
+ <widget class="GtkLabel" id="message">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">label</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">2</property>
@@ -61,7 +73,7 @@
</child>
</widget>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child internal-child="action_area">
@@ -88,7 +100,7 @@
<property name="response_id">-5</property>
</widget>
<packing>
- <property name="position">1</property>
+ <property name="position">3</property>
</packing>
</child>
</widget>
diff --git a/src/auth.h b/src/auth.h
index d7b5334..be3fd20 100644
--- a/src/auth.h
+++ b/src/auth.h
@@ -23,8 +23,14 @@
#ifndef VIRT_VIEWER_AUTH_H
#define VIRT_VIEWER_AUTH_H
+#include <libvirt/libvirt.h>
+
#include "util.h"
-void viewer_auth_vnc_credentials(GtkWidget *vnc, GValueArray *credList);
+void viewer_auth_vnc_credentials(GtkWidget *vnc, GValueArray *credList, char **message);
+
+int viewer_auth_libvirt_credentials(virConnectCredentialPtr cred,
+ unsigned int ncred,
+ void *cbdata);
#endif
diff --git a/src/util.h b/src/util.h
index c4c5b3f..421ea6c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -31,6 +31,7 @@
extern gboolean doDebug;
#define DEBUG_LOG(s, ...) do { if (doDebug) g_debug((s), ## __VA_ARGS__); } while (0)
+#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
GladeXML *viewer_load_glade(const char *name, const char *widget);
diff --git a/src/viewer.c b/src/viewer.c
index a13a128..606be3f 100644
--- a/src/viewer.c
+++ b/src/viewer.c
@@ -115,6 +115,7 @@ typedef struct VirtViewer {
gboolean withEvents;
int active;
+ char *vncAddress;
gboolean accelEnabled;
GValue accelSetting;
@@ -843,6 +844,8 @@ static int viewer_activate(VirtViewer *viewer,
DEBUG_LOG("Remote host is %s and transport %s user %s",
host, transport ? transport : "", user ? user : "");
+ viewer->vncAddress = g_strdup_printf("%s:%s", host, vncport);
+
#if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK)
if (transport && g_strcasecmp(transport, "ssh") == 0 &&
!viewer->direct)
@@ -850,10 +853,11 @@ static int viewer_activate(VirtViewer *viewer,
return -1;
#endif
- if (fd >= 0)
+ if (fd >= 0) {
vnc_display_open_fd(VNC_DISPLAY(viewer->vnc), fd);
- else
+ } else {
vnc_display_open_host(VNC_DISPLAY(viewer->vnc), host, vncport);
+ }
viewer_set_status(viewer, "Connecting to VNC server");
@@ -896,6 +900,8 @@ static void viewer_deactivate(VirtViewer *viewer)
gtk_main_quit();
}
viewer->active = 0;
+ g_free(viewer->vncAddress);
+ viewer->vncAddress = NULL;
viewer_set_title(viewer, FALSE);
}
@@ -1024,6 +1030,14 @@ viewer_start (const char *uri,
GtkWidget *notebook;
GtkWidget *align;
GtkWidget *menu;
+ int cred_types[] =
+ { VIR_CRED_AUTHNAME, VIR_CRED_PASSPHRASE };
+ virConnectAuth auth_libvirt = {
+ .credtype = cred_types,
+ .ncredtype = ARRAY_CARDINALITY(cred_types),
+ .cb = viewer_auth_libvirt_credentials,
+ .cbdata = (void *)uri,
+ };
doDebug = debug;
@@ -1043,9 +1057,10 @@ viewer_start (const char *uri,
viewer_event_register();
virSetErrorFunc(NULL, viewer_error_func);
- /* XXX write a graphical auth function */
+
viewer->conn = virConnectOpenAuth(uri,
- virConnectAuthPtrDefault,
+ //virConnectAuthPtrDefault,
+ &auth_libvirt,
VIR_CONNECT_RO);
if (!viewer->conn) {
fprintf(stderr, "unable to connect to libvirt %s\n",
@@ -1111,7 +1126,7 @@ viewer_start (const char *uri,
GTK_SIGNAL_FUNC(viewer_key_ungrab), viewer);
g_signal_connect(GTK_OBJECT(viewer->vnc), "vnc-auth-credential",
- GTK_SIGNAL_FUNC(viewer_auth_vnc_credentials), NULL);
+ GTK_SIGNAL_FUNC(viewer_auth_vnc_credentials), &viewer->vncAddress);
notebook = glade_xml_get_widget(viewer->glade, "notebook");