[svn] pinentry - r168 - in trunk: . doc gtk+-2 pinentry
svn author wk
cvs at cvs.gnupg.org
Tue Sep 18 13:38:23 CEST 2007
Author: wk
Date: 2007-09-18 13:38:21 +0200 (Tue, 18 Sep 2007)
New Revision: 168
Modified:
trunk/ChangeLog
trunk/doc/pinentry.texi
trunk/gtk+-2/pinentry-gtk-2.c
trunk/pinentry/pinentry.c
trunk/pinentry/pinentry.h
Log:
Add quality bar to the GTK-2 version.
Doesn't look very pretty yet.
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2007-07-09 07:36:40 UTC (rev 167)
+++ trunk/ChangeLog 2007-09-18 11:38:21 UTC (rev 168)
@@ -1,3 +1,11 @@
+2007-09-18 Werner Koch <wk at g10code.com>
+
+ * pinentry/pinentry.h (struct pinentry): Add member QUALITY_BAR
+ and CTX_ASSUAN.
+ * pinentry/pinentry.c (cmd_setqualitybar): New.
+ (copy_and_escape): New.
+ (pinentry_inq_quality): New.
+
2007-07-09 Werner Koch <wk at g10code.com>
* doc/pinentry.texi: Fixed direntry syntax.
Modified: trunk/doc/pinentry.texi
===================================================================
--- trunk/doc/pinentry.texi 2007-07-09 07:36:40 UTC (rev 167)
+++ trunk/doc/pinentry.texi 2007-09-18 11:38:21 UTC (rev 168)
@@ -276,6 +276,18 @@
S: OK
@end example
+ at item Enable a passphrase quality indicator
+Adds a quality indicator to the GETPIN window. This indicator is
+updated as the passphrase is typed. The clients needs to implement an
+inquiry named "QUALITY" which gets passed the current passpharse
+(percent-plus escaped) and should send back a string with a single
+numerical vauelue between -100 and 100. Negative values will be
+displayed in red.
+ at example
+ C: SETQUALITYBAR
+ S: OK
+ at end example
+
@item Ask for a PIN
The meat of this tool is to ask for a passphrase of PIN, it is done with
this command:
Modified: trunk/gtk+-2/pinentry-gtk-2.c
===================================================================
--- trunk/gtk+-2/pinentry-gtk-2.c 2007-07-09 07:36:40 UTC (rev 167)
+++ trunk/gtk+-2/pinentry-gtk-2.c 2007-09-18 11:38:21 UTC (rev 168)
@@ -1,6 +1,6 @@
/* pinentry-gtk-2.c
Copyright (C) 1999 Robert Bihlmeyer <robbe at orcus.priv.at>
- Copyright (C) 2001, 2002 g10 Code GmbH
+ Copyright (C) 2001, 2002, 2007 g10 Code GmbH
Copyright (C) 2004 by Albrecht Dreß <albrecht.dress at arcor.de>
pinentry-gtk-2 is a pinentry application for the Gtk+-2 widget set.
@@ -56,6 +56,7 @@
static int confirm_yes;
static GtkWidget *entry;
+static GtkWidget *qualitybar;
static GtkWidget *insure;
static GtkWidget *time_out;
@@ -181,6 +182,49 @@
}
+/* Handler called for "changed". We use it to update the quality
+ indicator. */
+static void
+changed_text_handler (GtkWidget *widget)
+{
+ char textbuf[50];
+ const char *s;
+ int length;
+ int percent;
+ GdkColor color = { 0, 0, 0, 0};
+
+ if (!qualitybar || !pinentry->quality_bar)
+ return;
+
+ s = gtk_secure_entry_get_text (GTK_SECURE_ENTRY (widget));
+ if (!s)
+ s = "";
+ length = strlen (s);
+ percent = length? pinentry_inq_quality (pinentry, s, length) : 0;
+ if (!length)
+ {
+ *textbuf = 0;
+ color.red = 0xffff;
+ }
+ else if (percent < 0)
+ {
+ snprintf (textbuf, sizeof textbuf, "(%d%%)", -percent);
+ color.red = 0xffff;
+ percent = -percent;
+ }
+ else
+ {
+ snprintf (textbuf, sizeof textbuf, "%d%%", percent);
+ color.green = 0xffff;
+ }
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (qualitybar),
+ (double)percent/100.0);
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (qualitybar), textbuf);
+ gtk_widget_modify_bg (qualitybar, GTK_STATE_PRELIGHT, &color);
+}
+
+
+
static GtkWidget *
create_window (int confirm_mode)
{
@@ -237,7 +281,7 @@
g_free (msg);
gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_box_pack_start (GTK_BOX (box), w, TRUE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), w, TRUE, FALSE, 0);
}
if (pinentry->error && !confirm_mode)
{
@@ -251,7 +295,17 @@
gtk_box_pack_start (GTK_BOX (box), w, TRUE, FALSE, 0);
gtk_widget_modify_fg (w, GTK_STATE_NORMAL, &color);
}
-
+
+ if (pinentry->quality_bar)
+ {
+ qualitybar = gtk_progress_bar_new();
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (qualitybar), "<small>foo</small>");
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (qualitybar), 0.0);
+ gtk_box_pack_start (GTK_BOX (box), qualitybar, TRUE, FALSE, 0);
+ }
+ else
+ qualitybar = NULL;
+
ebox = gtk_hbox_new (FALSE, HIG_SMALL);
gtk_box_pack_start (GTK_BOX(box), ebox, FALSE, FALSE, 0);
@@ -264,10 +318,13 @@
g_free (msg);
gtk_box_pack_start (GTK_BOX (ebox), w, FALSE, FALSE, 0);
}
+
entry = gtk_secure_entry_new ();
gtk_widget_set_size_request (entry, 200, -1);
g_signal_connect (G_OBJECT (entry), "activate",
G_CALLBACK (enter_callback), entry);
+ g_signal_connect (G_OBJECT (entry), "changed",
+ G_CALLBACK (changed_text_handler), entry);
gtk_box_pack_start (GTK_BOX (ebox), entry, TRUE, TRUE, 0);
gtk_widget_grab_focus (entry);
gtk_widget_show (entry);
Modified: trunk/pinentry/pinentry.c
===================================================================
--- trunk/pinentry/pinentry.c 2007-07-09 07:36:40 UTC (rev 167)
+++ trunk/pinentry/pinentry.c 2007-09-18 11:38:21 UTC (rev 168)
@@ -1,5 +1,5 @@
/* pinentry.c - The PIN entry support library
- Copyright (C) 2002, 2003 g10 Code GmbH
+ Copyright (C) 2002, 2003, 2007 g10 Code GmbH
This file is part of PINENTRY.
@@ -69,11 +69,13 @@
0, /* Result. */
0, /* Locale error flag. */
0, /* One-button flag. */
+ 0, /* Quality-Bar flag. */
PINENTRY_COLOR_DEFAULT,
0,
PINENTRY_COLOR_DEFAULT,
PINENTRY_COLOR_DEFAULT,
- 0
+ 0,
+ NULL /* Assuan context. */
};
@@ -208,6 +210,111 @@
}
#endif
+
+/* Copy TEXT or TEXTLEN to BUFFER and escape as required. Return a
+ pointer to the end of the new buffer. Note that BUFFER must be
+ large enough to keep the entire text; allocataing it 3 times of
+ TEXTLEN is sufficient. */
+static char *
+copy_and_escape (char *buffer, const void *text, size_t textlen)
+{
+ int i;
+ const unsigned char *s = (unsigned char *)text;
+ char *p = buffer;
+
+ for (i=0; i < textlen; i++)
+ {
+ if (s[i] < ' ' || s[i] == '+')
+ {
+ snprintf (p, 4, "%%%02X", s[i]);
+ p += 3;
+ }
+ else if (s[i] == ' ')
+ *p++ = '+';
+ else
+ *p++ = s[i];
+ }
+ return p;
+}
+
+
+
+/* Run a quality inquiry for PASSPHRASE of LENGTH. (We need LENGTH
+ because not all backends might be able to return a proper
+ C-string.). Returns: A value between -100 and 100 to give an
+ estimate of the passphrase's quality. Negative values are use if
+ the caller won't even accept that passphrase. Note that we expect
+ just one data line which should not be escaped in any represent a
+ numeric signed decimal value. Extra data is currently ignored but
+ should not be send at all. */
+int
+pinentry_inq_quality (pinentry_t pin, const char *passphrase, size_t length)
+{
+ ASSUAN_CONTEXT ctx = pin->ctx_assuan;
+ const char prefix[] = "INQUIRE QUALITY ";
+ char *command;
+ char *line;
+ size_t linelen;
+ int gotvalue = 0;
+ int value = 0;
+ int rc;
+
+ if (!ctx)
+ return 0; /* Can't run the callback. */
+
+ if (length > 300)
+ length = 300; /* Limit so that it definitely fits into an Assuan
+ line. */
+
+ command = secmem_malloc (strlen (prefix) + 3*length + 1);
+ if (!command)
+ return 0;
+ strcpy (command, prefix);
+ copy_and_escape (command + strlen(command), passphrase, length);
+ rc = assuan_write_line (ctx, command);
+ secmem_free (command);
+ if (rc)
+ {
+ fprintf (stderr, "ASSUAN WRITE LINE failed: rc=%d\n", rc);
+ return 0;
+ }
+
+ for (;;)
+ {
+ do
+ {
+ rc = assuan_read_line (ctx, &line, &linelen);
+ if (rc)
+ {
+ fprintf (stderr, "ASSUAN READ LINE failed: rc=%d\n", rc);
+ return 0;
+ }
+ }
+ while (*line == '#' || !linelen);
+ if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
+ && (!line[3] || line[3] == ' '))
+ break; /* END command received*/
+ if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N'
+ && (!line[3] || line[3] == ' '))
+ break; /* CAN command received*/
+ if (line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
+ && (!line[3] || line[3] == ' '))
+ break; /* ERR command received*/
+ if (line[0] != 'D' || line[1] != ' ' || linelen < 3 || gotvalue)
+ continue;
+ gotvalue = 1;
+ value = atoi (line+2);
+ }
+ if (value < -100)
+ value = -100;
+ else if (value > 100)
+ value = 100;
+
+ return value;
+}
+
+
+
/* Try to make room for at least LEN bytes in the pinentry. Returns
new buffer on success and 0 on failure or when the old buffer is
sufficient. */
@@ -638,7 +745,16 @@
}
+
static int
+cmd_setqualitybar (ASSUAN_CONTEXT ctx, char *line)
+{
+ pinentry.quality_bar = 1;
+ return 0;
+}
+
+
+static int
cmd_getpin (ASSUAN_CONTEXT ctx, char *line)
{
int result;
@@ -654,8 +770,9 @@
}
pinentry.locale_err = 0;
pinentry.one_button = 0;
-
+ pinentry.ctx_assuan = ctx;
result = (*pinentry_cmd_handler) (&pinentry);
+ pinentry.ctx_assuan = NULL;
if (pinentry.error)
{
free (pinentry.error);
@@ -664,6 +781,8 @@
if (set_prompt)
pinentry.prompt = NULL;
+ pinentry.quality_bar = 0; /* Reset it after the command. */
+
if (result < 0)
{
if (pinentry.pin)
@@ -704,6 +823,7 @@
int result;
pinentry.one_button = !!strstr (line, "--one-button");
+ pinentry.quality_bar = 0;
pinentry.locale_err = 0;
result = (*pinentry_cmd_handler) (&pinentry);
if (pinentry.error)
@@ -726,6 +846,7 @@
int result;
pinentry.one_button = 1;
+ pinentry.quality_bar = 0;
pinentry.locale_err = 0;
result = (*pinentry_cmd_handler) (&pinentry);
if (pinentry.error)
@@ -759,6 +880,7 @@
{ "GETPIN", 0, cmd_getpin },
{ "CONFIRM", 0, cmd_confirm },
{ "MESSAGE", 0, cmd_message },
+ { "SETQUALITYBAR", 0, cmd_setqualitybar },
{ NULL }
};
int i, j, rc;
Modified: trunk/pinentry/pinentry.h
===================================================================
--- trunk/pinentry/pinentry.h 2007-07-09 07:36:40 UTC (rev 167)
+++ trunk/pinentry/pinentry.h 2007-09-18 11:38:21 UTC (rev 168)
@@ -91,12 +91,21 @@
dismiss button is required. */
int one_button;
+ /* If this is set, a passphrase quality indicator is shown. There
+ will also be an inquiry back to the caller to get an indication
+ of the quality for the passphrase entered so far. */
+ int quality_bar;
+
/* For the curses pinentry, the color of error messages. */
pinentry_color_t color_fg;
int color_fg_bright;
pinentry_color_t color_bg;
pinentry_color_t color_so;
int color_so_bright;
+
+ /* Fo the quality indicator we need to do an inquiry. Thus we need
+ to save the assuan ctx. */
+ void *ctx_assuan;
};
typedef struct pinentry *pinentry_t;
@@ -124,6 +133,11 @@
Return NULL on error. */
char *pinentry_local_to_utf8 (char *lc_ctype, char *text, int secure);
+
+/* Run a quality inquiry for PASSPHRASE of LENGTH. */
+int pinentry_inq_quality (pinentry_t pin,
+ const char *passphrase, size_t length);
+
/* Try to make room for at least LEN bytes for the pin in the pinentry
PIN. Returns new buffer on success and 0 on failure. */
char *pinentry_setbufferlen (pinentry_t pin, int len);
More information about the Gnupg-commits
mailing list