[gnome-keyring] [prompt] Use 'secure' memory for buffer for prompt password entries.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring] [prompt] Use 'secure' memory for buffer for prompt password entries.
- Date: Sat, 19 Dec 2009 04:34:27 +0000 (UTC)
commit 224ae44851c96f117dbc72c282998b6c200d7298
Author: Stef Walter <stef memberwebs com>
Date: Sat Dec 19 01:11:05 2009 +0000
[prompt] Use 'secure' memory for buffer for prompt password entries.
daemon/prompt/Makefile.am | 1 +
daemon/prompt/gkd-prompt-buffer.c | 199 +++++++++++++++++++++++++++++++++++++
daemon/prompt/gkd-prompt-buffer.h | 59 +++++++++++
daemon/prompt/gkd-prompt-tool.c | 26 +++++
4 files changed, 285 insertions(+), 0 deletions(-)
---
diff --git a/daemon/prompt/Makefile.am b/daemon/prompt/Makefile.am
index 2269fd0..c739fe2 100644
--- a/daemon/prompt/Makefile.am
+++ b/daemon/prompt/Makefile.am
@@ -61,6 +61,7 @@ libexec_PROGRAMS= \
gnome_keyring_prompt_SOURCES = \
gkd-prompt-tool.c \
+ gkd-prompt-buffer.c gkd-prompt-buffer.h \
gkd-prompt-util.c gkd-prompt-util.h
gnome_keyring_prompt_LDADD = \
diff --git a/daemon/prompt/gkd-prompt-buffer.c b/daemon/prompt/gkd-prompt-buffer.c
new file mode 100644
index 0000000..3e07400
--- /dev/null
+++ b/daemon/prompt/gkd-prompt-buffer.c
@@ -0,0 +1,199 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-secure-buffer.c - secure memory gtkentry buffer
+
+ Copyright (C) 2009 Stefan Walter
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef memberwebs com>
+*/
+
+#include "config.h"
+
+#include "gkd-prompt-buffer.h"
+
+#include "egg/egg-secure-memory.h"
+
+#include <string.h>
+
+/* Initial size of buffer, in bytes */
+#define MIN_SIZE 16
+
+struct _GkdPromptBufferPrivate
+{
+ gchar *text;
+ gsize text_size;
+ gsize text_bytes;
+ guint text_chars;
+};
+
+G_DEFINE_TYPE (GkdPromptBuffer, gkd_prompt_buffer, GTK_TYPE_ENTRY_BUFFER);
+
+/* --------------------------------------------------------------------------------
+ * SECURE IMPLEMENTATIONS OF TEXT BUFFER
+ */
+
+static const gchar*
+gkd_prompt_buffer_real_get_text (GtkEntryBuffer *buffer, gsize *n_bytes)
+{
+ GkdPromptBuffer *self = GKD_PROMPT_BUFFER (buffer);
+ if (n_bytes)
+ *n_bytes = self->priv->text_bytes;
+ if (!self->priv->text)
+ return "";
+ return self->priv->text;
+}
+
+static guint
+gkd_prompt_buffer_real_get_length (GtkEntryBuffer *buffer)
+{
+ GkdPromptBuffer *self = GKD_PROMPT_BUFFER (buffer);
+ return self->priv->text_chars;
+}
+
+static guint
+gkd_prompt_buffer_real_insert_text (GtkEntryBuffer *buffer, guint position,
+ const gchar *chars, guint n_chars)
+{
+ GkdPromptBuffer *self = GKD_PROMPT_BUFFER (buffer);
+ GkdPromptBufferPrivate *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 = egg_secure_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
+gkd_prompt_buffer_real_delete_text (GtkEntryBuffer *buffer, guint position, guint n_chars)
+{
+ GkdPromptBuffer *self = GKD_PROMPT_BUFFER (buffer);
+ GkdPromptBufferPrivate *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
+gkd_prompt_buffer_init (GkdPromptBuffer *self)
+{
+ GkdPromptBufferPrivate *pv;
+ pv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GKD_TYPE_PROMPT_BUFFER, GkdPromptBufferPrivate);
+
+ pv->text = NULL;
+ pv->text_chars = 0;
+ pv->text_bytes = 0;
+ pv->text_size = 0;
+}
+
+static void
+gkd_prompt_buffer_finalize (GObject *obj)
+{
+ GkdPromptBuffer *self = GKD_PROMPT_BUFFER (obj);
+ GkdPromptBufferPrivate *pv = self->priv;
+
+ if (pv->text) {
+ egg_secure_strfree (pv->text);
+ pv->text = NULL;
+ pv->text_bytes = pv->text_size = 0;
+ pv->text_chars = 0;
+ }
+
+ G_OBJECT_CLASS (gkd_prompt_buffer_parent_class)->finalize (obj);
+}
+
+static void
+gkd_prompt_buffer_class_init (GkdPromptBufferClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkEntryBufferClass *buffer_class = GTK_ENTRY_BUFFER_CLASS (klass);
+
+ gobject_class->finalize = gkd_prompt_buffer_finalize;
+
+ buffer_class->get_text = gkd_prompt_buffer_real_get_text;
+ buffer_class->get_length = gkd_prompt_buffer_real_get_length;
+ buffer_class->insert_text = gkd_prompt_buffer_real_insert_text;
+ buffer_class->delete_text = gkd_prompt_buffer_real_delete_text;
+
+ g_type_class_add_private (gobject_class, sizeof (GkdPromptBufferPrivate));
+}
+
+/* --------------------------------------------------------------------------------
+ *
+ */
+
+GtkEntryBuffer*
+gkd_prompt_buffer_new (void)
+{
+ return g_object_new (GKD_TYPE_PROMPT_BUFFER, NULL);
+}
diff --git a/daemon/prompt/gkd-prompt-buffer.h b/daemon/prompt/gkd-prompt-buffer.h
new file mode 100644
index 0000000..35a5884
--- /dev/null
+++ b/daemon/prompt/gkd-prompt-buffer.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-secure-buffer.h - secure memory gtkentry buffer
+
+ Copyright (C) 2009 Stefan Walter
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef memberwebs com>
+*/
+
+#ifndef __GKD_PROMPT_BUFFER_H__
+#define __GKD_PROMPT_BUFFER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GKD_TYPE_PROMPT_BUFFER (gkd_prompt_buffer_get_type ())
+#define GKD_PROMPT_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKD_TYPE_PROMPT_BUFFER, GkdPromptBuffer))
+#define GKD_PROMPT_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKD_TYPE_PROMPT_BUFFER, GkdPromptBufferClass))
+#define GKD_IS_PROMPT_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKD_TYPE_PROMPT_BUFFER))
+#define GKD_IS_PROMPT_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKD_TYPE_PROMPT_BUFFER))
+#define GKD_PROMPT_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKD_TYPE_PROMPT_BUFFER, GkdPromptBufferClass))
+
+typedef struct _GkdPromptBuffer GkdPromptBuffer;
+typedef struct _GkdPromptBufferClass GkdPromptBufferClass;
+typedef struct _GkdPromptBufferPrivate GkdPromptBufferPrivate;
+
+struct _GkdPromptBuffer
+{
+ GtkEntryBuffer parent;
+ GkdPromptBufferPrivate *priv;
+};
+
+struct _GkdPromptBufferClass
+{
+ GtkEntryBufferClass parent_class;
+};
+
+GType gkd_prompt_buffer_get_type (void) G_GNUC_CONST;
+
+GtkEntryBuffer* gkd_prompt_buffer_new (void);
+
+G_END_DECLS
+
+#endif /* __GKD_PROMPT_BUFFER_H__ */
diff --git a/daemon/prompt/gkd-prompt-tool.c b/daemon/prompt/gkd-prompt-tool.c
index 1e360e6..96bb054 100644
--- a/daemon/prompt/gkd-prompt-tool.c
+++ b/daemon/prompt/gkd-prompt-tool.c
@@ -22,6 +22,7 @@
#include "config.h"
+#include "gkd-prompt-buffer.h"
#include "gkd-prompt-util.h"
#include "egg/egg-dh.h"
@@ -188,6 +189,30 @@ prepare_buttons (GtkBuilder *builder, GtkDialog *dialog)
}
static void
+prepare_password_entry (GtkEntry *entry)
+{
+ GtkEntryBuffer *buffer = gkd_prompt_buffer_new ();
+ g_return_if_fail (entry);
+ gtk_entry_set_buffer (entry, buffer);
+ g_object_unref (buffer);
+}
+
+static void
+prepare_passwords (GtkBuilder *builder, GtkDialog *dialog)
+{
+ GtkEntry *entry;
+
+ entry = GTK_ENTRY(gtk_builder_get_object (builder, "password_entry"));
+ prepare_password_entry (entry);
+
+ entry = GTK_ENTRY(gtk_builder_get_object (builder, "original_entry"));
+ prepare_password_entry (entry);
+
+ entry = GTK_ENTRY(gtk_builder_get_object (builder, "confirm_entry"));
+ prepare_password_entry (entry);
+}
+
+static void
prepare_security (GtkBuilder *builder, GtkDialog *dialog)
{
/*
@@ -219,6 +244,7 @@ prepare_dialog (GtkBuilder *builder)
prepare_prompt (builder, dialog);
prepare_visibility (builder, dialog);
prepare_buttons (builder, dialog);
+ prepare_passwords (builder, dialog);
prepare_security (builder, dialog);
return dialog;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]