[Gpa-commits] r957 - trunk/src
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Tue Mar 3 16:40:24 CET 2009
Author: werner
Date: 2009-03-03 16:40:19 +0100 (Tue, 03 Mar 2009)
New Revision: 957
Added:
trunk/src/gpa-logo.ppm
trunk/src/server-access.c
trunk/src/server-access.h
Removed:
trunk/src/gpa_logo.ppm
trunk/src/server_access.c
trunk/src/server_access.h
Modified:
trunk/src/ChangeLog
trunk/src/Makefile.am
trunk/src/cm-openpgp.c
trunk/src/convert.c
trunk/src/gpaexportserverop.c
trunk/src/gpaimportserverop.c
trunk/src/keyring.c
Log:
Better formatted fields.
Some file renames.
Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog 2009-02-27 10:06:24 UTC (rev 956)
+++ trunk/src/ChangeLog 2009-03-03 15:40:19 UTC (rev 957)
@@ -1,5 +1,28 @@
+2009-03-03 Werner Koch <wk at g10code.com>
+
+ * convert.c (gpa_sex_char_to_string): Make strings a salutation.
+
+ * cm-openpgp.c (add_table_row): Set the label alignment again.
+ (update_entry_fpr, update_entry_chv_status): New.
+ (reload_data): Use them.
+ (set_integer): New.
+ (construct_data_widget): Add new field for the PUK. Reorder code.
+ (edit_toggled_cb): New.
+ (save_attr): Add arg IS_ESCAPED and change all callers.
+ (save_entry_sig_force_pin): new.
+
2009-02-27 Werner Koch <wk at g10code.com>
+ * server_access.c: Rename to server-access.c.
+ * server_access.h: Rename to server-access.h.
+ * gpa_logo.ppm: Rename to gpa-logo.ppm.
+ * Makefile.am: Adjust accordingly.
+ * server-access.c, keyring.c, gpaimportserverop.c
+ * gpaexportserverop.c: Ditto.
+
+ * server_access.c (helper_path) [G_OS_WIN32]: Fix syntax error.
+ (close_dialog): Build only for G_OS_UNIX.
+
* filewatch.c: Remove debug output.
* cardman.c (struct _GpaCardManager): Add TICKER_TIMEOUT_ID and
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2009-02-27 10:06:24 UTC (rev 956)
+++ trunk/src/Makefile.am 2009-03-03 15:40:19 UTC (rev 957)
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-logo = gpa_logo.ppm
+logo = gpa-logo.ppm
pkgdata_DATA = $(logo)
@@ -91,7 +91,7 @@
keytable.c keytable.h \
gpgmetools.h gpgmetools.c \
gpgmeedit.h gpgmeedit.c \
- server_access.h server_access.c \
+ server-access.h server-access.c \
settingsdlg.h settingsdlg.c \
passwddlg.h passwddlg.c \
gpacontext.h gpacontext.c \
Modified: trunk/src/cm-openpgp.c
===================================================================
--- trunk/src/cm-openpgp.c 2009-02-27 10:06:24 UTC (rev 956)
+++ trunk/src/cm-openpgp.c 2009-03-03 15:40:19 UTC (rev 957)
@@ -52,6 +52,7 @@
ENTRY_KEY_ENC,
ENTRY_KEY_AUTH,
ENTRY_PIN_RETRYCOUNTER,
+ ENTRY_PUK_RETRYCOUNTER,
ENTRY_ADMIN_PIN_RETRYCOUNTER,
ENTRY_SIG_FORCE_PIN,
@@ -80,6 +81,8 @@
GtkWidget *entries[ENTRY_LAST];
gboolean changed[ENTRY_LAST];
+ GtkLabel *puk_label; /* The label of the PUK field. */
+
int reloading;
};
@@ -148,10 +151,6 @@
static void
show_edit_error (GpaCMOpenpgp *card, const char *text)
{
- if (text)
- g_debug ("Edit error: %s", text);
- else
- g_debug ("Clear edit error");
gpa_cm_object_update_status (GPA_CM_OBJECT(card), text);
}
@@ -202,6 +201,15 @@
gtk_entry_set_text (GTK_ENTRY (card->entries[ENTRY_SERIALNO]), serialno);
gtk_entry_set_text (GTK_ENTRY (card->entries[ENTRY_MANUFACTURER]), vendor);
gtk_entry_set_text (GTK_ENTRY (card->entries[ENTRY_VERSION]), version);
+
+ if ((*version == '1' || *version == '0') && version[1] == '.')
+ {
+ gtk_label_set_text (card->puk_label, _("CHV2 retry counter: "));
+ }
+ else /* Version 2 card. */
+ {
+ gtk_label_set_text (card->puk_label, _("PUK retry counter: "));
+ }
}
@@ -254,6 +262,73 @@
}
+static void
+set_integer (GtkWidget *entry, int value)
+{
+ char numbuf[35];
+
+ snprintf (numbuf, sizeof numbuf, "%d", value);
+ gtk_entry_set_text (GTK_ENTRY (entry), numbuf);
+}
+
+
+/* Update the CVH (PIN) status fields. STRING is the space separated
+ list of the decimal encoded values from the DO 0xC4. */
+static void
+update_entry_chv_status (GpaCMOpenpgp *card, int entry_id, const char *string)
+{
+ int force_pw1;
+ int pw_maxlen[3];
+ int pw_retry[3];
+ int i;
+
+ (void)entry_id; /* Not used. */
+
+ while (spacep (string))
+ string++;
+ force_pw1 = atoi (string);
+ while (*string && !spacep (string))
+ string++;
+ while (spacep (string))
+ string++;
+ for (i=0; *string && i < DIM (pw_maxlen); i++)
+ {
+ pw_maxlen[i] = atoi (string);
+ while (*string && !spacep (string))
+ string++;
+ while (spacep (string))
+ string++;
+ }
+ for (i=0; *string && i < DIM (pw_retry); i++)
+ {
+ pw_retry[i] = atoi (string);
+ while (*string && !spacep (string))
+ string++;
+ while (spacep (string))
+ string++;
+ }
+
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (card->entries[ENTRY_SIG_FORCE_PIN]), !!force_pw1);
+ set_integer (card->entries[ENTRY_PIN_RETRYCOUNTER], pw_retry[0]);
+ set_integer (card->entries[ENTRY_PUK_RETRYCOUNTER], pw_retry[1]);
+ set_integer (card->entries[ENTRY_ADMIN_PIN_RETRYCOUNTER], pw_retry[2]);
+
+}
+
+
+/* Format the raw hex fingerprint STRING and set it into ENTRY_ID. */
+static void
+update_entry_fpr (GpaCMOpenpgp *card, int entry_id, const char *string)
+{
+ char *buf;
+
+ buf = gpa_gpgme_key_format_fingerprint (string);
+ gtk_entry_set_text (GTK_ENTRY (card->entries[entry_id]), buf);
+ xfree (buf);
+}
+
+
struct scd_getattr_parm
{
GpaCMOpenpgp *card; /* The object. */
@@ -328,8 +403,8 @@
{ "PUBKEY-URL", ENTRY_PUBKEY_URL },
{ "LOGIN-DATA", ENTRY_LOGIN },
/* { "SIG-COUNTER",ENTRY_SIG_COUNTER }, */
- { "CHV-STATUS", ENTRY_PIN_RETRYCOUNTER, NULL/*fixme*/ },
- { "KEY-FPR", ENTRY_LAST },
+ { "CHV-STATUS", ENTRY_PIN_RETRYCOUNTER, update_entry_chv_status },
+ { "KEY-FPR", ENTRY_LAST, update_entry_fpr },
/* { "CA-FPR", }, */
{ NULL }
};
@@ -381,11 +456,11 @@
static gpg_error_t
-save_attr (GpaCMOpenpgp *card, const char *name, const char *value)
+save_attr (GpaCMOpenpgp *card, const char *name,
+ const char *value, int is_escaped)
{
gpg_error_t err;
char *command;
- char *p;
gpgme_ctx_t gpgagent;
g_return_val_if_fail (*name && value, gpg_error (GPG_ERR_BUG));
@@ -393,11 +468,16 @@
gpgagent = GPA_CM_OBJECT (card)->agent_ctx;
g_return_val_if_fail (gpgagent,gpg_error (GPG_ERR_BUG));
-
- p = percent_escape (value, NULL, 1);
- command = g_strdup_printf ("SCD SETATTR %s %s", name, p);
- xfree (p);
+ if (is_escaped)
+ command = g_strdup_printf ("SCD SETATTR %s %s", name, value);
+ else
+ {
+ char *p;
+ p = percent_escape (value, NULL, 1);
+ command = g_strdup_printf ("SCD SETATTR %s %s", name, p);
+ xfree (p);
+ }
err = gpgme_op_assuan_transact (gpgagent,
command,
NULL, NULL,
@@ -470,7 +550,7 @@
if (strlen (buffer) > 39)
errstr = _("Total length of first and last name "
"may not be longer than 39 characters.");
- else if (save_attr (card, "DISP-NAME", buffer))
+ else if (save_attr (card, "DISP-NAME", buffer, 0))
errstr = _("Saving the field failed.");
g_free (buffer);
}
@@ -508,7 +588,7 @@
goto leave;
}
- if (save_attr (card, "DISP-LANG", value))
+ if (save_attr (card, "DISP-LANG", value, 0))
errstr = _("Saving the field failed.");
leave:
@@ -519,7 +599,7 @@
}
-/* Save the sex field. Returns true on error. */
+/* Save the salutation field. Returns true on error. */
static gpg_error_t
save_entry_sex (GpaCMOpenpgp *card)
{
@@ -535,7 +615,7 @@
else
string = "9";
- if (save_attr (card, "DISP-SEX", string))
+ if (save_attr (card, "DISP-SEX", string, 0))
errstr = _("Saving the field failed.");
if (errstr)
@@ -559,7 +639,7 @@
goto leave;
}
- if (save_attr (card, "PUBKEY-URL", value))
+ if (save_attr (card, "PUBKEY-URL", value, 0))
errstr = _("Saving the field failed.");
leave:
@@ -584,7 +664,7 @@
goto leave;
}
- if (save_attr (card, "LOGIN-DATA", value))
+ if (save_attr (card, "LOGIN-DATA", value, 0))
errstr = _("Saving the field failed.");
leave:
@@ -595,7 +675,27 @@
}
+/* Save the force signature PIN field. */
+static gpg_error_t
+save_entry_sig_force_pin (GpaCMOpenpgp *card)
+{
+ int value;
+ const char *errstr = NULL;
+ value = gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON (card->entries[ENTRY_SIG_FORCE_PIN]));
+
+ if (save_attr (card, "CHV-STATUS-1", value? "%01":"%00", 1))
+ errstr = _("Saving the field failed.");
+
+ if (errstr)
+ show_edit_error (card, errstr);
+
+ return !!errstr;
+}
+
+
+
/* Callback for the "changed" signal connected to entry fields. We
figure out the entry field for which this signal has been emitted
and set a flag to know ehether we have unsaved data. */
@@ -658,7 +758,31 @@
}
}
+/* Callback for the "changed" signal connected to entry fields. We
+ figure out the entry field for which this signal has been emitted
+ and set a flag to know ehether we have unsaved data. */
+static void
+edit_toggled_cb (GtkToggleButton *toggle, void *opaque)
+{
+ GpaCMOpenpgp *card = opaque;
+ int idx;
+ for (idx=0; idx < ENTRY_LAST; idx++)
+ if (GTK_IS_TOGGLE_BUTTON (card->entries[idx])
+ && GTK_TOGGLE_BUTTON (card->entries[idx]) == toggle)
+ break;
+ if (!(idx < ENTRY_LAST))
+ return;
+
+ if (!card->changed[idx])
+ {
+ card->changed[idx] = TRUE;
+/* g_debug ("toggled signal for entry %d", idx); */
+ }
+}
+
+
+
/* Callback for the "focus" signal connected to entry fields. We
figure out the entry field for which this signal has been emitted
and whether we are receiving or losing focus. If a the change flag
@@ -706,6 +830,9 @@
case ENTRY_LOGIN:
result = save_entry_login (card);
break;
+ case ENTRY_SIG_FORCE_PIN:
+ result = save_entry_sig_force_pin (card);
+ break;
}
if (!result)
@@ -726,8 +853,8 @@
-/* Helper for construct_data_widget. */
-static void
+/* Helper for construct_data_widget. Returns the label widget. */
+static GtkLabel *
add_table_row (GtkWidget *table, int *rowidx,
const char *labelstr, GtkWidget *widget, GtkWidget *widget2,
int readonly)
@@ -736,7 +863,7 @@
label = gtk_label_new (labelstr);
gtk_label_set_width_chars (GTK_LABEL (label), 22);
- // gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
*rowidx, *rowidx + 1, GTK_FILL, GTK_SHRINK, 0, 0);
@@ -755,6 +882,8 @@
gtk_table_attach (GTK_TABLE (table), widget2, 2, 3,
*rowidx, *rowidx + 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
++*rowidx;
+
+ return GTK_LABEL (label);
}
@@ -774,162 +903,155 @@
GtkWidget *pin_table;
int rowidx;
int idx;
-/* GtkWidget *hbox; */
- /* Create frames and tables. */
+ /* General frame. */
general_frame = card->general_frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (general_frame), GTK_SHADOW_NONE);
label = gtk_label_new (_("<b>General</b>"));
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
gtk_frame_set_label_widget (GTK_FRAME (general_frame), label);
- personal_frame = card->personal_frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (personal_frame), GTK_SHADOW_NONE);
- label = gtk_label_new (_("<b>Personal</b>"));
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
- gtk_frame_set_label_widget (GTK_FRAME (personal_frame), label);
-
- keys_frame = card->keys_frame = gtk_expander_new (NULL);
- label = gtk_label_new (_("<b>Keys</b>"));
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
- gtk_expander_set_label_widget (GTK_EXPANDER (keys_frame), label);
- gtk_expander_set_expanded (GTK_EXPANDER (keys_frame), TRUE);
-
- pin_frame = card->pin_frame = gtk_expander_new (NULL);
- label = gtk_label_new (_("<b>PIN</b>"));
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
- gtk_expander_set_label_widget (GTK_EXPANDER (pin_frame), label);
- gtk_expander_set_expanded (GTK_EXPANDER (pin_frame), TRUE);
-
general_table = gtk_table_new (4, 3, FALSE);
- personal_table = gtk_table_new (6, 3, FALSE);
- keys_table = gtk_table_new (3, 3, FALSE);
- pin_table = gtk_table_new (3, 3, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (general_table), 10);
- gtk_container_set_border_width (GTK_CONTAINER (general_table), 10);
- gtk_container_set_border_width (GTK_CONTAINER (personal_table), 10);
- gtk_container_set_border_width (GTK_CONTAINER (keys_table), 10);
- gtk_container_set_border_width (GTK_CONTAINER (pin_table), 10);
-
- /* General frame. */
rowidx = 0;
card->entries[ENTRY_SERIALNO] = gtk_entry_new ();
add_table_row (general_table, &rowidx,
- "Serial number: ", card->entries[ENTRY_SERIALNO], NULL, 1);
+ _("Serial number:"), card->entries[ENTRY_SERIALNO], NULL, 1);
card->entries[ENTRY_VERSION] = gtk_entry_new ();
add_table_row (general_table, &rowidx,
- "Card version: ", card->entries[ENTRY_VERSION], NULL, 1);
+ _("Card version:"), card->entries[ENTRY_VERSION], NULL, 1);
card->entries[ENTRY_MANUFACTURER] = gtk_entry_new ();
add_table_row (general_table, &rowidx,
- "Manufacturer: ", card->entries[ENTRY_MANUFACTURER], NULL, 1);
+ _("Manufacturer:"),
+ card->entries[ENTRY_MANUFACTURER], NULL, 1);
gtk_container_add (GTK_CONTAINER (general_frame), general_table);
+
/* Personal frame. */
+ personal_frame = card->personal_frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (personal_frame), GTK_SHADOW_NONE);
+ label = gtk_label_new (_("<b>Personal</b>"));
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_frame_set_label_widget (GTK_FRAME (personal_frame), label);
+
+ personal_table = gtk_table_new (6, 3, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (personal_table), 10);
+
rowidx = 0;
+ card->entries[ENTRY_SEX] = gtk_combo_box_new_text ();
+ for (idx=0; "mfu"[idx]; idx++)
+ gtk_combo_box_append_text (GTK_COMBO_BOX (card->entries[ENTRY_SEX]),
+ gpa_sex_char_to_string ("mfu"[idx]));
+ add_table_row (personal_table, &rowidx,
+ _("Salutation:"), card->entries[ENTRY_SEX], NULL, 0);
+
card->entries[ENTRY_FIRST_NAME] = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (card->entries[ENTRY_FIRST_NAME]), 35);
add_table_row (personal_table, &rowidx,
- "First name:", card->entries[ENTRY_FIRST_NAME], NULL, 0);
+ _("First name:"), card->entries[ENTRY_FIRST_NAME], NULL, 0);
card->entries[ENTRY_LAST_NAME] = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (card->entries[ENTRY_LAST_NAME]), 35);
add_table_row (personal_table, &rowidx,
- "Last name:", card->entries[ENTRY_LAST_NAME], NULL, 0);
+ _("Last name:"), card->entries[ENTRY_LAST_NAME], NULL, 0);
- card->entries[ENTRY_SEX] = gtk_combo_box_new_text ();
- for (idx=0; "mfu"[idx]; idx++)
- gtk_combo_box_append_text (GTK_COMBO_BOX (card->entries[ENTRY_SEX]),
- gpa_sex_char_to_string ("mfu"[idx]));
- add_table_row (personal_table, &rowidx,
- "Sex:", card->entries[ENTRY_SEX], NULL, 0);
-
-/* hbox = gtk_hbox_new (FALSE, 0); */
-/* card->entries[ENTRY_SEX] = gtk_radio_button_new_with_label */
-/* (NULL, gpa_sex_char_to_string ('m')); */
-/* gtk_box_pack_start (GTK_BOX (hbox), card->entries[ENTRY_SEX], */
-/* FALSE, FALSE, 5); */
-/* gtk_box_pack_start (GTK_BOX (hbox), */
-/* gtk_radio_button_new_with_label_from_widget */
-/* (GTK_RADIO_BUTTON (card->entries[ENTRY_SEX]), */
-/* gpa_sex_char_to_string ('f')), */
-/* FALSE, FALSE, 5); */
-/* gtk_box_pack_start (GTK_BOX (hbox), */
-/* gtk_radio_button_new_with_label_from_widget */
-/* (GTK_RADIO_BUTTON (card->entries[ENTRY_SEX]), */
-/* gpa_sex_char_to_string ('u')), */
-/* FALSE, FALSE, 5); */
-/* add_table_row (personal_table, &rowidx, */
-/* "Sex:", hbox, NULL); */
-
-
card->entries[ENTRY_LANGUAGE] = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (card->entries[ENTRY_LANGUAGE]), 8);
add_table_row (personal_table, &rowidx,
- "Language: ", card->entries[ENTRY_LANGUAGE], NULL, 0);
+ _("Language:"), card->entries[ENTRY_LANGUAGE], NULL, 0);
card->entries[ENTRY_LOGIN] = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (card->entries[ENTRY_LOGIN]), 254);
add_table_row (personal_table, &rowidx,
- "Login data: ", card->entries[ENTRY_LOGIN], NULL, 0);
+ _("Login data:"), card->entries[ENTRY_LOGIN], NULL, 0);
card->entries[ENTRY_PUBKEY_URL] = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (card->entries[ENTRY_PUBKEY_URL]), 254);
add_table_row (personal_table, &rowidx,
- "Public key URL: ", card->entries[ENTRY_PUBKEY_URL], NULL, 0);
+ _("Public key URL:"),
+ card->entries[ENTRY_PUBKEY_URL], NULL, 0);
gtk_container_add (GTK_CONTAINER (personal_frame), personal_table);
+
/* Keys frame. */
+ keys_frame = card->keys_frame = gtk_expander_new (NULL);
+ label = gtk_label_new (_("<b>Keys</b>"));
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_expander_set_label_widget (GTK_EXPANDER (keys_frame), label);
+ gtk_expander_set_expanded (GTK_EXPANDER (keys_frame), TRUE);
+
+ keys_table = gtk_table_new (3, 3, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (keys_table), 10);
+
rowidx = 0;
card->entries[ENTRY_KEY_SIG] = gtk_entry_new ();
gtk_entry_set_width_chars (GTK_ENTRY (card->entries[ENTRY_KEY_SIG]), 48);
add_table_row (keys_table, &rowidx,
- "Signature key: ", card->entries[ENTRY_KEY_SIG], NULL, 1);
+ _("Signature key:"), card->entries[ENTRY_KEY_SIG], NULL, 1);
card->entries[ENTRY_KEY_ENC] = gtk_entry_new ();
add_table_row (keys_table, &rowidx,
- "Encryption key: ", card->entries[ENTRY_KEY_ENC], NULL, 1);
+ _("Encryption key:"), card->entries[ENTRY_KEY_ENC], NULL, 1);
card->entries[ENTRY_KEY_AUTH] = gtk_entry_new ();
add_table_row (keys_table, &rowidx,
- "Authentication key: ",card->entries[ENTRY_KEY_AUTH], NULL, 1);
+ ("Authentication key:"),
+ card->entries[ENTRY_KEY_AUTH], NULL, 1);
gtk_container_add (GTK_CONTAINER (keys_frame), keys_table);
/* PIN frame. */
+ pin_frame = card->pin_frame = gtk_expander_new (NULL);
+ label = gtk_label_new (_("<b>PIN</b>"));
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_expander_set_label_widget (GTK_EXPANDER (pin_frame), label);
+ gtk_expander_set_expanded (GTK_EXPANDER (pin_frame), TRUE);
+
+ pin_table = gtk_table_new (4, 3, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (pin_table), 10);
+
rowidx = 0;
+ card->entries[ENTRY_SIG_FORCE_PIN] = gtk_check_button_new ();
+ add_table_row (pin_table, &rowidx,
+ _("Force signature PIN:"),
+ card->entries[ENTRY_SIG_FORCE_PIN], NULL, 0);
+
card->entries[ENTRY_PIN_RETRYCOUNTER] = gtk_entry_new ();
gtk_entry_set_width_chars
- (GTK_ENTRY (card->entries[ENTRY_PIN_RETRYCOUNTER]), 24);
+ (GTK_ENTRY (card->entries[ENTRY_PIN_RETRYCOUNTER]), 1);
add_table_row (pin_table, &rowidx,
- "PIN Retry Counter: ",
+ _("PIN retry counter:"),
card->entries[ENTRY_PIN_RETRYCOUNTER], NULL, 1);
+ card->entries[ENTRY_PUK_RETRYCOUNTER] = gtk_entry_new ();
+ gtk_entry_set_width_chars
+ (GTK_ENTRY (card->entries[ENTRY_PUK_RETRYCOUNTER]), 1);
+ card->puk_label =
+ add_table_row (pin_table, &rowidx,
+ "", /* The label depends on the card version. */
+ card->entries[ENTRY_PUK_RETRYCOUNTER], NULL, 1);
+
card->entries[ENTRY_ADMIN_PIN_RETRYCOUNTER] = gtk_entry_new ();
gtk_entry_set_width_chars
- (GTK_ENTRY (card->entries[ENTRY_ADMIN_PIN_RETRYCOUNTER]), 24);
+ (GTK_ENTRY (card->entries[ENTRY_ADMIN_PIN_RETRYCOUNTER]), 1);
add_table_row (pin_table, &rowidx,
- "Admin PIN Retry Counter: ",
+ _("Admin PIN retry counter:"),
card->entries[ENTRY_ADMIN_PIN_RETRYCOUNTER], NULL, 1);
- card->entries[ENTRY_SIG_FORCE_PIN] = gtk_entry_new ();
- gtk_entry_set_width_chars
- (GTK_ENTRY (card->entries[ENTRY_SIG_FORCE_PIN]), 24);
- add_table_row (pin_table, &rowidx,
- "Force Signature PIN: ",
- card->entries[ENTRY_SIG_FORCE_PIN], NULL, 1);
-
gtk_container_add (GTK_CONTAINER (pin_frame), pin_table);
+
/* Put all frames together. */
gtk_box_pack_start (GTK_BOX (card), general_frame, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (card), personal_frame, FALSE, TRUE, 0);
@@ -950,6 +1072,13 @@
G_CALLBACK (edit_focus_cb), card);
break;
+ case ENTRY_SIG_FORCE_PIN:
+ g_signal_connect (G_OBJECT (card->entries[idx]), "toggled",
+ G_CALLBACK (edit_toggled_cb), card);
+ g_signal_connect (G_OBJECT (card->entries[idx]), "focus",
+ G_CALLBACK (edit_focus_cb), card);
+ break;
+
default:
g_signal_connect (G_OBJECT (card->entries[idx]), "changed",
G_CALLBACK (edit_changed_cb), card);
Modified: trunk/src/convert.c
===================================================================
--- trunk/src/convert.c 2009-02-27 10:06:24 UTC (rev 956)
+++ trunk/src/convert.c 2009-03-03 15:40:19 UTC (rev 957)
@@ -112,11 +112,11 @@
gpa_sex_char_to_string (char sex)
{
if (sex == 'm')
- return _("male");
+ return _("Mr.");
else if (sex == 'f')
- return _("female");
+ return _("Ms.");
else if (sex == 'u')
- return _("unspecified");
+ return "";
else
return _("(unknown)");
}
Copied: trunk/src/gpa-logo.ppm (from rev 953, trunk/src/gpa_logo.ppm)
Property changes on: trunk/src/gpa-logo.ppm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Name: svn:mergeinfo
+
Deleted: trunk/src/gpa_logo.ppm
===================================================================
(Binary files differ)
Modified: trunk/src/gpaexportserverop.c
===================================================================
--- trunk/src/gpaexportserverop.c 2009-02-27 10:06:24 UTC (rev 956)
+++ trunk/src/gpaexportserverop.c 2009-03-03 15:40:19 UTC (rev 957)
@@ -26,7 +26,7 @@
#include "i18n.h"
#include "gtktools.h"
#include "gpgmetools.h"
-#include "server_access.h"
+#include "server-access.h"
#include "gpaexportserverop.h"
static GObjectClass *parent_class = NULL;
Modified: trunk/src/gpaimportserverop.c
===================================================================
--- trunk/src/gpaimportserverop.c 2009-02-27 10:06:24 UTC (rev 956)
+++ trunk/src/gpaimportserverop.c 2009-03-03 15:40:19 UTC (rev 957)
@@ -27,7 +27,7 @@
#include "gtktools.h"
#include "gparecvkeydlg.h"
#include "gpaimportserverop.h"
-#include "server_access.h"
+#include "server-access.h"
static GObjectClass *parent_class = NULL;
Modified: trunk/src/keyring.c
===================================================================
--- trunk/src/keyring.c 2009-02-27 10:06:24 UTC (rev 956)
+++ trunk/src/keyring.c 2009-03-03 15:40:19 UTC (rev 957)
@@ -48,7 +48,7 @@
#include "gpgmetools.h"
#include "gpgmeedit.h"
#include "keytable.h"
-#include "server_access.h"
+#include "server-access.h"
#include "options.h"
#include "convert.h"
Copied: trunk/src/server-access.c (from rev 953, trunk/src/server_access.c)
===================================================================
--- trunk/src/server_access.c 2009-02-24 14:19:00 UTC (rev 953)
+++ trunk/src/server-access.c 2009-03-03 15:40:19 UTC (rev 957)
@@ -0,0 +1,612 @@
+/* server-access.c - The GNU Privacy Assistant keyserver access.
+ Copyright (C) 2002 Miguel Coca.
+ Copyright (C) 2005 g10 Code GmbH.
+
+ This file is part of GPA
+
+ GPA is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ GPA 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GPA; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
+
+#include <config.h>
+
+#include "gpa.h"
+#include <glib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <signal.h>
+
+/* For unlink() */
+#ifdef G_OS_UNIX
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#else
+#include <windows.h>
+#include <io.h>
+#endif
+
+#include "gtktools.h"
+#include "server-access.h"
+
+/* WARNING: Keep this up to date with gnupg's include/keyserver.h */
+#define KEYSERVER_OK 0 /* not an error */
+#define KEYSERVER_INTERNAL_ERROR 1 /* gpgkeys_ internal error */
+#define KEYSERVER_NOT_SUPPORTED 2 /* operation not supported */
+#define KEYSERVER_VERSION_ERROR 3 /* VERSION mismatch */
+#define KEYSERVER_GENERAL_ERROR 4 /* keyserver internal error */
+#define KEYSERVER_NO_MEMORY 5 /* out of memory */
+#define KEYSERVER_KEY_NOT_FOUND 6 /* key not found */
+#define KEYSERVER_KEY_EXISTS 7 /* key already exists */
+#define KEYSERVER_KEY_INCOMPLETE 8 /* key incomplete (EOF) */
+#define KEYSERVER_UNREACHABLE 9 /* unable to contact keyserver */
+
+#define KEYSERVER_SCHEME_NOT_FOUND 127
+
+#define COMMAND_TEMP_NAME "gpa-com-XXXXXX"
+#define OUTPUT_TEMP_NAME "gpa-out-XXXXXX"
+
+/* Internal API */
+
+/* FIXME: THIS SHOULDN'T BE HERE
+ * The strsep function is not portable, yet parse_keyserver_uri needs it and
+ * I'm too lazy to rewrite it using GLib or ANSI functions, so we copy an
+ * implementation here. If there is no other way around it, this kind or
+ * portability function should be moved to a new file, maybe even in a
+ * separate directory. I'm putting it here to have a solution for the 0.6.1
+ * release, and should be revised at some point after that.
+ */
+
+#ifndef HAVE_STRSEP
+/* code taken from glibc-2.2.1/sysdeps/generic/strsep.c */
+char *
+strsep (char **stringp, const char *delim)
+{
+ char *begin, *end;
+
+ begin = *stringp;
+ if (begin == NULL)
+ return NULL;
+
+ /* A frequent case is when the delimiter string contains only one
+ character. Here we don't need to call the expensive `strpbrk'
+ function and instead work using `strchr'. */
+ if (delim[0] == '\0' || delim[1] == '\0')
+ {
+ char ch = delim[0];
+
+ if (ch == '\0')
+ end = NULL;
+ else
+ {
+ if (*begin == ch)
+ end = begin;
+ else if (*begin == '\0')
+ end = NULL;
+ else
+ end = strchr (begin + 1, ch);
+ }
+ }
+ else
+ /* Find the end of the token. */
+ end = strpbrk (begin, delim);
+
+ if (end)
+ {
+ /* Terminate the token and set *STRINGP past NUL character. */
+ *end++ = '\0';
+ *stringp = end;
+ }
+ else
+ /* No more delimiters; this is the last token. */
+ *stringp = NULL;
+
+ return begin;
+}
+#endif /*HAVE_STRSEP*/
+
+/* Code adapted from GnuPG (file g10/keyserver.c) */
+static gboolean
+parse_keyserver_uri (char *uri, char **scheme, char **host,
+ char **port, char **opaque)
+{
+ int assume_hkp=0;
+
+ assert(uri!=NULL);
+
+ *host=NULL;
+ *port=NULL;
+ *opaque=NULL;
+
+ /* Get the scheme */
+
+ *scheme=strsep(&uri,":");
+ if(uri==NULL)
+ {
+ /* Assume HKP if there is no scheme */
+ assume_hkp=1;
+ uri=*scheme;
+ *scheme="hkp";
+ }
+
+ if(assume_hkp || (uri[0]=='/' && uri[1]=='/'))
+ {
+ /* Two slashes means network path. */
+
+ /* Skip over the "//", if any */
+ if(!assume_hkp)
+ uri+=2;
+
+ /* Get the host */
+ *host=strsep(&uri,":/");
+ if(*host[0]=='\0')
+ return FALSE;
+
+ if(uri==NULL || uri[0]=='\0')
+ *port=NULL;
+ else
+ {
+ char *ch;
+
+ /* Get the port */
+ *port=strsep(&uri,"/");
+
+ /* Ports are digits only */
+ ch=*port;
+ while(*ch!='\0')
+ {
+ if(!isdigit(*ch))
+ return FALSE;
+
+ ch++;
+ }
+ }
+
+ /* (any path part of the URI is discarded for now as no keyserver
+ uses it yet) */
+ }
+ else if(uri[0]!='/')
+ {
+ /* No slash means opaque. Just record the opaque blob and get
+ out. */
+ *opaque=uri;
+ return TRUE;
+ }
+ else
+ {
+ /* One slash means absolute path. We don't need to support that
+ yet. */
+ return FALSE;
+ }
+
+ if(*scheme[0]=='\0')
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Return the path to the helper for a certain scheme */
+static gchar *
+helper_path (const gchar *scheme)
+{
+ gchar *helper;
+ gchar *path;
+#ifdef G_OS_WIN32
+ char name[530];
+
+ if ( !GetModuleFileNameA (0, name, sizeof (name)-30) )
+ helper = GPA_KEYSERVER_HELPERS_DIR;
+ else
+ {
+ char *p = strrchr (name, '\\');
+ if (p)
+ *p = 0;
+ else
+ *name = 0;
+ helper = name;
+ }
+ path = g_strdup_printf ("%s\\gpg2keys_%s.exe", helper, scheme);
+ if (access (path, F_OK))
+ {
+ g_free (path);
+ path = g_strdup_printf ("%s\\gpgkeys_%s.exe", helper, scheme);
+ }
+#else
+ helper = g_strdup_printf ("gpg2keys_%s", scheme);
+ path = g_build_filename (GPA_KEYSERVER_HELPERS_DIR, helper, NULL);
+ g_free (helper);
+ if (access (path, F_OK))
+ {
+ g_free (path);
+ helper = g_strdup_printf ("gpgkeys_%s", scheme);
+ path = g_build_filename (GPA_KEYSERVER_HELPERS_DIR, helper, NULL);
+ g_free (helper);
+ }
+#endif
+ return path;
+}
+
+/* Find out the plugin protocol version */
+static int
+protocol_version (const gchar *scheme)
+{
+ gchar *helper[] = {helper_path (scheme), "-V", NULL};
+ gchar *output = NULL;
+ gint version;
+
+ g_spawn_sync (NULL, helper, NULL, G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL,
+ &output, NULL, NULL, NULL);
+ if (output && *output)
+ {
+ /* The version is a number, and it's value is it's ascii code minus
+ * the ascii code of 0 */
+ version = output[0] - '0';
+ }
+ else
+ {
+ version = 0;
+ }
+ g_free (output);
+ g_free (helper[0]);
+ return version;
+}
+
+/* Return the first error code found */
+static gint
+parse_helper_output (const gchar *filename)
+{
+ FILE *file = fopen (filename, "r");
+ char line[80];
+ gint error = KEYSERVER_GENERAL_ERROR;
+ char keyid[17];
+
+ /* Can't happen */
+ if (!file)
+ return KEYSERVER_INTERNAL_ERROR;
+
+ while (fgets(line,sizeof(line),file) != NULL)
+ if (sscanf (line,"KEY %16s FAILED %i\n", keyid, &error) == 2 )
+ {
+ break;
+ }
+ fclose (file);
+
+ return error;
+}
+
+/* Return an error string for the code */
+static const gchar *
+error_string (gint error_code)
+{
+ switch (error_code)
+ {
+ case KEYSERVER_OK:
+ return _("No error");
+ break;
+ case KEYSERVER_INTERNAL_ERROR:
+ return _("Internal error");
+ break;
+ case KEYSERVER_NOT_SUPPORTED:
+ return _("Operation not supported");
+ break;
+ case KEYSERVER_VERSION_ERROR:
+ return _("Version mismatch");
+ break;
+ case KEYSERVER_GENERAL_ERROR:
+ return _("Internal keyserver error");
+ break;
+ case KEYSERVER_NO_MEMORY:
+ return _("Out of memory");
+ break;
+ case KEYSERVER_KEY_NOT_FOUND:
+ return _("Key not found");
+ break;
+ case KEYSERVER_KEY_EXISTS:
+ return _("Key already exists on server");
+ break;
+ case KEYSERVER_KEY_INCOMPLETE:
+ return _("Key incomplete");
+ break;
+ case KEYSERVER_UNREACHABLE:
+ return _("Could not contact keyserver");
+ break;
+ default:
+ return _("Unknown Error");
+ }
+}
+
+static void
+write_command (FILE *file, const char *scheme,
+ const char *host, const char *port,
+ const char *opaque, const char *command)
+{
+ fprintf (file, "%s\n", "VERSION 1");
+ fprintf (file, "SCHEME %s\n", scheme);
+
+ if (opaque)
+ {
+ fprintf (file, "OPAQUE %s\n", opaque);
+ }
+ else
+ {
+ fprintf (file, "HOST %s\n", host);
+ if (port)
+ {
+ fprintf (file, "PORT %s\n", port);
+ }
+ }
+ fprintf (file, "%s\n", "OPTION include-revoked");
+ fprintf (file, "%s\n", "OPTION include-subkeys");
+ fprintf (file, "COMMAND %s\n\n", command);
+}
+
+static GtkWidget *
+wait_dialog (const gchar *server, GtkWidget *parent)
+{
+ GtkWidget *dialog =
+ gtk_message_dialog_new (GTK_WINDOW (parent),
+ GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_NONE,
+ _("Connecting to server \"%s\".\n"
+ "Please wait."), server);
+ /* FIXME: The dialog is not displayed */
+ gtk_widget_show_all (dialog);
+ return dialog;
+}
+
+/* Report any errors to the user. Returns TRUE if there were errors and false
+ * otherwise */
+static gboolean
+check_errors (int exit_status, gchar *error_message, gchar *output_filename,
+ int version, GtkWidget *parent)
+{
+ /* Error during connection. Try to parse the output and report the
+ * error.
+ */
+ if (version == 0)
+ {
+ /* With Version 0 plugins, we just can't know the error, so we
+ * show the error output from the plugin to the user if the process
+ * ended with error */
+ if (exit_status)
+ {
+ gchar *message = g_strdup_printf (_("An error ocurred while "
+ "contacting the server:\n\n%s"),
+ error_message);
+ gpa_window_error (message, parent);
+ return TRUE;
+ }
+ }
+ /* If version != 0, at least try to use version 1 error codes */
+ else if (exit_status)
+ {
+ gint error_code = parse_helper_output (output_filename);
+ /* Not really errors */
+ if (error_code == KEYSERVER_OK ||
+ error_code == KEYSERVER_KEY_NOT_FOUND ||
+ error_code == KEYSERVER_KEY_EXISTS)
+ {
+ return FALSE;
+ }
+ else
+ {
+ gchar *message = g_strdup_printf (_("An error ocurred while "
+ "contacting the server:\n\n%s"),
+ error_string (error_code));
+ gpa_window_error (message, parent);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* This is a hack: when a SIGCHLD is received, close the dialog. We need a
+ * global variable to pass the dialog to the signal handler. */
+#ifdef G_OS_UNIX
+GtkWidget *waiting_dlg;
+static void
+close_dialog (int sig)
+{
+ gtk_dialog_response (GTK_DIALOG (waiting_dlg), GTK_RESPONSE_CLOSE);
+}
+#endif /*G_OS_UNIX*/
+
+/* Run the helper, and update the dialog if possible. Returns FALSE on error */
+static gboolean
+do_spawn (const gchar *scheme, const gchar *command_filename,
+ const gchar *output_filename, gchar **error_output,
+ gint *exit_status, GtkWidget *dialog)
+{
+ gchar *helper_argv[] = {NULL, "-o", NULL, NULL, NULL};
+ GError *error = NULL;
+#ifdef G_OS_UNIX
+ pid_t pid;
+ gint standard_error;
+ gsize length;
+ GIOChannel *channel;
+#endif
+
+ /* Make sure output parameters get a sane value */
+ *error_output = NULL;
+ *exit_status = 127;
+ /* Build the command line */
+ helper_argv[0] = helper_path (scheme);
+ helper_argv[2] = (gchar*) output_filename;
+ helper_argv[3] = (gchar*) command_filename;
+
+ /* Invoke the keyserver helper */
+#ifdef G_OS_UNIX
+ /* On Unix, run the helper asyncronously, so that we can update the dialog */
+ g_spawn_async_with_pipes (NULL, helper_argv, NULL,
+ G_SPAWN_STDOUT_TO_DEV_NULL|
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, &pid, NULL, NULL, &standard_error,
+ &error);
+#else
+ /* On Windows, use syncronous spawn */
+ g_spawn_sync (NULL, helper_argv, NULL,
+ G_SPAWN_STDOUT_TO_DEV_NULL, NULL, NULL,
+ NULL, error_output, exit_status, &error);
+#endif
+
+ /* Free the helper's filename */
+ g_free (helper_argv[0]);
+
+ if (error)
+ {
+ /* An error ocurred in the fork/exec: we assume that there is no plugin.
+ */
+ gpa_window_error (_("There is no plugin available for the keyserver\n"
+ "protocol you specified."), dialog);
+ return FALSE;
+ }
+
+#ifdef G_OS_UNIX
+ /* FIXME: Could we do this properly, without a global variable? */
+ /* We run the dialog until we get a SIGCHLD, meaning the helper has
+ * finnished, then we wait for it. */
+ waiting_dlg = dialog;
+ signal (SIGCHLD, close_dialog);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ signal (SIGCHLD, SIG_DFL);
+ wait (exit_status);
+ /* Read stderr, since we need any error message */
+ channel = g_io_channel_unix_new (standard_error);
+ g_io_channel_read_to_end (channel, error_output, &length, NULL);
+ g_io_channel_unref (channel);
+ /* Make sure the pipe is closed */
+ close (standard_error);
+#endif
+
+ return TRUE;
+}
+
+static gboolean
+invoke_helper (const gchar *server, const gchar *scheme,
+ gchar *command_filename, gchar **output_filename,
+ GtkWidget *parent)
+{
+ int exit_status;
+ int output_fd;
+ gchar *error_output;
+ GtkWidget *dialog = NULL;
+ gboolean result = TRUE;
+
+ /* Display a pretty dialog */
+ dialog = wait_dialog (server, parent);
+ /* Open the output file */
+ output_fd = g_file_open_tmp (OUTPUT_TEMP_NAME, output_filename, NULL);
+ /* Run the helper */
+ result = do_spawn (scheme, command_filename, *output_filename, &error_output,
+ &exit_status, dialog);
+ /* If the exec went well, check for errors in the output */
+ if (result)
+ {
+ result = !check_errors (exit_status, error_output, *output_filename,
+ protocol_version (scheme), dialog);
+ }
+ close (output_fd);
+ g_free (error_output);
+ /* Destroy the dialog */
+ gtk_widget_destroy (dialog);
+
+ return result;
+}
+
+/* Public functions */
+
+gboolean
+server_send_keys (const gchar *server, const gchar *keyid,
+ gpgme_data_t data, GtkWidget *parent)
+{
+ gchar *keyserver = g_strdup (server);
+ gchar *command_filename, *output_filename;
+ int command_fd;
+ FILE *command;
+ gchar *scheme, *host, *port, *opaque;
+ gboolean success;
+
+ /* Parse the URI */
+ if (!parse_keyserver_uri (keyserver, &scheme, &host, &port, &opaque))
+ {
+ gpa_window_error (_("The keyserver you specified is not valid"), parent);
+ return FALSE;
+ }
+ /* Create a temp command file */
+ command_fd = g_file_open_tmp (COMMAND_TEMP_NAME, &command_filename, NULL);
+ command = fdopen (command_fd, "w");
+ /* Write the command to the file */
+ write_command (command, scheme, host, port, opaque, "SEND");
+ /* Write the keys to the file */
+ fprintf (command, "\nKEY %s BEGIN\n", keyid);
+ dump_data_to_file (data, command);
+ fprintf (command, "\nKEY %s END\n", keyid);
+ fclose (command);
+ success = invoke_helper (server, scheme, command_filename,
+ &output_filename, parent);
+ g_free (keyserver);
+ /* Delete temp files */
+ unlink (command_filename);
+ g_free (command_filename);
+ unlink (output_filename);
+ g_free (output_filename);
+
+ return success;
+}
+
+gboolean
+server_get_key (const gchar *server, const gchar *keyid,
+ gpgme_data_t *data, GtkWidget *parent)
+{
+ gchar *keyserver = g_strdup (server);
+ gchar *command_filename, *output_filename;
+ int command_fd;
+ FILE *command;
+ gchar *scheme, *host, *port, *opaque;
+ int success;
+ gpg_error_t err;
+
+ /* Parse the URI */
+ if (!parse_keyserver_uri (keyserver, &scheme, &host, &port, &opaque))
+ {
+ /* Create an empty gpgme_data_t, so that we always return a valid one */
+ err = gpgme_data_new (data);
+ if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
+ gpa_gpgme_error (err);
+ gpa_window_error (_("The keyserver you specified is not valid"), parent);
+ return FALSE;
+ }
+ /* Create a temp command file */
+ command_fd = g_file_open_tmp (COMMAND_TEMP_NAME, &command_filename, NULL);
+ command = fdopen (command_fd, "w");
+ /* Write the command to the file */
+ write_command (command, scheme, host, port, opaque, "GET");
+ /* Write the keys to the file */
+ fprintf (command, "0x%s\n", keyid);
+ fclose (command);
+ success = invoke_helper (server, scheme, command_filename,
+ &output_filename, parent);
+ /* Read the output */
+ /* No error checking: the import will take care of that. */
+ err = gpa_gpgme_data_new_from_file (data, output_filename, parent);
+ if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
+ gpa_gpgme_error (err);
+ g_free (keyserver);
+ /* Delete temp files */
+ unlink (command_filename);
+ g_free (command_filename);
+ unlink (output_filename);
+ g_free (output_filename);
+
+ return success;
+}
Property changes on: trunk/src/server-access.c
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ native
Copied: trunk/src/server-access.h (from rev 953, trunk/src/server_access.h)
===================================================================
--- trunk/src/server_access.h 2009-02-24 14:19:00 UTC (rev 953)
+++ trunk/src/server-access.h 2009-03-03 15:40:19 UTC (rev 957)
@@ -0,0 +1,40 @@
+/* server-access.h - The GNU Privacy Assistant
+ * Copyright (C) 2002, Miguel Coca.
+ *
+ * This file is part of GPA
+ *
+ * GPA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPA 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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
+ */
+
+/* A set of functions to access the gpg keyserver helper programs.
+ */
+
+#ifndef SERVER_ACCESS_H
+#define SERVER_ACCESS_H
+
+#include <gtk/gtk.h>
+#include <gpgme.h>
+#include "gpa.h"
+
+/* Send the keys in NULL terminated array KEYS to the keyserver SERVER.
+ * The PARENT window is used as parent for any dialog the function displays.
+ */
+gboolean server_send_keys (const gchar *server, const gchar *keyid,
+ gpgme_data_t data, GtkWidget *parent);
+
+gboolean server_get_key (const gchar *server, const gchar *keyid,
+ gpgme_data_t *data, GtkWidget *parent);
+
+#endif
Property changes on: trunk/src/server-access.h
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ native
Deleted: trunk/src/server_access.c
===================================================================
--- trunk/src/server_access.c 2009-02-27 10:06:24 UTC (rev 956)
+++ trunk/src/server_access.c 2009-03-03 15:40:19 UTC (rev 957)
@@ -1,610 +0,0 @@
-/* server_access.c - The GNU Privacy Assistant keyserver access.
- Copyright (C) 2002 Miguel Coca.
- Copyright (C) 2005 g10 Code GmbH.
-
- This file is part of GPA
-
- GPA is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- GPA 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GPA; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
-
-#include <config.h>
-
-#include "gpa.h"
-#include <glib.h>
-#include <assert.h>
-#include <ctype.h>
-#include <signal.h>
-
-/* For unlink() */
-#ifdef G_OS_UNIX
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#else
-#include <windows.h>
-#include <io.h>
-#endif
-
-#include "gtktools.h"
-#include "server_access.h"
-
-/* WARNING: Keep this up to date with gnupg's include/keyserver.h */
-#define KEYSERVER_OK 0 /* not an error */
-#define KEYSERVER_INTERNAL_ERROR 1 /* gpgkeys_ internal error */
-#define KEYSERVER_NOT_SUPPORTED 2 /* operation not supported */
-#define KEYSERVER_VERSION_ERROR 3 /* VERSION mismatch */
-#define KEYSERVER_GENERAL_ERROR 4 /* keyserver internal error */
-#define KEYSERVER_NO_MEMORY 5 /* out of memory */
-#define KEYSERVER_KEY_NOT_FOUND 6 /* key not found */
-#define KEYSERVER_KEY_EXISTS 7 /* key already exists */
-#define KEYSERVER_KEY_INCOMPLETE 8 /* key incomplete (EOF) */
-#define KEYSERVER_UNREACHABLE 9 /* unable to contact keyserver */
-
-#define KEYSERVER_SCHEME_NOT_FOUND 127
-
-#define COMMAND_TEMP_NAME "gpa-com-XXXXXX"
-#define OUTPUT_TEMP_NAME "gpa-out-XXXXXX"
-
-/* Internal API */
-
-/* FIXME: THIS SHOULDN'T BE HERE
- * The strsep function is not portable, yet parse_keyserver_uri needs it and
- * I'm too lazy to rewrite it using GLib or ANSI functions, so we copy an
- * implementation here. If there is no other way around it, this kind or
- * portability function should be moved to a new file, maybe even in a
- * separate directory. I'm putting it here to have a solution for the 0.6.1
- * release, and should be revised at some point after that.
- */
-
-#ifndef HAVE_STRSEP
-/* code taken from glibc-2.2.1/sysdeps/generic/strsep.c */
-char *
-strsep (char **stringp, const char *delim)
-{
- char *begin, *end;
-
- begin = *stringp;
- if (begin == NULL)
- return NULL;
-
- /* A frequent case is when the delimiter string contains only one
- character. Here we don't need to call the expensive `strpbrk'
- function and instead work using `strchr'. */
- if (delim[0] == '\0' || delim[1] == '\0')
- {
- char ch = delim[0];
-
- if (ch == '\0')
- end = NULL;
- else
- {
- if (*begin == ch)
- end = begin;
- else if (*begin == '\0')
- end = NULL;
- else
- end = strchr (begin + 1, ch);
- }
- }
- else
- /* Find the end of the token. */
- end = strpbrk (begin, delim);
-
- if (end)
- {
- /* Terminate the token and set *STRINGP past NUL character. */
- *end++ = '\0';
- *stringp = end;
- }
- else
- /* No more delimiters; this is the last token. */
- *stringp = NULL;
-
- return begin;
-}
-#endif /*HAVE_STRSEP*/
-
-/* Code adapted from GnuPG (file g10/keyserver.c) */
-static gboolean
-parse_keyserver_uri (char *uri, char **scheme, char **host,
- char **port, char **opaque)
-{
- int assume_hkp=0;
-
- assert(uri!=NULL);
-
- *host=NULL;
- *port=NULL;
- *opaque=NULL;
-
- /* Get the scheme */
-
- *scheme=strsep(&uri,":");
- if(uri==NULL)
- {
- /* Assume HKP if there is no scheme */
- assume_hkp=1;
- uri=*scheme;
- *scheme="hkp";
- }
-
- if(assume_hkp || (uri[0]=='/' && uri[1]=='/'))
- {
- /* Two slashes means network path. */
-
- /* Skip over the "//", if any */
- if(!assume_hkp)
- uri+=2;
-
- /* Get the host */
- *host=strsep(&uri,":/");
- if(*host[0]=='\0')
- return FALSE;
-
- if(uri==NULL || uri[0]=='\0')
- *port=NULL;
- else
- {
- char *ch;
-
- /* Get the port */
- *port=strsep(&uri,"/");
-
- /* Ports are digits only */
- ch=*port;
- while(*ch!='\0')
- {
- if(!isdigit(*ch))
- return FALSE;
-
- ch++;
- }
- }
-
- /* (any path part of the URI is discarded for now as no keyserver
- uses it yet) */
- }
- else if(uri[0]!='/')
- {
- /* No slash means opaque. Just record the opaque blob and get
- out. */
- *opaque=uri;
- return TRUE;
- }
- else
- {
- /* One slash means absolute path. We don't need to support that
- yet. */
- return FALSE;
- }
-
- if(*scheme[0]=='\0')
- return FALSE;
-
- return TRUE;
-}
-
-/* Return the path to the helper for a certain scheme */
-static gchar *
-helper_path (const gchar *scheme)
-{
- gchar *helper;
- gchar *path;
-#ifdef G_OS_WIN32
- char name[530];
-
- if ( !GetModuleFileNameA (0, name, sizeof (name)-30) )
- helper = GPA_KEYSERVER_HELPERS_DIR;
- else
- {
- char *p = strrchr (name, '\\');
- if (p)
- *p = 0;
- else
- *name = 0;
- helper = name;
- }
- path = g_strdup_printf ("%s\\gpg2keys_%s.exe", helper, scheme);
- if (access (path, F_OK))
- {
- g_free (path)
- path = g_strdup_printf ("%s\\gpgkeys_%s.exe", helper, scheme);
- }
-#else
- helper = g_strdup_printf ("gpg2keys_%s", scheme);
- path = g_build_filename (GPA_KEYSERVER_HELPERS_DIR, helper, NULL);
- g_free (helper);
- if (access (path, F_OK))
- {
- g_free (path);
- helper = g_strdup_printf ("gpgkeys_%s", scheme);
- path = g_build_filename (GPA_KEYSERVER_HELPERS_DIR, helper, NULL);
- g_free (helper);
- }
-#endif
- return path;
-}
-
-/* Find out the plugin protocol version */
-static int
-protocol_version (const gchar *scheme)
-{
- gchar *helper[] = {helper_path (scheme), "-V", NULL};
- gchar *output = NULL;
- gint version;
-
- g_spawn_sync (NULL, helper, NULL, G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL,
- &output, NULL, NULL, NULL);
- if (output && *output)
- {
- /* The version is a number, and it's value is it's ascii code minus
- * the ascii code of 0 */
- version = output[0] - '0';
- }
- else
- {
- version = 0;
- }
- g_free (output);
- g_free (helper[0]);
- return version;
-}
-
-/* Return the first error code found */
-static gint
-parse_helper_output (const gchar *filename)
-{
- FILE *file = fopen (filename, "r");
- char line[80];
- gint error = KEYSERVER_GENERAL_ERROR;
- char keyid[17];
-
- /* Can't happen */
- if (!file)
- return KEYSERVER_INTERNAL_ERROR;
-
- while (fgets(line,sizeof(line),file) != NULL)
- if (sscanf (line,"KEY %16s FAILED %i\n", keyid, &error) == 2 )
- {
- break;
- }
- fclose (file);
-
- return error;
-}
-
-/* Return an error string for the code */
-static const gchar *
-error_string (gint error_code)
-{
- switch (error_code)
- {
- case KEYSERVER_OK:
- return _("No error");
- break;
- case KEYSERVER_INTERNAL_ERROR:
- return _("Internal error");
- break;
- case KEYSERVER_NOT_SUPPORTED:
- return _("Operation not supported");
- break;
- case KEYSERVER_VERSION_ERROR:
- return _("Version mismatch");
- break;
- case KEYSERVER_GENERAL_ERROR:
- return _("Internal keyserver error");
- break;
- case KEYSERVER_NO_MEMORY:
- return _("Out of memory");
- break;
- case KEYSERVER_KEY_NOT_FOUND:
- return _("Key not found");
- break;
- case KEYSERVER_KEY_EXISTS:
- return _("Key already exists on server");
- break;
- case KEYSERVER_KEY_INCOMPLETE:
- return _("Key incomplete");
- break;
- case KEYSERVER_UNREACHABLE:
- return _("Could not contact keyserver");
- break;
- default:
- return _("Unknown Error");
- }
-}
-
-static void
-write_command (FILE *file, const char *scheme,
- const char *host, const char *port,
- const char *opaque, const char *command)
-{
- fprintf (file, "%s\n", "VERSION 1");
- fprintf (file, "SCHEME %s\n", scheme);
-
- if (opaque)
- {
- fprintf (file, "OPAQUE %s\n", opaque);
- }
- else
- {
- fprintf (file, "HOST %s\n", host);
- if (port)
- {
- fprintf (file, "PORT %s\n", port);
- }
- }
- fprintf (file, "%s\n", "OPTION include-revoked");
- fprintf (file, "%s\n", "OPTION include-subkeys");
- fprintf (file, "COMMAND %s\n\n", command);
-}
-
-static GtkWidget *
-wait_dialog (const gchar *server, GtkWidget *parent)
-{
- GtkWidget *dialog =
- gtk_message_dialog_new (GTK_WINDOW (parent),
- GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
- GTK_MESSAGE_INFO, GTK_BUTTONS_NONE,
- _("Connecting to server \"%s\".\n"
- "Please wait."), server);
- /* FIXME: The dialog is not displayed */
- gtk_widget_show_all (dialog);
- return dialog;
-}
-
-/* Report any errors to the user. Returns TRUE if there were errors and false
- * otherwise */
-static gboolean
-check_errors (int exit_status, gchar *error_message, gchar *output_filename,
- int version, GtkWidget *parent)
-{
- /* Error during connection. Try to parse the output and report the
- * error.
- */
- if (version == 0)
- {
- /* With Version 0 plugins, we just can't know the error, so we
- * show the error output from the plugin to the user if the process
- * ended with error */
- if (exit_status)
- {
- gchar *message = g_strdup_printf (_("An error ocurred while "
- "contacting the server:\n\n%s"),
- error_message);
- gpa_window_error (message, parent);
- return TRUE;
- }
- }
- /* If version != 0, at least try to use version 1 error codes */
- else if (exit_status)
- {
- gint error_code = parse_helper_output (output_filename);
- /* Not really errors */
- if (error_code == KEYSERVER_OK ||
- error_code == KEYSERVER_KEY_NOT_FOUND ||
- error_code == KEYSERVER_KEY_EXISTS)
- {
- return FALSE;
- }
- else
- {
- gchar *message = g_strdup_printf (_("An error ocurred while "
- "contacting the server:\n\n%s"),
- error_string (error_code));
- gpa_window_error (message, parent);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/* This is a hack: when a SIGCHLD is received, close the dialog. We need a
- * global variable to pass the dialog to the signal handler. */
-GtkWidget *waiting_dlg;
-static void
-close_dialog (int sig)
-{
- gtk_dialog_response (GTK_DIALOG (waiting_dlg), GTK_RESPONSE_CLOSE);
-}
-
-/* Run the helper, and update the dialog if possible. Returns FALSE on error */
-static gboolean
-do_spawn (const gchar *scheme, const gchar *command_filename,
- const gchar *output_filename, gchar **error_output,
- gint *exit_status, GtkWidget *dialog)
-{
- gchar *helper_argv[] = {NULL, "-o", NULL, NULL, NULL};
- GError *error = NULL;
-#ifdef G_OS_UNIX
- pid_t pid;
- gint standard_error;
- gsize length;
- GIOChannel *channel;
-#endif
-
- /* Make sure output parameters get a sane value */
- *error_output = NULL;
- *exit_status = 127;
- /* Build the command line */
- helper_argv[0] = helper_path (scheme);
- helper_argv[2] = (gchar*) output_filename;
- helper_argv[3] = (gchar*) command_filename;
-
- /* Invoke the keyserver helper */
-#ifdef G_OS_UNIX
- /* On Unix, run the helper asyncronously, so that we can update the dialog */
- g_spawn_async_with_pipes (NULL, helper_argv, NULL,
- G_SPAWN_STDOUT_TO_DEV_NULL|
- G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL, &pid, NULL, NULL, &standard_error,
- &error);
-#else
- /* On Windows, use syncronous spawn */
- g_spawn_sync (NULL, helper_argv, NULL,
- G_SPAWN_STDOUT_TO_DEV_NULL, NULL, NULL,
- NULL, error_output, exit_status, &error);
-#endif
-
- /* Free the helper's filename */
- g_free (helper_argv[0]);
-
- if (error)
- {
- /* An error ocurred in the fork/exec: we assume that there is no plugin.
- */
- gpa_window_error (_("There is no plugin available for the keyserver\n"
- "protocol you specified."), dialog);
- return FALSE;
- }
-
-#ifdef G_OS_UNIX
- /* FIXME: Could we do this properly, without a global variable? */
- /* We run the dialog until we get a SIGCHLD, meaning the helper has
- * finnished, then we wait for it. */
- waiting_dlg = dialog;
- signal (SIGCHLD, close_dialog);
- gtk_dialog_run (GTK_DIALOG (dialog));
- signal (SIGCHLD, SIG_DFL);
- wait (exit_status);
- /* Read stderr, since we need any error message */
- channel = g_io_channel_unix_new (standard_error);
- g_io_channel_read_to_end (channel, error_output, &length, NULL);
- g_io_channel_unref (channel);
- /* Make sure the pipe is closed */
- close (standard_error);
-#endif
-
- return TRUE;
-}
-
-static gboolean
-invoke_helper (const gchar *server, const gchar *scheme,
- gchar *command_filename, gchar **output_filename,
- GtkWidget *parent)
-{
- int exit_status;
- int output_fd;
- gchar *error_output;
- GtkWidget *dialog = NULL;
- gboolean result = TRUE;
-
- /* Display a pretty dialog */
- dialog = wait_dialog (server, parent);
- /* Open the output file */
- output_fd = g_file_open_tmp (OUTPUT_TEMP_NAME, output_filename, NULL);
- /* Run the helper */
- result = do_spawn (scheme, command_filename, *output_filename, &error_output,
- &exit_status, dialog);
- /* If the exec went well, check for errors in the output */
- if (result)
- {
- result = !check_errors (exit_status, error_output, *output_filename,
- protocol_version (scheme), dialog);
- }
- close (output_fd);
- g_free (error_output);
- /* Destroy the dialog */
- gtk_widget_destroy (dialog);
-
- return result;
-}
-
-/* Public functions */
-
-gboolean
-server_send_keys (const gchar *server, const gchar *keyid,
- gpgme_data_t data, GtkWidget *parent)
-{
- gchar *keyserver = g_strdup (server);
- gchar *command_filename, *output_filename;
- int command_fd;
- FILE *command;
- gchar *scheme, *host, *port, *opaque;
- gboolean success;
-
- /* Parse the URI */
- if (!parse_keyserver_uri (keyserver, &scheme, &host, &port, &opaque))
- {
- gpa_window_error (_("The keyserver you specified is not valid"), parent);
- return FALSE;
- }
- /* Create a temp command file */
- command_fd = g_file_open_tmp (COMMAND_TEMP_NAME, &command_filename, NULL);
- command = fdopen (command_fd, "w");
- /* Write the command to the file */
- write_command (command, scheme, host, port, opaque, "SEND");
- /* Write the keys to the file */
- fprintf (command, "\nKEY %s BEGIN\n", keyid);
- dump_data_to_file (data, command);
- fprintf (command, "\nKEY %s END\n", keyid);
- fclose (command);
- success = invoke_helper (server, scheme, command_filename,
- &output_filename, parent);
- g_free (keyserver);
- /* Delete temp files */
- unlink (command_filename);
- g_free (command_filename);
- unlink (output_filename);
- g_free (output_filename);
-
- return success;
-}
-
-gboolean
-server_get_key (const gchar *server, const gchar *keyid,
- gpgme_data_t *data, GtkWidget *parent)
-{
- gchar *keyserver = g_strdup (server);
- gchar *command_filename, *output_filename;
- int command_fd;
- FILE *command;
- gchar *scheme, *host, *port, *opaque;
- int success;
- gpg_error_t err;
-
- /* Parse the URI */
- if (!parse_keyserver_uri (keyserver, &scheme, &host, &port, &opaque))
- {
- /* Create an empty gpgme_data_t, so that we always return a valid one */
- err = gpgme_data_new (data);
- if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
- gpa_gpgme_error (err);
- gpa_window_error (_("The keyserver you specified is not valid"), parent);
- return FALSE;
- }
- /* Create a temp command file */
- command_fd = g_file_open_tmp (COMMAND_TEMP_NAME, &command_filename, NULL);
- command = fdopen (command_fd, "w");
- /* Write the command to the file */
- write_command (command, scheme, host, port, opaque, "GET");
- /* Write the keys to the file */
- fprintf (command, "0x%s\n", keyid);
- fclose (command);
- success = invoke_helper (server, scheme, command_filename,
- &output_filename, parent);
- /* Read the output */
- /* No error checking: the import will take care of that. */
- err = gpa_gpgme_data_new_from_file (data, output_filename, parent);
- if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
- gpa_gpgme_error (err);
- g_free (keyserver);
- /* Delete temp files */
- unlink (command_filename);
- g_free (command_filename);
- unlink (output_filename);
- g_free (output_filename);
-
- return success;
-}
Deleted: trunk/src/server_access.h
===================================================================
--- trunk/src/server_access.h 2009-02-27 10:06:24 UTC (rev 956)
+++ trunk/src/server_access.h 2009-03-03 15:40:19 UTC (rev 957)
@@ -1,40 +0,0 @@
-/* server_access.h - The GNU Privacy Assistant
- * Copyright (C) 2002, Miguel Coca.
- *
- * This file is part of GPA
- *
- * GPA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GPA 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 General Public License for more details.
- *
- * You should have received a copy of the GNU 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
- */
-
-/* A set of functions to access the gpg keyserver helper programs.
- */
-
-#ifndef SERVER_ACCESS_H
-#define SERVER_ACCESS_H
-
-#include <gtk/gtk.h>
-#include <gpgme.h>
-#include "gpa.h"
-
-/* Send the keys in NULL terminated array KEYS to the keyserver SERVER.
- * The PARENT window is used as parent for any dialog the function displays.
- */
-gboolean server_send_keys (const gchar *server, const gchar *keyid,
- gpgme_data_t data, GtkWidget *parent);
-
-gboolean server_get_key (const gchar *server, const gchar *keyid,
- gpgme_data_t *data, GtkWidget *parent);
-
-#endif
More information about the Gpa-commits
mailing list