Ensure auth popup windows have correct transient parent

This commit is contained in:
Daniel P. Berrange 2012-02-08 19:33:40 +00:00
parent 28830c8596
commit 0fa4d098f9
9 changed files with 173 additions and 125 deletions

View File

@ -623,16 +623,18 @@ virt_viewer_app_create_session(VirtViewerApp *self, const gchar *type)
#ifdef HAVE_GTK_VNC
if (g_ascii_strcasecmp(type, "vnc") == 0) {
GtkWindow *window = virt_viewer_window_get_window(priv->main_window);
virt_viewer_app_trace(self, "Guest %s has a %s display\n",
priv->guest_name, type);
priv->session = virt_viewer_session_vnc_new();
priv->session = virt_viewer_session_vnc_new(window);
} else
#endif
#ifdef HAVE_SPICE_GTK
if (g_ascii_strcasecmp(type, "spice") == 0) {
GtkWindow *window = virt_viewer_window_get_window(priv->main_window);
virt_viewer_app_trace(self, "Guest %s has a %s display\n",
priv->guest_name, type);
priv->session = virt_viewer_session_spice_new();
priv->session = virt_viewer_session_spice_new(window);
} else
#endif
{

View File

@ -33,7 +33,8 @@
int
virt_viewer_auth_collect_credentials(const char *type,
virt_viewer_auth_collect_credentials(GtkWindow *window,
const char *type,
const char *address,
char **username,
char **password)
@ -50,6 +51,7 @@ virt_viewer_auth_collect_credentials(const char *type,
dialog = GTK_WIDGET(gtk_builder_get_object(creds, "auth"));
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
gtk_window_set_transient_for(GTK_WINDOW(dialog), window);
labelMessage = GTK_WIDGET(gtk_builder_get_object(creds, "message"));
credUsername = GTK_WIDGET(gtk_builder_get_object(creds, "cred-username"));
@ -93,9 +95,10 @@ virt_viewer_auth_collect_credentials(const char *type,
#ifdef HAVE_GTK_VNC
void
virt_viewer_auth_vnc_credentials(GtkWidget *vnc,
virt_viewer_auth_vnc_credentials(GtkWindow *window,
GtkWidget *vnc,
GValueArray *credList,
char **vncAddress)
char *vncAddress)
{
char *username = NULL, *password = NULL;
gboolean wantPassword = FALSE, wantUsername = FALSE;
@ -122,7 +125,8 @@ virt_viewer_auth_vnc_credentials(GtkWidget *vnc,
}
if (wantUsername || wantPassword) {
int ret = virt_viewer_auth_collect_credentials("VNC", vncAddress ? *vncAddress : NULL,
int ret = virt_viewer_auth_collect_credentials(window,
"VNC", vncAddress,
wantUsername ? &username : NULL,
wantPassword ? &password : NULL);
@ -173,64 +177,6 @@ virt_viewer_auth_vnc_credentials(GtkWidget *vnc,
}
#endif
#ifdef HAVE_LIBVIRT
int
virt_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 = virt_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;
}
#endif
/*
* Local variables:
* c-indent-level: 4

View File

@ -31,21 +31,17 @@
#include "virt-viewer-util.h"
void virt_viewer_auth_vnc_credentials(GtkWidget *vnc,
void virt_viewer_auth_vnc_credentials(GtkWindow *window,
GtkWidget *vnc,
GValueArray *credList,
char **message);
char *vncAddress);
int virt_viewer_auth_collect_credentials(const char *type,
int virt_viewer_auth_collect_credentials(GtkWindow *window,
const char *type,
const char *address,
char **username,
char **password);
#ifdef HAVE_LIBVIRT
int virt_viewer_auth_libvirt_credentials(virConnectCredentialPtr cred,
unsigned int ncred,
void *cbdata);
#endif
#endif
/*
* Local variables:

View File

@ -1,31 +1,86 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkDialog" id="auth">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Authentication required</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
<object class="GtkBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button-cancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button-ok">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="message">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">label</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
@ -33,6 +88,7 @@
<child>
<object class="GtkLabel" id="prompt-password">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Password:</property>
</object>
@ -44,6 +100,7 @@
<child>
<object class="GtkLabel" id="prompt-username">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Username:</property>
</object>
@ -73,49 +130,10 @@
</packing>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button-cancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button-ok">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>

View File

@ -38,6 +38,7 @@ G_DEFINE_TYPE (VirtViewerSessionSpice, virt_viewer_session_spice, VIRT_VIEWER_TY
struct _VirtViewerSessionSpicePrivate {
GtkWindow *main_window;
SpiceSession *session;
SpiceGtkSession *gtk_session;
SpiceMainChannel *main_channel;
@ -106,6 +107,8 @@ virt_viewer_session_spice_dispose(GObject *obj)
g_object_unref(spice->priv->audio);
if (spice->priv->main_channel)
g_object_unref(spice->priv->main_channel);
if (spice->priv->main_window)
g_object_unref(spice->priv->main_window);
G_OBJECT_CLASS(virt_viewer_session_spice_parent_class)->finalize(obj);
}
@ -298,7 +301,8 @@ virt_viewer_session_spice_main_channel_event(SpiceChannel *channel G_GNUC_UNUSED
break;
case SPICE_CHANNEL_ERROR_AUTH:
DEBUG_LOG("main channel: auth failure (wrong password?)");
int ret = virt_viewer_auth_collect_credentials("SPICE",
int ret = virt_viewer_auth_collect_credentials(self->priv->main_window,
"SPICE",
NULL,
NULL, &password);
if (ret < 0) {
@ -444,13 +448,14 @@ virt_viewer_session_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s,
}
VirtViewerSession *
virt_viewer_session_spice_new(void)
virt_viewer_session_spice_new(GtkWindow *main_window)
{
VirtViewerSessionSpice *self;
self = g_object_new(VIRT_VIEWER_TYPE_SESSION_SPICE, NULL);
create_spice_session(self);
self->priv->main_window = g_object_ref(main_window);
return VIRT_VIEWER_SESSION(self);
}

View File

@ -65,7 +65,7 @@ struct _VirtViewerSessionSpiceClass {
GType virt_viewer_session_spice_get_type(void);
VirtViewerSession* virt_viewer_session_spice_new(void);
VirtViewerSession* virt_viewer_session_spice_new(GtkWindow *main_window);
SpiceMainChannel* virt_viewer_session_spice_get_main_channel(VirtViewerSessionSpice *self);
G_END_DECLS

View File

@ -34,6 +34,7 @@
G_DEFINE_TYPE(VirtViewerSessionVnc, virt_viewer_session_vnc, VIRT_VIEWER_TYPE_SESSION)
struct _VirtViewerSessionVncPrivate {
GtkWindow *main_window;
/* XXX we should really just have a VncConnection */
VncDisplay *vnc;
};
@ -57,6 +58,8 @@ virt_viewer_session_vnc_finalize(GObject *obj)
vnc_display_close(vnc->priv->vnc);
g_object_unref(vnc->priv->vnc);
}
if (vnc->priv->main_window)
g_object_unref(vnc->priv->main_window);
G_OBJECT_CLASS(virt_viewer_session_vnc_parent_class)->finalize(obj);
}
@ -208,6 +211,21 @@ virt_viewer_session_vnc_open_uri(VirtViewerSession* session,
return ret;
}
static void
virt_viewer_session_vnc_auth_credential(GtkWidget *src,
GValueArray *credList,
VirtViewerSession *session)
{
VirtViewerSessionVnc *self = VIRT_VIEWER_SESSION_VNC(session);
virt_viewer_auth_vnc_credentials(self->priv->main_window,
src,
credList,
NULL);
}
static void
virt_viewer_session_vnc_close(VirtViewerSession* session)
{
@ -240,18 +258,19 @@ virt_viewer_session_vnc_close(VirtViewerSession* session)
G_CALLBACK(virt_viewer_session_vnc_cut_text), session);
g_signal_connect(self->priv->vnc, "vnc-auth-credential",
G_CALLBACK(virt_viewer_auth_vnc_credentials), NULL);
G_CALLBACK(virt_viewer_session_vnc_auth_credential), session);
}
VirtViewerSession *
virt_viewer_session_vnc_new(void)
virt_viewer_session_vnc_new(GtkWindow *main_window)
{
VirtViewerSessionVnc *session;
session = g_object_new(VIRT_VIEWER_TYPE_SESSION_VNC, NULL);
session->priv->vnc = VNC_DISPLAY(vnc_display_new());
session->priv->main_window = g_object_ref(main_window);
g_signal_connect(session->priv->vnc, "vnc-connected",
G_CALLBACK(virt_viewer_session_vnc_connected), session);
@ -270,7 +289,7 @@ virt_viewer_session_vnc_new(void)
G_CALLBACK(virt_viewer_session_vnc_cut_text), session);
g_signal_connect(session->priv->vnc, "vnc-auth-credential",
G_CALLBACK(virt_viewer_auth_vnc_credentials), NULL);
G_CALLBACK(virt_viewer_session_vnc_auth_credential), session);
return VIRT_VIEWER_SESSION(session);
}

View File

@ -64,7 +64,7 @@ struct _VirtViewerSessionVncClass {
GType virt_viewer_session_vnc_get_type(void);
VirtViewerSession *virt_viewer_session_vnc_new(void);
VirtViewerSession *virt_viewer_session_vnc_new(GtkWindow *main_window);
G_END_DECLS

View File

@ -524,6 +524,68 @@ virt_viewer_error_func (void *data G_GNUC_UNUSED,
/* nada */
}
static int
virt_viewer_auth_libvirt_credentials(virConnectCredentialPtr cred,
unsigned int ncred,
void *cbdata)
{
char **username = NULL, **password = NULL;
VirtViewer *app = 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) {
VirtViewerWindow *vwin = virt_viewer_app_get_main_window(VIRT_VIEWER_APP(app));
GtkWindow *win = virt_viewer_window_get_window(vwin);
ret = virt_viewer_auth_collect_credentials(win,
"libvirt",
app->priv->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;
}
static gboolean
virt_viewer_start(VirtViewerApp *app)
{
@ -535,7 +597,7 @@ virt_viewer_start(VirtViewerApp *app)
.credtype = cred_types,
.ncredtype = ARRAY_CARDINALITY(cred_types),
.cb = virt_viewer_auth_libvirt_credentials,
.cbdata = (void *)priv->uri,
.cbdata = app,
};
int oflags = 0;