mirror of
https://gitlab.com/virt-viewer/virt-viewer.git
synced 2025-01-11 05:17:45 +03:00
Ensure auth popup windows have correct transient parent
This commit is contained in:
parent
28830c8596
commit
0fa4d098f9
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user