Commit ed6f046f authored by Adam Schreiber's avatar Adam Schreiber

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.
parent aab8e97a
......@@ -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) \
......
......@@ -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
......
......@@ -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 */
......
/*
* 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);
}
/*
* 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__ */
This diff is collapsed.
/*
* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library 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 of the License, or (at your option) any later version.
*
* This 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
/*
* Heavily stripped down for use in pinentry-gtk-2 by Albrecht Dreß
* <albrecht.dress@arcor.de> Feb. 2004.
*
* (C) by Albrecht Dreß 2004 unter the terms of the GNU Lesser General
* Public License.
*
* The entry is now always invisible, uses secure memory methods to
* allocate the text memory, and all potentially dangerous methods
* (copy & paste, popup, etc.) have been removed.
*/
#ifndef __SEAHORSE_SECURE_ENTRY_H__
#define __SEAHORSE_SECURE_ENTRY_H__
#include <gtk/gtk.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SEAHORSE_TYPE_SECURE_ENTRY (seahorse_secure_entry_get_type ())
#define SEAHORSE_SECURE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_SECURE_ENTRY, SeahorseSecureEntry))
#define SEAHORSE_SECURE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_SECURE_ENTRY, SeahorseSecureEntryClass))
#define SEAHORSE_IS_SECURE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_SECURE_ENTRY))
#define SEAHORSE_IS_SECURE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_SECURE_ENTRY))
#define SEAHORSE_SECURE_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_SECURE_ENTRY, SeahorseSecureEntryClass))
typedef struct _SeahorseSecureEntry SeahorseSecureEntry;
typedef struct _SeahorseSecureEntryClass SeahorseSecureEntryClass;
struct _SeahorseSecureEntry {
GtkWidget widget;
gchar *text;
guint overwrite_mode : 1;
/* length in use, in chars */
guint16 text_length;
guint16 text_max_length;
/*< private > */
GdkWindow *text_area;
GtkIMContext *im_context;
gint current_pos;
gint selection_bound;
PangoLayout *cached_layout;
guint cache_includes_preedit : 1;
guint need_im_reset : 1;
guint has_frame : 1;
guint activates_default : 1;
guint cursor_visible : 1;
/* Flag so we don't select all when clicking in entry to focus in */
guint in_click : 1;
/* Only used by GtkCellRendererText */
guint is_cell_renderer : 1;
guint editing_canceled : 1;
guint mouse_cursor_obscured : 1;
/* PangoDirection */
guint resolved_dir : 4;
guint button;
guint blink_timeout;
guint recompute_idle;
gint scroll_offset;
gint ascent; /* font ascent, in pango units */
gint descent; /* font descent, in pango units */
guint16 text_size; /* allocated size, in bytes */
guint16 n_bytes; /* length in use, in bytes */
guint16 preedit_length; /* length of preedit string, in bytes */
guint16 preedit_cursor; /* offset of cursor within preedit string, in chars */
gunichar invisible_char;
gint width_chars;
gboolean visibility;
/* Keeps track of whether changed between resets */
gboolean changed;
};
struct _SeahorseSecureEntryClass {
GtkWidgetClass parent_class;
/* Action signals */
void (*activate) (SeahorseSecureEntry *entry);
void (*move_cursor) (SeahorseSecureEntry *entry, GtkMovementStep step,
gint count, gboolean extend_selection);
void (*insert_at_cursor) (SeahorseSecureEntry *entry, const gchar *str);
void (*delete_from_cursor) (SeahorseSecureEntry *entry, GtkDeleteType type, gint count);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
};
GType seahorse_secure_entry_get_type (void) G_GNUC_CONST;
GtkWidget* seahorse_secure_entry_new (void);
void seahorse_secure_entry_reset_changed (SeahorseSecureEntry *entry);
gboolean seahorse_secure_entry_get_changed (SeahorseSecureEntry *entry);
void seahorse_secure_entry_set_visibility (SeahorseSecureEntry *entry, gboolean setting);
gboolean seahorse_secure_entry_get_visibility (SeahorseSecureEntry *entry);
void seahorse_secure_entry_set_invisible_char (SeahorseSecureEntry *entry, gunichar ch);
gunichar seahorse_secure_entry_get_invisible_char (SeahorseSecureEntry *entry);
void seahorse_secure_entry_set_has_frame (SeahorseSecureEntry *entry, gboolean setting);
gboolean seahorse_secure_entry_get_has_frame (SeahorseSecureEntry *entry);
/* text is truncated if needed */
void seahorse_secure_entry_set_max_length (SeahorseSecureEntry *entry, gint max);
gint seahorse_secure_entry_get_max_length (SeahorseSecureEntry *entry);
void seahorse_secure_entry_set_activates_default (SeahorseSecureEntry *entry, gboolean setting);
gboolean seahorse_secure_entry_get_activates_default (SeahorseSecureEntry *entry);
void seahorse_secure_entry_set_width_chars (SeahorseSecureEntry *entry, gint n_chars);
gint seahorse_secure_entry_get_width_chars (SeahorseSecureEntry *entry);
/* Somewhat more convenient than the GtkEditable generic functions */
void seahorse_secure_entry_set_text (SeahorseSecureEntry *entry, const gchar *text);
/* returns a reference to the text */
const gchar* seahorse_secure_entry_get_text (SeahorseSecureEntry *entry);
PangoLayout* seahorse_secure_entry_get_layout (SeahorseSecureEntry *entry);
void seahorse_secure_entry_get_layout_offsets (SeahorseSecureEntry *entry, gint *x, gint *y);
#ifdef __cplusplus
}
#endif
#endif /*__SEAHORSE_SECURE_ENTRY_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment