[PATCH 20/25] Replace 'auth_cred' operation with a signal
- From: "Daniel P. Berrange" <berrange redhat com>
- To: gtk-vnc-list gnome org
- Cc: "Daniel P. Berrange" <berrange redhat com>
- Subject: [PATCH 20/25] Replace 'auth_cred' operation with a signal
- Date: Sat, 21 Nov 2009 13:28:09 +0000
Remove the 'auth_cred' operation in VncConnection. Introduce a
new 'vnc-auth-credential' signal
---
src/vncconnection.c | 231 ++++++++++++++++++++++++++------------------
src/vncconnection.h | 22 ++---
src/vncdisplay.c | 127 ++-----------------------
src/vncimageframebuffer.c | 2 +
4 files changed, 155 insertions(+), 227 deletions(-)
diff --git a/src/vncconnection.c b/src/vncconnection.c
index 587c170..3def590 100644
--- a/src/vncconnection.c
+++ b/src/vncconnection.c
@@ -52,6 +52,10 @@
#include <sasl/sasl.h>
#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
#include <zlib.h>
#include <gdk/gdkkeysyms.h>
@@ -198,13 +202,14 @@ enum {
VNC_AUTH_FAILURE,
VNC_AUTH_UNSUPPORTED,
+ VNC_AUTH_CREDENTIAL,
VNC_LAST_SIGNAL,
};
static guint signals[VNC_LAST_SIGNAL] = { 0, 0, 0, 0,
0, 0, 0, 0,
- 0, };
+ 0, 0, };
#define nibhi(a) (((a) >> 4) & 0x0F)
#define niblo(a) ((a) & 0x0F)
@@ -390,6 +395,7 @@ struct signal_data
VncPixelFormat *pixelFormat;
const char *authReason;
unsigned int authUnsupported;
+ GValueArray *authCred;
} params;
};
@@ -464,6 +470,13 @@ static gboolean do_vnc_connection_emit_main_context(gpointer opaque)
data->params.authUnsupported);
break;
+ case VNC_AUTH_CREDENTIAL:
+ g_signal_emit(G_OBJECT(data->conn),
+ signals[data->signum],
+ 0,
+ data->params.authCred);
+ break;
+
}
coroutine_yieldto(data->caller, NULL);
@@ -2576,27 +2589,6 @@ gboolean vnc_connection_server_message(VncConnection *conn)
return !vnc_connection_has_error(conn);
}
-gboolean vnc_connection_wants_credential_password(VncConnection *conn)
-{
- VncConnectionPrivate *priv = conn->priv;
-
- return priv->want_cred_password;
-}
-
-gboolean vnc_connection_wants_credential_username(VncConnection *conn)
-{
- VncConnectionPrivate *priv = conn->priv;
-
- return priv->want_cred_username;
-}
-
-gboolean vnc_connection_wants_credential_x509(VncConnection *conn)
-{
- VncConnectionPrivate *priv = conn->priv;
-
- return priv->want_cred_x509;
-}
-
static gboolean vnc_connection_has_credentials(gpointer data)
{
VncConnection *conn = data;
@@ -2604,9 +2596,9 @@ static gboolean vnc_connection_has_credentials(gpointer data)
if (priv->has_error)
return TRUE;
- if (vnc_connection_wants_credential_username(conn) && !priv->cred_username)
+ if (priv->want_cred_username && !priv->cred_username)
return FALSE;
- if (vnc_connection_wants_credential_password(conn) && !priv->cred_password)
+ if (priv->want_cred_password && !priv->cred_password)
return FALSE;
/*
* For x509 we require a minimum of the CA cert.
@@ -2616,7 +2608,7 @@ static gboolean vnc_connection_has_credentials(gpointer data)
* alone though - we'll merely find out when TLS
* negotiation takes place.
*/
- if (vnc_connection_wants_credential_x509(conn) && !priv->cred_x509_cacert)
+ if (priv->want_cred_x509 && !priv->cred_x509_cacert)
return FALSE;
return TRUE;
}
@@ -2625,14 +2617,41 @@ static gboolean vnc_connection_gather_credentials(VncConnection *conn)
{
VncConnectionPrivate *priv = conn->priv;
+ if (priv->has_error)
+ return FALSE;
+
if (!vnc_connection_has_credentials(conn)) {
- GVNC_DEBUG("Requesting missing credentials");
- if (priv->has_error || !priv->ops.auth_cred) {
- priv->has_error = TRUE;
- return FALSE;
+ GValueArray *authCred;
+ GValue username, password, clientname;
+ struct signal_data sigdata;
+
+ memset(&username, 0, sizeof(username));
+ memset(&password, 0, sizeof(password));
+ memset(&clientname, 0, sizeof(clientname));
+
+ authCred = g_value_array_new(0);
+ if (priv->want_cred_username) {
+ g_value_init(&username, VNC_TYPE_CONNECTION_CREDENTIAL);
+ g_value_set_enum(&username, VNC_CONNECTION_CREDENTIAL_USERNAME);
+ authCred = g_value_array_append(authCred, &username);
}
- if (!priv->ops.auth_cred(priv->ops_data))
- priv->has_error = TRUE;
+ if (priv->want_cred_password) {
+ g_value_init(&password, VNC_TYPE_CONNECTION_CREDENTIAL);
+ g_value_set_enum(&password, VNC_CONNECTION_CREDENTIAL_PASSWORD);
+ authCred = g_value_array_append(authCred, &password);
+ }
+ if (priv->want_cred_x509) {
+ g_value_init(&clientname, VNC_TYPE_CONNECTION_CREDENTIAL);
+ g_value_set_enum(&clientname, VNC_CONNECTION_CREDENTIAL_CLIENTNAME);
+ authCred = g_value_array_append(authCred, &clientname);
+ }
+
+ sigdata.params.authCred = authCred;
+ GVNC_DEBUG("Requesting missing credentials");
+ vnc_connection_emit_main_context(conn, VNC_AUTH_CREDENTIAL, &sigdata);
+
+ g_value_array_free(authCred);
+
if (priv->has_error)
return FALSE;
GVNC_DEBUG("Waiting for missing credentials");
@@ -3817,6 +3836,17 @@ static void vnc_connection_class_init(VncConnectionClass *klass)
1,
G_TYPE_UINT);
+ signals[VNC_AUTH_CREDENTIAL] =
+ g_signal_new ("vnc-auth-credential",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (VncConnectionClass, vnc_auth_credential),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_VALUE_ARRAY);
+
g_type_class_add_private(klass, sizeof(VncConnectionPrivate));
}
@@ -4242,88 +4272,99 @@ gboolean vnc_connection_set_auth_subtype(VncConnection *conn, unsigned int type)
return !vnc_connection_has_error(conn);
}
-gboolean vnc_connection_set_credential_password(VncConnection *conn, const char *password)
-{
- VncConnectionPrivate *priv = conn->priv;
- GVNC_DEBUG("Set password credential %s", password);
- if (priv->cred_password)
- g_free(priv->cred_password);
- if (!(priv->cred_password = g_strdup(password))) {
- priv->has_error = TRUE;
- return FALSE;
- }
- return TRUE;
+static int vnc_connection_best_path(char **buf,
+ const char *basedir,
+ const char *basefile,
+ char **dirs,
+ unsigned int ndirs)
+{
+ unsigned int i;
+ gchar *tmp;
+ for (i = 0 ; i < ndirs ; i++) {
+ struct stat sb;
+ tmp = g_strdup_printf("%s/%s/%s", dirs[i], basedir, basefile);
+ if (stat(tmp, &sb) == 0) {
+ *buf = tmp;
+ return 0;
+ }
+ g_free(tmp);
+ }
+ return -1;
}
-gboolean vnc_connection_set_credential_username(VncConnection *conn, const char *username)
-{
- VncConnectionPrivate *priv = conn->priv;
- GVNC_DEBUG("Set username credential %s", username);
- if (priv->cred_username)
- g_free(priv->cred_username);
- if (!(priv->cred_username = g_strdup(username))) {
- priv->has_error = TRUE;
- return FALSE;
- }
- return TRUE;
-}
-gboolean vnc_connection_set_credential_x509_cacert(VncConnection *conn, const char *file)
+static gboolean vnc_connection_set_credential_x509(VncConnection *conn,
+ const gchar *name)
{
VncConnectionPrivate *priv = conn->priv;
+ char sysdir[PATH_MAX];
+#ifndef WIN32
+ char userdir[PATH_MAX];
+ struct passwd *pw;
+ char *dirs[] = { sysdir, userdir };
+#else
+ char *dirs[] = { sysdir };
+#endif
- GVNC_DEBUG("Set x509 cacert %s", file);
- if (priv->cred_x509_cacert)
- g_free(priv->cred_x509_cacert);
- if (!(priv->cred_x509_cacert = g_strdup(file))) {
- priv->has_error = TRUE;
- return FALSE;
- }
- return TRUE;
-}
+ strncpy(sysdir, SYSCONFDIR "/pki", PATH_MAX-1);
+ sysdir[PATH_MAX-1] = '\0';
-gboolean vnc_connection_set_credential_x509_cacrl(VncConnection *conn, const char *file)
-{
- VncConnectionPrivate *priv = conn->priv;
+#ifndef WIN32
+ if (!(pw = getpwuid(getuid())))
+ return FALSE;
- GVNC_DEBUG("Set x509 cacrl %s", file);
- if (priv->cred_x509_cacrl)
- g_free(priv->cred_x509_cacrl);
- if (!(priv->cred_x509_cacrl = g_strdup(file))) {
- priv->has_error = TRUE;
- return FALSE;
- }
- return TRUE;
-}
+ snprintf(userdir, PATH_MAX-1, "%s/.pki", pw->pw_dir);
+ userdir[PATH_MAX-1] = '\0';
+#endif
-gboolean vnc_connection_set_credential_x509_key(VncConnection *conn, const char *file)
-{
- VncConnectionPrivate *priv = conn->priv;
+ if (vnc_connection_best_path(&priv->cred_x509_cacert, "CA", "cacert.pem",
+ dirs, sizeof(dirs)/sizeof(dirs[0])) < 0)
+ return FALSE;
- GVNC_DEBUG("Set x509 key %s", file);
- if (priv->cred_x509_key)
- g_free(priv->cred_x509_key);
- if (!(priv->cred_x509_key = g_strdup(file))) {
- priv->has_error = TRUE;
- return FALSE;
- }
- return TRUE;
+ /* Don't mind failures of CRL */
+ vnc_connection_best_path(&priv->cred_x509_cacrl, "CA", "cacrl.pem",
+ dirs, sizeof(dirs)/sizeof(dirs[0]));
+
+ /* Set client key & cert if we have them. Server will reject auth
+ * if it decides it requires them*/
+ vnc_connection_best_path(&priv->cred_x509_key, name, "private/clientkey.pem",
+ dirs, sizeof(dirs)/sizeof(dirs[0]));
+ vnc_connection_best_path(&priv->cred_x509_cert, name, "clientcert.pem",
+ dirs, sizeof(dirs)/sizeof(dirs[0]));
+
+ return TRUE;
}
-gboolean vnc_connection_set_credential_x509_cert(VncConnection *conn, const char *file)
+gboolean vnc_connection_set_credential(VncConnection *conn, int type, const gchar *data)
{
VncConnectionPrivate *priv = conn->priv;
- GVNC_DEBUG("Set x509 cert %s", file);
- if (priv->cred_x509_cert)
+ GVNC_DEBUG("Set credential %d %s", type, data);
+ switch (type) {
+ case VNC_CONNECTION_CREDENTIAL_PASSWORD:
+ g_free(priv->cred_password);
+ priv->cred_password = g_strdup(data);
+ break;
+
+ case VNC_CONNECTION_CREDENTIAL_USERNAME:
+ g_free(priv->cred_username);
+ priv->cred_username = g_strdup(data);
+ break;
+
+ case VNC_CONNECTION_CREDENTIAL_CLIENTNAME:
+ g_free(priv->cred_x509_cacert);
+ g_free(priv->cred_x509_cacrl);
+ g_free(priv->cred_x509_key);
g_free(priv->cred_x509_cert);
- if (!(priv->cred_x509_cert = g_strdup(file))) {
- priv->has_error = TRUE;
- return FALSE;
- }
- return TRUE;
+ return vnc_connection_set_credential_x509(conn, data);
+
+ default:
+ priv->has_error = TRUE;
+ }
+
+ return !vnc_connection_has_error(conn);
}
diff --git a/src/vncconnection.h b/src/vncconnection.h
index bd8532f..866d461 100644
--- a/src/vncconnection.h
+++ b/src/vncconnection.h
@@ -61,13 +61,13 @@ struct _VncConnectionClass
void (*vnc_pixel_format_changed)(VncConnection *conn, VncPixelFormat *format);
void (*vnc_auth_failure)(VncConnection *conn, const char *reason);
void (*vnc_auth_unsupported)(VncConnection *conn, unsigned int authType);
+ void (*vnc_auth_credential)(VncConnection *conn, GValueArray *creds);
};
typedef void (rgb24_render_func)(void *, int, int, int, int, guint8 *, int);
struct vnc_connection_ops
{
- gboolean (*auth_cred)(void *);
gboolean (*auth_type)(void *, unsigned int, unsigned int *);
gboolean (*auth_subtype)(void *, unsigned int, unsigned int *);
gboolean (*set_color_map_entry)(void *, int, int, int, int);
@@ -135,6 +135,14 @@ typedef enum {
GVNC_AUTH_VENCRYPT_TLSSASL = 264,
} VncConnectionAuthVencrypt;
+typedef enum
+{
+ VNC_CONNECTION_CREDENTIAL_PASSWORD,
+ VNC_CONNECTION_CREDENTIAL_USERNAME,
+ VNC_CONNECTION_CREDENTIAL_CLIENTNAME,
+} VncConnectionCredential;
+
+
GType vnc_connection_get_type(void) G_GNUC_CONST;
VncConnection *vnc_connection_new(const struct vnc_connection_ops *ops, gpointer ops_data);
@@ -148,17 +156,7 @@ gboolean vnc_connection_is_open(VncConnection *conn);
gboolean vnc_connection_set_auth_type(VncConnection *conn, unsigned int type);
gboolean vnc_connection_set_auth_subtype(VncConnection *conn, unsigned int type);
-
-gboolean vnc_connection_set_credential_password(VncConnection *conn, const char *password);
-gboolean vnc_connection_set_credential_username(VncConnection *conn, const char *username);
-gboolean vnc_connection_set_credential_x509_cacert(VncConnection *conn, const char *file);
-gboolean vnc_connection_set_credential_x509_cacrl(VncConnection *conn, const char *file);
-gboolean vnc_connection_set_credential_x509_key(VncConnection *conn, const char *file);
-gboolean vnc_connection_set_credential_x509_cert(VncConnection *conn, const char *file);
-
-gboolean vnc_connection_wants_credential_password(VncConnection *conn);
-gboolean vnc_connection_wants_credential_username(VncConnection *conn);
-gboolean vnc_connection_wants_credential_x509(VncConnection *conn);
+gboolean vnc_connection_set_credential(VncConnection *conn, int type, const gchar *data);
gboolean vnc_connection_initialize(VncConnection *conn, gboolean shared_flag);
gboolean vnc_connection_is_initialized(VncConnection *conn);
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index 0d46119..eeaf524 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -40,9 +40,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
@@ -882,12 +879,6 @@ static gboolean emit_signal_auth_cred(gpointer opaque)
struct signal_data *s = opaque;
switch (s->signum) {
- case VNC_AUTH_CREDENTIAL:
- g_signal_emit(G_OBJECT(s->obj),
- signals[VNC_AUTH_CREDENTIAL],
- 0,
- s->cred_list);
- break;
case VNC_CONNECTED:
case VNC_INITIALIZED:
case VNC_DISCONNECTED:
@@ -1092,40 +1083,13 @@ static void on_pointer_mode_changed(VncConnection *conn G_GNUC_UNUSED,
do_pointer_show(obj);
}
-static gboolean on_auth_cred(void *opaque)
+static void on_auth_cred(VncConnection *conn G_GNUC_UNUSED,
+ GValueArray *creds,
+ gpointer opaque)
{
VncDisplay *obj = VNC_DISPLAY(opaque);
- GValueArray *cred_list;
- GValue username, password, clientname;
- struct signal_data s;
-
- memset(&username, 0, sizeof(username));
- memset(&password, 0, sizeof(password));
- memset(&clientname, 0, sizeof(clientname));
-
- cred_list = g_value_array_new(0);
- if (vnc_connection_wants_credential_username(obj->priv->conn)) {
- g_value_init(&username, VNC_TYPE_DISPLAY_CREDENTIAL);
- g_value_set_enum(&username, VNC_DISPLAY_CREDENTIAL_USERNAME);
- cred_list = g_value_array_append(cred_list, &username);
- }
- if (vnc_connection_wants_credential_password(obj->priv->conn)) {
- g_value_init(&password, VNC_TYPE_DISPLAY_CREDENTIAL);
- g_value_set_enum(&password, VNC_DISPLAY_CREDENTIAL_PASSWORD);
- cred_list = g_value_array_append(cred_list, &password);
- }
- if (vnc_connection_wants_credential_x509(obj->priv->conn)) {
- g_value_init(&clientname, VNC_TYPE_DISPLAY_CREDENTIAL);
- g_value_set_enum(&clientname, VNC_DISPLAY_CREDENTIAL_CLIENTNAME);
- cred_list = g_value_array_append(cred_list, &clientname);
- }
-
- s.cred_list = cred_list;
- emit_signal_delayed(obj, VNC_AUTH_CREDENTIAL, &s);
-
- g_value_array_free(cred_list);
- return TRUE;
+ g_signal_emit(G_OBJECT(obj), signals[VNC_AUTH_CREDENTIAL], 0, creds);
}
static gboolean on_auth_type(void *opaque, unsigned int ntype, unsigned int *types)
@@ -1310,7 +1274,6 @@ static gboolean on_render_jpeg(void *opaque G_GNUC_UNUSED,
}
static const struct vnc_connection_ops vnc_display_ops = {
- .auth_cred = on_auth_cred,
.auth_type = on_auth_type,
.auth_subtype = on_auth_subtype,
.render_jpeg = on_render_jpeg,
@@ -2020,89 +1983,13 @@ static void vnc_display_init(VncDisplay *display)
G_CALLBACK(on_auth_failure), display);
g_signal_connect(G_OBJECT(priv->conn), "vnc-auth-unsupported",
G_CALLBACK(on_auth_unsupported), display);
-}
-
-static int vnc_display_best_path(char *buf,
- int buflen,
- const char *basedir,
- const char *basefile,
- char **dirs,
- unsigned int ndirs)
-{
- unsigned int i;
- for (i = 0 ; i < ndirs ; i++) {
- struct stat sb;
- snprintf(buf, buflen-1, "%s/%s/%s", dirs[i], basedir, basefile);
- buf[buflen-1] = '\0';
- if (stat(buf, &sb) == 0)
- return 0;
- }
- return -1;
-}
-
-static int vnc_display_set_x509_credential(VncDisplay *obj, const char *name)
-{
- char file[PATH_MAX];
- char sysdir[PATH_MAX];
-#ifndef WIN32
- char userdir[PATH_MAX];
- struct passwd *pw;
- char *dirs[] = { sysdir, userdir };
-#else
- char *dirs[] = { sysdir };
-#endif
-
- strncpy(sysdir, SYSCONFDIR "/pki", PATH_MAX-1);
- sysdir[PATH_MAX-1] = '\0';
-
-#ifndef WIN32
- if (!(pw = getpwuid(getuid())))
- return TRUE;
-
- snprintf(userdir, PATH_MAX-1, "%s/.pki", pw->pw_dir);
- userdir[PATH_MAX-1] = '\0';
-#endif
-
- if (vnc_display_best_path(file, PATH_MAX, "CA", "cacert.pem",
- dirs, sizeof(dirs)/sizeof(dirs[0])) < 0)
- return TRUE;
- vnc_connection_set_credential_x509_cacert(obj->priv->conn, file);
-
- /* Don't mind failures of CRL */
- if (vnc_display_best_path(file, PATH_MAX, "CA", "cacrl.pem",
- dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
- vnc_connection_set_credential_x509_cacert(obj->priv->conn, file);
-
- /* Set client key & cert if we have them. Server will reject auth
- * if it decides it requires them*/
- if (vnc_display_best_path(file, PATH_MAX, name, "private/clientkey.pem",
- dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
- vnc_connection_set_credential_x509_key(obj->priv->conn, file);
- if (vnc_display_best_path(file, PATH_MAX, name, "clientcert.pem",
- dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
- vnc_connection_set_credential_x509_cert(obj->priv->conn, file);
-
- return FALSE;
+ g_signal_connect(G_OBJECT(priv->conn), "vnc-auth-credential",
+ G_CALLBACK(on_auth_cred), display);
}
gboolean vnc_display_set_credential(VncDisplay *obj, int type, const gchar *data)
{
- switch (type) {
- case VNC_DISPLAY_CREDENTIAL_PASSWORD:
- if (vnc_connection_set_credential_password(obj->priv->conn, data))
- return FALSE;
- return TRUE;
-
- case VNC_DISPLAY_CREDENTIAL_USERNAME:
- if (vnc_connection_set_credential_username(obj->priv->conn, data))
- return FALSE;
- return TRUE;
-
- case VNC_DISPLAY_CREDENTIAL_CLIENTNAME:
- return vnc_display_set_x509_credential(obj, data);
- }
-
- return FALSE;
+ return !vnc_connection_set_credential(obj->priv->conn, type, data);
}
void vnc_display_set_pointer_local(VncDisplay *obj, gboolean enable)
diff --git a/src/vncimageframebuffer.c b/src/vncimageframebuffer.c
index 1a71707..4a38c93 100644
--- a/src/vncimageframebuffer.c
+++ b/src/vncimageframebuffer.c
@@ -150,6 +150,8 @@ VncImageFramebuffer *vnc_image_framebuffer_new(GdkImage *image,
localFormat.bits_per_pixel = image->bpp * 8;
localFormat.byte_order = image->byte_order == GDK_LSB_FIRST ? G_LITTLE_ENDIAN : G_BIG_ENDIAN;
+ memset(image->mem, 0, image->bpl * image->height);
+
return VNC_IMAGE_FRAMEBUFFER(g_object_new(VNC_TYPE_IMAGE_FRAMEBUFFER,
"image", image,
"buffer", (guint8 *)image->mem,
--
1.6.5.2
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]