[Gpa-commits] r1005 - in trunk: . src

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Mon Jun 15 11:12:22 CEST 2009


Author: werner
Date: 2009-06-15 11:12:21 +0200 (Mon, 15 Jun 2009)
New Revision: 1005

Modified:
   trunk/TODO
   trunk/src/ChangeLog
   trunk/src/gpgmeedit.c
   trunk/src/gpgmetools.c
   trunk/src/gpgmetools.h
   trunk/src/keygendlg.c
   trunk/src/keygenwizard.c
Log:
Change user ID before generating the key.


Modified: trunk/TODO
===================================================================
--- trunk/TODO	2009-06-13 16:47:12 UTC (rev 1004)
+++ trunk/TODO	2009-06-15 09:12:21 UTC (rev 1005)
@@ -3,11 +3,9 @@
 In no particular order:
 
 * Improve support for smartcard
-** lookup and display public key details associated to a smartcard
 ** display status during smartcard access, since it often takes longer
    than a second (idea: simply disable refresh button?)
 ** display messages "please attach reader" in case no smartcard reader is attached
-** mark readonly data objects on the card (maybe grey them out?)
 ** generate-new-key-pair button if card contains no key.
 ** check if cardman releases the smartcard (reader) as it should. maybe we have
    to destroy the cardman instance instead of simply hiding it.
@@ -142,6 +140,11 @@
    fingerprint). I think the expander's width should be allowed to
    grow in case there's unused space to the right of the expander widget.
 
+** Keygenwizard
+   Immediately show an error description if the entered values does
+   not pass the validation function.
+
+
 * Building
 
 * Bugs

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2009-06-13 16:47:12 UTC (rev 1004)
+++ trunk/src/ChangeLog	2009-06-15 09:12:21 UTC (rev 1005)
@@ -1,3 +1,19 @@
+2009-06-15  Werner Koch  <wk at g10code.com>
+
+	* keygenwizard.c (name_validate_cb, email_validate_cb): Use new
+	validation functions.
+
+	* keygendlg.c (create_dialog): Show backup button only in card mode.
+	(gpa_key_gen_run_dialog): Adjust for this.
+	(validate_name, validate_comment): New.
+	(response_cb): Use them.
+	* gpgmetools.c (gpa_validate_gpg_name, gpa_validate_gpg_email)
+	(gpa_validate_gpg_comment): New.
+	(has_invalid_email_chars, string_count_chr, is_valid_mailbox): New.
+
+	* gpgmeedit.c (card_edit_genkey_fnc_transit): Check for repeated
+	name/email/comment prompts.
+
 2009-06-13  Moritz  <moritz at gnu.org>
 
 	* keygenwizard.c (focus_repeat_passphrase, passwd_validate_cb)

Modified: trunk/src/gpgmeedit.c
===================================================================
--- trunk/src/gpgmeedit.c	2009-06-13 16:47:12 UTC (rev 1004)
+++ trunk/src/gpgmeedit.c	2009-06-15 09:12:21 UTC (rev 1005)
@@ -1371,7 +1371,8 @@
         {
           if (!strcmp (args, "keygen.email"))
             next_state = CARD_GENERATE_EMAIL;
-          else if (!strcmp (args, "cardedit.prompt"))
+          else if (!strcmp (args, "cardedit.prompt")
+                   || !strcmp (args, "keygen.name"))
             goto unexpected_prompt;
           else
             {
@@ -1388,7 +1389,8 @@
         {
           if (!strcmp (args, "keygen.comment"))
             next_state = CARD_GENERATE_COMMENT;
-          else if (!strcmp (args, "cardedit.prompt"))
+          else if (!strcmp (args, "cardedit.prompt")
+                   || !strcmp (args, "keygen.email"))
             goto unexpected_prompt;
           else
             {
@@ -1403,6 +1405,8 @@
     case CARD_GENERATE_COMMENT:
       if (status == GPGME_STATUS_KEY_CREATED)
 	next_state = CARD_GENERATE_DONE;
+      else if (!strcmp (args, "keygen.comment"))
+        goto unexpected_prompt;
       else
         goto bad_state;
       break;

Modified: trunk/src/gpgmetools.c
===================================================================
--- trunk/src/gpgmetools.c	2009-06-13 16:47:12 UTC (rev 1004)
+++ trunk/src/gpgmetools.c	2009-06-15 09:12:21 UTC (rev 1005)
@@ -1491,3 +1491,111 @@
   gpa_start_simple_gpg_command (NULL, NULL, GPGME_PROTOCOL_ASSUAN,
                                 "NOP", "/bye", NULL);
 }
+
+
+
+/* Fucntions matching the user id verification isn gpg's key generation.  */
+
+const char *
+gpa_validate_gpg_name (const char *name)
+{
+  const char *result = NULL;
+
+  if (!name || !*name)
+    result = _("You must enter a name.");
+  else if (strpbrk (name, "<>"))
+    result = _("Invalid character in name.");
+  else if (g_ascii_isdigit (*name))
+    result = _("Name may not start with a digit.");
+  else if (g_utf8_strlen (name, -1) < 5)
+    result = _("Name is too short.");
+  
+  return result;
+}
+
+
+/* Check whether the string has characters not valid in an RFC-822
+   address.  To cope with OpenPGP we allow non-ascii characters
+   so that for example umlauts are legal in an email address.  An
+   OpenPGP user ID must be utf-8 encoded but there is no strict
+   requirement for RFC-822.  Thus to avoid IDNA encoding we put the
+   address verbatim as utf-8 into the user ID under the assumption
+   that mail programs handle IDNA at a lower level and take OpenPGP
+   user IDs as utf-8.  */
+static int
+has_invalid_email_chars (const char *s)
+{
+  int at_seen = 0;
+  const char *valid_chars=
+    "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+  for ( ; *s; s++ ) 
+    {
+      if ((*s & 0x80))
+        continue; /* We only care about ASCII.  */
+      if (*s == '@')
+        at_seen=1;
+      else if (!at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ))
+        return 1;
+      else if (at_seen && !strchr (valid_chars, *s))
+        return 1;
+    }
+  return 0;
+}
+
+
+static int
+string_count_chr (const char *string, int c)
+{
+  int count;
+
+  for (count=0; *string; string++ )
+    if ( *string == c )
+      count++;
+  return count;
+}
+
+
+/* Check whether NAME represents a valid mailbox according to RFC822
+   except for non-ascii utf-8 characters. Returns true if so. */
+static int
+is_valid_mailbox (const char *name)
+{
+  return !( !name
+            || !*name
+            || has_invalid_email_chars (name)
+            || string_count_chr (name,'@') != 1
+            || *name == '@'
+            || name[strlen(name)-1] == '@'
+            || name[strlen(name)-1] == '.'
+            || strstr (name, "..") );
+}
+
+
+const char *
+gpa_validate_gpg_email (const char *email)
+{
+  const char *result = NULL;
+
+  if (!email || !*email)
+    ;
+  else if (!is_valid_mailbox (email))
+    result = _("Email address is not valid.");
+
+  return result;
+}
+
+
+const char *
+gpa_validate_gpg_comment (const char *comment)
+{
+  const char *result = NULL;
+
+  if (!comment || !*comment)
+    ;
+  else if (strpbrk (comment, "()"))
+    result = _("Invalid character in comments.");
+
+  return result;
+}
+

Modified: trunk/src/gpgmetools.h
===================================================================
--- trunk/src/gpgmetools.h	2009-06-13 16:47:12 UTC (rev 1004)
+++ trunk/src/gpgmetools.h	2009-06-15 09:12:21 UTC (rev 1005)
@@ -208,5 +208,10 @@
 
 void gpa_start_agent (void);
 
+/* Funtions to check user inputs in the same way gpg does.  */
+const char *gpa_validate_gpg_name (const char *name);
+const char *gpa_validate_gpg_email (const char *email);
+const char *gpa_validate_gpg_comment (const char *comment);
 
+
 #endif /*GPGMETOOLS_H*/

Modified: trunk/src/keygendlg.c
===================================================================
--- trunk/src/keygendlg.c	2009-06-13 16:47:12 UTC (rev 1004)
+++ trunk/src/keygendlg.c	2009-06-15 09:12:21 UTC (rev 1005)
@@ -58,13 +58,50 @@
   GtkWidget *entry_email;
   GtkWidget *entry_comment;
   GtkWidget *entry_expire;
-  GtkWidget *entry_backup;
+  GtkWidget *entry_backup;  /* Maybe NULL.  */
 
   GtkWidget *label_userid;
 };
 typedef struct _GpaKeyGenDlg GpaKeyGenDlg;
 
 
+static gboolean
+validate_name (GpaKeyGenDlg *self)
+{
+  const char *s;
+
+  s = gpa_validate_gpg_name (gtk_entry_get_text 
+                             (GTK_ENTRY (self->entry_name)));
+  if (s)
+    gpa_window_error (s, self->dialog);
+  return !s;
+}
+
+static gboolean
+validate_email (GpaKeyGenDlg *self)
+{
+  const char *s;
+
+  s = gpa_validate_gpg_email (gtk_entry_get_text 
+                              (GTK_ENTRY (self->entry_email)));
+  if (s)
+    gpa_window_error (s, self->dialog);
+  return !s;
+}
+
+static gboolean
+validate_comment (GpaKeyGenDlg *self)
+{
+  const char *s;
+
+  s = gpa_validate_gpg_comment (gtk_entry_get_text 
+                                (GTK_ENTRY (self->entry_comment)));
+  if (s)
+    gpa_window_error (s, self->dialog);
+  return !s;
+}
+
+
 /* This callback gets called each time the user clicks on the [OK] or
    [Cancel] buttons.  If the button was [OK], it verifies that the
    input makes sense.  */
@@ -86,9 +123,10 @@
           :  NULL);
   keysize = temp? atoi (temp):0; 
              
-  if (!name || !*name)
+  if (!validate_name (self)
+      || !validate_email (self)
+      || !validate_comment (self))
     {
-      gpa_window_error (_("You must enter a User ID."), self->dialog);
       g_signal_stop_emission_by_name (dlg, "response");
     }
   else if (self->forcard)
@@ -286,23 +324,28 @@
   self->entry_expire = button;
   rowidx++;
 
-  label = gtk_label_new_with_mnemonic (_("Backup: "));
-  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
-  gtk_table_attach (GTK_TABLE (table), label, 0, 1, rowidx, rowidx+1,
-                    GTK_FILL, GTK_SHRINK, 0, 0);
-  button = gtk_check_button_new ();
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  hbox = gtk_hbox_new (FALSE, 0);
-  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-  gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, rowidx, rowidx+1,
-                    GTK_FILL, GTK_SHRINK, 0, 0);
-  self->entry_backup = button;
-  gpa_add_tooltip (hbox,
-                   _("If checked the encryption key will be created "
-                     "and stored to a backup file and then loaded into "
-                     "the card.  This is recommended so that encrypted "
-                     "messages can be decrypted even if the card has a "
-                     "malfunction."));
+  if (forcard)
+    {
+      label = gtk_label_new_with_mnemonic (_("Backup: "));
+      gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+      gtk_table_attach (GTK_TABLE (table), label, 0, 1, rowidx, rowidx+1,
+                        GTK_FILL, GTK_SHRINK, 0, 0);
+      button = gtk_check_button_new ();
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+      gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, rowidx, rowidx+1,
+                        GTK_FILL, GTK_SHRINK, 0, 0);
+      self->entry_backup = button;
+      gpa_add_tooltip (hbox,
+                       _("If checked the encryption key will be created "
+                         "and stored to a backup file and then loaded into "
+                         "the card.  This is recommended so that encrypted "
+                         "messages can be decrypted even if the card has a "
+                         "malfunction."));
+    }
+  else
+    self->entry_backup = NULL;
 
 }
 
@@ -369,8 +412,10 @@
       
   gpa_date_box_get_date (GPA_DATE_BOX (self->entry_expire), &params->expire);
 
-  params->backup = gtk_toggle_button_get_active 
-    (GTK_TOGGLE_BUTTON (self->entry_backup));
+  params->backup = self->entry_backup 
+                   ? gtk_toggle_button_get_active 
+                        (GTK_TOGGLE_BUTTON (self->entry_backup))
+                   : 0;
 
   gtk_widget_destroy (self->dialog);
   g_free (self);

Modified: trunk/src/keygenwizard.c
===================================================================
--- trunk/src/keygenwizard.c	2009-06-13 16:47:12 UTC (rev 1004)
+++ trunk/src/keygenwizard.c	2009-06-15 09:12:21 UTC (rev 1005)
@@ -157,7 +157,8 @@
   while (*name && g_unichar_isspace (g_utf8_get_char (name)))
     name = g_utf8_next_char (name);
   gtk_assistant_set_page_complete (GTK_ASSISTANT (wizard->window),
-				   wizard->name_page, *name != '\0');
+				   wizard->name_page, 
+                                   !gpa_validate_gpg_name (name));
 
   return FALSE;
 }
@@ -193,11 +194,9 @@
   while (*email && g_unichar_isspace (g_utf8_get_char (email)))
     email = g_utf8_next_char (email);
   gtk_assistant_set_page_complete (GTK_ASSISTANT (wizard->window),
-				   wizard->email_page, *email != '\0');
+				   wizard->email_page,
+                                   !gpa_validate_gpg_email (email));
 
-  /* FIXME: we should do much more checking. Best would be exactly the
-     same checks gpg does in interactive mode with --gen-key.  */
-
   return FALSE;
 }
 



More information about the Gpa-commits mailing list