mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/virt-viewer
synced 2025-12-28 07:06:04 +00:00
Add support for libvirt graphical auth
This commit is contained in:
parent
852825ae5e
commit
bc55a8d757
212
src/auth.c
212
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;
|
||||
int ret = viewer_auth_collect_credentials("VNC", vncAddress ? *vncAddress : NULL,
|
||||
wantUsername ? &username : NULL,
|
||||
wantPassword ? &password : NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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]) {
|
||||
if (vnc_display_set_credential(VNC_DISPLAY(vnc),
|
||||
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),
|
||||
data[i])) {
|
||||
username)) {
|
||||
DEBUG_LOG("Failed to set credential type %d", g_value_get_enum(cred));
|
||||
vnc_display_close(VNC_DISPLAY(vnc));
|
||||
}
|
||||
} else {
|
||||
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),
|
||||
"libvirt")) {
|
||||
DEBUG_LOG("Failed to set credential type %d", g_value_get_enum(cred));
|
||||
vnc_display_close(VNC_DISPLAY(vnc));
|
||||
}
|
||||
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:
|
||||
*/
|
||||
|
||||
@ -12,6 +12,18 @@
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<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>
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
25
src/viewer.c
25
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");
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user