[seahorse-plugins] Use GTK+ GtkEntryBuffer for secure password entry.



commit ed6f046ff86e34925acb8ec045b150d26137d472
Author: Adam Schreiber <sadam gnome org>
Date:   Sun Jan 24 21:22:24 2010 -0500

    Use GTK+ GtkEntryBuffer for secure password entry.
    
    Remove our own copy of GtkEntry, and use the new GtkEntryBuffer
    in GTK+ 2.18. Bump requred GTK+ version.  These changes are copied
    from seahorse an modified slightly.  The author of
    seahorse-secure-buffer.[ch] is Stef Walter.

 libseahorse/Makefile.am              |    2 +-
 libseahorse/seahorse-passphrase.c    |   31 +-
 libseahorse/seahorse-prefs.c         |    2 +-
 libseahorse/seahorse-secure-buffer.c |  196 +++
 libseahorse/seahorse-secure-buffer.h |   57 +
 libseahorse/seahorse-secure-entry.c  | 2987 ----------------------------------
 libseahorse/seahorse-secure-entry.h  |  187 ---
 7 files changed, 273 insertions(+), 3189 deletions(-)
---
diff --git a/libseahorse/Makefile.am b/libseahorse/Makefile.am
index ce76704..e0ae1b4 100644
--- a/libseahorse/Makefile.am
+++ b/libseahorse/Makefile.am
@@ -43,7 +43,7 @@ libseahorse_a_SOURCES = \
 	seahorse-gconf.c seahorse-gconf.h \
 	seahorse-gtkstock.c seahorse-gtkstock.h \
 	seahorse-secure-memory.c seahorse-secure-memory.h \
-	seahorse-secure-entry.c seahorse-secure-entry.h \
+	seahorse-secure-buffer.c seahorse-secure-buffer.h \
 	seahorse-algo.c seahorse-algo.h \
 	seahorse-unix-signal.c seahorse-unix-signal.h \
 	$(BUILT_SOURCES) \
diff --git a/libseahorse/seahorse-passphrase.c b/libseahorse/seahorse-passphrase.c
index b9feb0b..5d738d6 100644
--- a/libseahorse/seahorse-passphrase.c
+++ b/libseahorse/seahorse-passphrase.c
@@ -46,7 +46,7 @@
 #include "seahorse-widget.h"
 #include "seahorse-util.h"
 #include "seahorse-passphrase.h"
-#include "seahorse-secure-entry.h"
+#include "seahorse-secure-buffer.h"
 #include "seahorse-gpg-options.h"
 #include "agent/seahorse-agent.h"
 
@@ -122,7 +122,7 @@ static void
 confirm_callback (GtkWidget *widget, GtkDialog *dialog)
 {
     GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
-    g_assert (SEAHORSE_IS_SECURE_ENTRY (entry));
+    g_assert (GTK_IS_ENTRY (entry));
     gtk_widget_grab_focus (entry);
 }
 
@@ -136,14 +136,14 @@ enter_callback (GtkWidget *widget, GtkDialog *dialog)
 static void
 entry_changed (GtkEditable *editable, GtkDialog *dialog)
 {
-    SeahorseSecureEntry *entry, *confirm;
+    GtkEntry *entry, *confirm;
     
-    entry = SEAHORSE_SECURE_ENTRY (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
-    confirm = SEAHORSE_SECURE_ENTRY (g_object_get_data (G_OBJECT (dialog), "confirm-entry"));
+    entry = GTK_ENTRY (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
+    confirm = GTK_ENTRY (g_object_get_data (G_OBJECT (dialog), "confirm-entry"));
     
     gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_ACCEPT, 
-                                       strcmp (seahorse_secure_entry_get_text (entry), 
-                                               seahorse_secure_entry_get_text (confirm)) == 0);
+                                       strcmp (gtk_entry_get_text (entry), 
+                                               gtk_entry_get_text (confirm)) == 0);
 }
 
 static gboolean
@@ -185,7 +185,8 @@ seahorse_passphrase_prompt_show (const gchar *title, const gchar *description,
                                  const gchar *prompt, const gchar *check,
                                  gboolean confirm)
 {
-    SeahorseSecureEntry *entry;
+    GtkEntryBuffer *buffer;
+    GtkEntry *entry;
     GtkDialog *dialog;
     GtkWidget *w;
     GtkWidget *box;
@@ -251,7 +252,9 @@ seahorse_passphrase_prompt_show (const gchar *title, const gchar *description,
         g_free (msg);
         gtk_table_attach (table, w, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
 
-        entry = SEAHORSE_SECURE_ENTRY (seahorse_secure_entry_new ());
+        buffer = seahorse_secure_buffer_new ();
+        entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer));
+        g_object_unref (buffer);
         gtk_widget_set_size_request (GTK_WIDGET (entry), 200, -1);
         g_object_set_data (G_OBJECT (dialog), "confirm-entry", entry);
         g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (confirm_callback), dialog);
@@ -267,7 +270,9 @@ seahorse_passphrase_prompt_show (const gchar *title, const gchar *description,
     g_free (msg);
     gtk_table_attach (table, w, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
     
-    entry = SEAHORSE_SECURE_ENTRY (seahorse_secure_entry_new ());
+    buffer = seahorse_secure_buffer_new ();
+    entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer));
+    g_object_unref (buffer);
     gtk_widget_set_size_request (GTK_WIDGET (entry), 200, -1);
     g_object_set_data (G_OBJECT (dialog), "secure-entry", entry);
     g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (enter_callback), dialog);
@@ -315,10 +320,10 @@ seahorse_passphrase_prompt_show (const gchar *title, const gchar *description,
 const gchar*
 seahorse_passphrase_prompt_get (GtkDialog *dialog)
 {
-    SeahorseSecureEntry *entry;
+    GtkEntry *entry;
 
-    entry = SEAHORSE_SECURE_ENTRY (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
-    return seahorse_secure_entry_get_text (entry);
+    entry = GTK_ENTRY (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
+    return gtk_entry_get_text (entry);
 }
 
 gboolean
diff --git a/libseahorse/seahorse-prefs.c b/libseahorse/seahorse-prefs.c
index eab846d..44ea4e9 100644
--- a/libseahorse/seahorse-prefs.c
+++ b/libseahorse/seahorse-prefs.c
@@ -32,7 +32,7 @@
 #include "seahorse-check-button-control.h"
 #include "seahorse-gconf.h"
 #include "seahorse-gtkstock.h"
-#include "seahorse-secure-entry.h"
+#include "seahorse-secure-buffer.h"
 #include "seahorse-widget.h"
 
 /* From seahorse-prefs-cache.c */
diff --git a/libseahorse/seahorse-secure-buffer.c b/libseahorse/seahorse-secure-buffer.c
new file mode 100644
index 0000000..8db74f0
--- /dev/null
+++ b/libseahorse/seahorse-secure-buffer.c
@@ -0,0 +1,196 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "seahorse-secure-buffer.h"
+#include <gnome-keyring-memory.h>
+
+#include <string.h>
+
+/* Initial size of buffer, in bytes */
+#define MIN_SIZE 16
+
+struct _SeahorseSecureBufferPrivate
+{
+	gchar *text;
+	gsize text_size;
+	gsize text_bytes;
+	guint text_chars;
+};
+
+G_DEFINE_TYPE (SeahorseSecureBuffer, seahorse_secure_buffer, GTK_TYPE_ENTRY_BUFFER);
+
+/* --------------------------------------------------------------------------------
+ * SECURE IMPLEMENTATIONS OF TEXT BUFFER
+ */
+
+static const gchar*
+seahorse_secure_buffer_real_get_text (GtkEntryBuffer *buffer, gsize *n_bytes)
+{
+	SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (buffer);
+	if (n_bytes)
+		*n_bytes = self->priv->text_bytes;
+	if (!self->priv->text)
+		return "";
+	return self->priv->text;
+}
+
+static guint
+seahorse_secure_buffer_real_get_length (GtkEntryBuffer *buffer)
+{
+	SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (buffer);
+	return self->priv->text_chars;
+}
+
+static guint
+seahorse_secure_buffer_real_insert_text (GtkEntryBuffer *buffer, guint position,
+                                         const gchar *chars, guint n_chars)
+{
+	SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (buffer);
+	SeahorseSecureBufferPrivate *pv = self->priv;
+	gsize n_bytes;
+	gsize at;
+
+	n_bytes = g_utf8_offset_to_pointer (chars, n_chars) - chars;
+
+	/* Need more memory */
+	if (n_bytes + pv->text_bytes + 1 > pv->text_size) {
+
+		/* Calculate our new buffer size */
+		while (n_bytes + pv->text_bytes + 1 > pv->text_size) {
+			if (pv->text_size == 0) {
+				pv->text_size = MIN_SIZE;
+			} else {
+				if (2 * pv->text_size < GTK_ENTRY_BUFFER_MAX_SIZE) {
+					pv->text_size *= 2;
+				} else {
+					pv->text_size = GTK_ENTRY_BUFFER_MAX_SIZE;
+					if (n_bytes > pv->text_size - pv->text_bytes - 1) {
+						n_bytes = pv->text_size - pv->text_bytes - 1;
+						n_bytes = g_utf8_find_prev_char (chars, chars + n_bytes + 1) - chars;
+						n_chars = g_utf8_strlen (chars, n_bytes);
+					}
+					break;
+				}
+			}
+		}
+
+		pv->text = gnome_keyring_memory_realloc (pv->text, pv->text_size);
+	}
+
+	/* Actual text insertion */
+	at = g_utf8_offset_to_pointer (pv->text, position) - pv->text;
+	g_memmove (pv->text + at + n_bytes, pv->text + at, pv->text_bytes - at);
+	memcpy (pv->text + at, chars, n_bytes);
+
+	/* Book keeping */
+	pv->text_bytes += n_bytes;
+	pv->text_chars += n_chars;
+	pv->text[pv->text_bytes] = '\0';
+
+	gtk_entry_buffer_emit_inserted_text (buffer, position, chars, n_chars);
+	return n_chars;
+}
+
+static guint
+seahorse_secure_buffer_real_delete_text (GtkEntryBuffer *buffer, guint position, guint n_chars)
+{
+	SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (buffer);
+	SeahorseSecureBufferPrivate *pv = self->priv;
+	gsize start, end;
+
+	if (position > pv->text_chars)
+		position = pv->text_chars;
+	if (position + n_chars > pv->text_chars)
+		n_chars = pv->text_chars - position;
+
+	if (n_chars > 0) {
+		start = g_utf8_offset_to_pointer (pv->text, position) - pv->text;
+		end = g_utf8_offset_to_pointer (pv->text, position + n_chars) - pv->text;
+
+		g_memmove (pv->text + start, pv->text + end, pv->text_bytes + 1 - end);
+		pv->text_chars -= n_chars;
+		pv->text_bytes -= (end - start);
+
+		gtk_entry_buffer_emit_deleted_text (buffer, position, n_chars);
+	}
+
+	return n_chars;
+}
+
+/* --------------------------------------------------------------------------------
+ *
+ */
+
+static void
+seahorse_secure_buffer_init (SeahorseSecureBuffer *self)
+{
+	SeahorseSecureBufferPrivate *pv;
+	pv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_SECURE_BUFFER, SeahorseSecureBufferPrivate);
+
+	pv->text = NULL;
+	pv->text_chars = 0;
+	pv->text_bytes = 0;
+	pv->text_size = 0;
+}
+
+static void
+seahorse_secure_buffer_finalize (GObject *obj)
+{
+	SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (obj);
+	SeahorseSecureBufferPrivate *pv = self->priv;
+
+	if (pv->text) {
+		gnome_keyring_memory_free (pv->text);
+		pv->text = NULL;
+		pv->text_bytes = pv->text_size = 0;
+		pv->text_chars = 0;
+	}
+
+	G_OBJECT_CLASS (seahorse_secure_buffer_parent_class)->finalize (obj);
+}
+
+static void
+seahorse_secure_buffer_class_init (SeahorseSecureBufferClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	GtkEntryBufferClass *buffer_class = GTK_ENTRY_BUFFER_CLASS (klass);
+
+	gobject_class->finalize = seahorse_secure_buffer_finalize;
+
+	buffer_class->get_text = seahorse_secure_buffer_real_get_text;
+	buffer_class->get_length = seahorse_secure_buffer_real_get_length;
+	buffer_class->insert_text = seahorse_secure_buffer_real_insert_text;
+	buffer_class->delete_text = seahorse_secure_buffer_real_delete_text;
+
+	g_type_class_add_private (gobject_class, sizeof (SeahorseSecureBufferPrivate));
+}
+
+/* --------------------------------------------------------------------------------
+ *
+ */
+
+GtkEntryBuffer*
+seahorse_secure_buffer_new (void)
+{
+	return g_object_new (SEAHORSE_TYPE_SECURE_BUFFER, NULL);
+}
diff --git a/libseahorse/seahorse-secure-buffer.h b/libseahorse/seahorse-secure-buffer.h
new file mode 100644
index 0000000..7c94f8a
--- /dev/null
+++ b/libseahorse/seahorse-secure-buffer.h
@@ -0,0 +1,57 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __SEAHORSE_SECURE_BUFFER_H__
+#define __SEAHORSE_SECURE_BUFFER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define SEAHORSE_TYPE_SECURE_BUFFER            (seahorse_secure_buffer_get_type ())
+#define SEAHORSE_SECURE_BUFFER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_SECURE_BUFFER, SeahorseSecureBuffer))
+#define SEAHORSE_SECURE_BUFFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_SECURE_BUFFER, SeahorseSecureBufferClass))
+#define SEAHORSE_IS_SECURE_BUFFER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_SECURE_BUFFER))
+#define SEAHORSE_IS_SECURE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_SECURE_BUFFER))
+#define SEAHORSE_SECURE_BUFFER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_SECURE_BUFFER, SeahorseSecureBufferClass))
+
+typedef struct _SeahorseSecureBuffer            SeahorseSecureBuffer;
+typedef struct _SeahorseSecureBufferClass       SeahorseSecureBufferClass;
+typedef struct _SeahorseSecureBufferPrivate     SeahorseSecureBufferPrivate;
+
+struct _SeahorseSecureBuffer
+{
+	GtkEntryBuffer parent;
+	SeahorseSecureBufferPrivate *priv;
+};
+
+struct _SeahorseSecureBufferClass
+{
+	GtkEntryBufferClass parent_class;
+};
+
+GType                     seahorse_secure_buffer_get_type               (void) G_GNUC_CONST;
+
+GtkEntryBuffer*           seahorse_secure_buffer_new                    (void);
+
+G_END_DECLS
+
+#endif /* __SEAHORSE_SECURE_BUFFER_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]