[Gpa-commits] r886 - trunk/src
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed May 7 13:19:27 CEST 2008
Author: werner
Date: 2008-05-07 13:19:25 +0200 (Wed, 07 May 2008)
New Revision: 886
Modified:
trunk/src/ChangeLog
trunk/src/gpakeydeleteop.c
trunk/src/gpakeyexpireop.c
trunk/src/gpakeypasswdop.c
trunk/src/gpakeysignop.c
trunk/src/gpakeytrustop.c
trunk/src/gpgmetools.c
trunk/src/gpgmetools.h
trunk/src/server.c
trunk/src/settingsdlg.c
Log:
Cleanups in the server code.
Implemenetd basic server code for verify and decrypt.
Show auto-key-locate options only for newer gpgs.
Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/ChangeLog 2008-05-07 11:19:25 UTC (rev 886)
@@ -1,3 +1,25 @@
+2008-05-07 Werner Koch <wk at g10code.com>
+
+ * gpakeydeleteop.c (gpa_key_delete_operation_next): Init ERR.
+
+ * gpgmetools.c (parse_version_number, parse_version_string)
+ (compare_version_strings): New. Taken from gpgme.
+ (is_gpg_version_at_least): New.
+ * settingsdlg.c (settings_dlg_constructor): Use AKL only if
+ enabled. Disabled all akl fucntion callers if not.
+
+ * server.c (cmd_session): New command; a stub for now.
+ (cmd_encrypt, cmd_prep_encrypt, cmd_sign): Factor protocol option
+ parsing out to ..
+ (parse_protocol_option): .. new.
+ (cmd_encrypt, cmd_sign): Factor common code out to ..
+ (finish_io_streams, prepare_io_streams): .. new.
+ (translate_io_streams): New.
+ (cmd_decrypt, cont_decrypt): New.
+ (cont_verify, cmd_verify): New.
+ (close_message_fd, cmd_message): New.
+ (my_gpgme_message_read_cb): New.
+
2008-05-06 Marcus Brinkmann <marcus at ulysses.g10code.com>
* gpakeydeleteop.c (gpa_key_delete_operation_next), gpakeysignop.c
Modified: trunk/src/gpakeydeleteop.c
===================================================================
--- trunk/src/gpakeydeleteop.c 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/gpakeydeleteop.c 2008-05-07 11:19:25 UTC (rev 886)
@@ -149,7 +149,8 @@
gpgme_key_t key;
key = gpa_key_operation_current_key (GPA_KEY_OPERATION (op));
-
+ g_return_val_if_fail (key, gpg_error (GPG_ERR_CANCELED));
+
if (! gpa_delete_dialog_run (GPA_OPERATION (op)->window, key))
return gpg_error (GPG_ERR_CANCELED);
@@ -180,7 +181,7 @@
static void
gpa_key_delete_operation_next (GpaKeyDeleteOperation *op)
{
- gpg_error_t err;
+ gpg_error_t err = 0;
if (GPA_KEY_OPERATION (op)->current)
{
Modified: trunk/src/gpakeyexpireop.c
===================================================================
--- trunk/src/gpakeyexpireop.c 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/gpakeyexpireop.c 2008-05-07 11:19:25 UTC (rev 886)
@@ -175,6 +175,7 @@
GDate *date;
key = gpa_key_operation_current_key (GPA_KEY_OPERATION (op));
+ g_return_val_if_fail (key, gpg_error (GPG_ERR_CANCELED));
if (! gpa_expiry_dialog_run (GPA_OPERATION (op)->window, key, &date))
return gpg_error (GPG_ERR_CANCELED);
Modified: trunk/src/gpakeypasswdop.c
===================================================================
--- trunk/src/gpakeypasswdop.c 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/gpakeypasswdop.c 2008-05-07 11:19:25 UTC (rev 886)
@@ -151,6 +151,7 @@
gpgme_key_t key;
key = gpa_key_operation_current_key (GPA_KEY_OPERATION (op));
+ g_return_val_if_fail (key, gpg_error (GPG_ERR_CANCELED));
err = gpa_gpgme_edit_passwd_start (GPA_OPERATION(op)->context, key);
if (err)
Modified: trunk/src/gpakeysignop.c
===================================================================
--- trunk/src/gpakeysignop.c 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/gpakeysignop.c 2008-05-07 11:19:25 UTC (rev 886)
@@ -160,6 +160,8 @@
gboolean sign_locally = FALSE;
key = gpa_key_operation_current_key (GPA_KEY_OPERATION (op));
+ g_return_val_if_fail (key, gpg_error (GPG_ERR_CANCELED));
+
if (! gpa_key_sign_run_dialog (GPA_OPERATION (op)->window,
key, &sign_locally))
return gpg_error (GPG_ERR_CANCELED);
Modified: trunk/src/gpakeytrustop.c
===================================================================
--- trunk/src/gpakeytrustop.c 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/gpakeytrustop.c 2008-05-07 11:19:25 UTC (rev 886)
@@ -154,6 +154,7 @@
gpgme_validity_t trust;
key = gpa_key_operation_current_key (GPA_KEY_OPERATION (op));
+ g_return_val_if_fail (key, gpg_error (GPG_ERR_CANCELED));
if (! gpa_ownertrust_run_dialog (key, GPA_OPERATION (op)->window, &trust))
return gpg_error (GPG_ERR_CANCELED);
Modified: trunk/src/gpgmetools.c
===================================================================
--- trunk/src/gpgmetools.c 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/gpgmetools.c 2008-05-07 11:19:25 UTC (rev 886)
@@ -24,6 +24,7 @@
#include <config.h>
#include <errno.h>
+#include <ctype.h>
#include "gpa.h"
#include "gtktools.h"
#include "gpgmetools.h"
@@ -1064,3 +1065,110 @@
}
}
+
+
+
+
+/* Read the next number in the version string STR and return it in
+ *NUMBER. Return a pointer to the tail of STR after parsing, or
+ *NULL if the version string was invalid. */
+static const char *
+parse_version_number (const char *str, int *number)
+{
+#define MAXVAL ((INT_MAX - 10) / 10)
+ int val = 0;
+
+ /* Leading zeros are not allowed. */
+ if (*str == '0' && isascii (str[1]) && isdigit (str[1]))
+ return NULL;
+
+ while (isascii (*str) && isdigit (*str) && val <= MAXVAL)
+ {
+ val *= 10;
+ val += *(str++) - '0';
+ }
+ *number = val;
+ return val > MAXVAL ? NULL : str;
+#undef MAXVAL
+}
+
+
+/* Parse the version string STR in the format MAJOR.MINOR.MICRO (for
+ example, 9.3.2) and return the components in MAJOR, MINOR and MICRO
+ as integers. The function returns the tail of the string that
+ follows the version number. This might be te empty string if there
+ is nothing following the version number, or a patchlevel. The
+ function returns NULL if the version string is not valid. */
+static const char *
+parse_version_string (const char *str, int *major, int *minor, int *micro)
+{
+ str = parse_version_number (str, major);
+ if (!str || *str != '.')
+ return NULL;
+ str++;
+
+ str = parse_version_number (str, minor);
+ if (!str || *str != '.')
+ return NULL;
+ str++;
+
+ str = parse_version_number (str, micro);
+ if (!str)
+ return NULL;
+
+ /* A patchlevel might follow. */
+ return str;
+}
+
+
+/* Return true if MY_VERSION is at least REQ_VERSION, and false
+ otherwise. */
+static int
+compare_version_strings (const char *my_version,
+ const char *rq_version)
+{
+ int my_major, my_minor, my_micro;
+ int rq_major, rq_minor, rq_micro;
+ const char *my_plvl, *rq_plvl;
+
+ if (!rq_version)
+ return 1;
+ if (!my_version)
+ return 0;
+
+ my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
+ if (!my_plvl)
+ return 0;
+
+ rq_plvl = parse_version_string (rq_version, &rq_major, &rq_minor, &rq_micro);
+ if (!rq_plvl)
+ return 0;
+
+ if (my_major > rq_major
+ || (my_major == rq_major && my_minor > rq_minor)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro > rq_micro)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
+ return 1;
+
+ return 0;
+}
+
+
+/* Return true if the gpg engine has at least version NEED_VERSION. */
+int
+is_gpg_version_at_least (const char *need_version)
+{
+ gpgme_engine_info_t engine;
+
+ gpgme_get_engine_info (&engine);
+ while (engine)
+ {
+ if (engine->protocol == GPGME_PROTOCOL_OpenPGP)
+ return compare_version_strings (engine->version, need_version);
+ engine = engine->next;
+ }
+ return 0; /* No gpg-engine available. */
+}
+
Modified: trunk/src/gpgmetools.h
===================================================================
--- trunk/src/gpgmetools.h 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/gpgmetools.h 2008-05-07 11:19:25 UTC (rev 886)
@@ -188,5 +188,8 @@
/* Release all keys in the array KEYS as weel as ARRY itself. */
void gpa_gpgme_release_keyarray (gpgme_key_t *keys);
+/* Return true if the gpg engine has at least version NEED_VERSION. */
+int is_gpg_version_at_least (const char *need_version);
-#endif
+
+#endif /*GPGMETOOLS_H*/
Modified: trunk/src/server.c
===================================================================
--- trunk/src/server.c 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/server.c 2008-05-07 11:19:25 UTC (rev 886)
@@ -67,9 +67,13 @@
int input_fd;
int output_fd;
+ /* Fiel descriptor set with the MESSAGE command. */
+ int message_fd;
+
/* Channels used with the gpgme callbacks. */
GIOChannel *input_channel;
GIOChannel *output_channel;
+ GIOChannel *message_channel;
/* List of collected recipients. */
GSList *recipients;
@@ -101,7 +105,12 @@
static assuan_sock_nonce_t socket_nonce;
+/* Forward declarations. */
+static void run_server_continuation (assuan_context_t ctx, gpg_error_t err);
+
+
+
static int
not_finished (conn_ctrl_t ctrl)
@@ -233,6 +242,44 @@
NULL
};
+static ssize_t
+my_gpgme_message_read_cb (void *opaque, void *buffer, size_t size)
+{
+ conn_ctrl_t ctrl = opaque;
+ GIOStatus status;
+ size_t nread;
+ int retval;
+
+ status = g_io_channel_read_chars (ctrl->message_channel, buffer, size,
+ &nread, NULL);
+ if (status == G_IO_STATUS_AGAIN
+ || (status == G_IO_STATUS_NORMAL && !nread))
+ {
+ errno = EAGAIN;
+ retval = -1;
+ }
+ else if (status == G_IO_STATUS_NORMAL)
+ retval = (int)nread;
+ else if (status == G_IO_STATUS_EOF)
+ retval = 0;
+ else
+ {
+ errno = EIO;
+ retval = -1;
+ }
+
+ return retval;
+}
+
+static struct gpgme_data_cbs my_gpgme_message_cbs =
+ {
+ my_gpgme_message_read_cb,
+ NULL,
+ NULL,
+ NULL
+ };
+
+
/* Release the recipients stored in the connection context. */
static void
@@ -269,10 +316,209 @@
ctrl->selected_protocol = GPGME_PROTOCOL_UNKNOWN;
}
+
+/* Helper to parse an protocol option. */
+static gpg_error_t
+parse_protocol_option (assuan_context_t ctx, char *line, int mandatory,
+ gpgme_protocol_t *r_protocol)
+{
+ *r_protocol = GPGME_PROTOCOL_UNKNOWN;
+ if (has_option (line, "--protocol=OpenPGP"))
+ *r_protocol = GPGME_PROTOCOL_OpenPGP;
+ else if (has_option (line, "--protocol=CMS"))
+ *r_protocol = GPGME_PROTOCOL_CMS;
+ else if (has_option_name (line, "--protocol"))
+ return set_error (GPG_ERR_ASS_PARAMETER, "invalid protocol");
+ else if (mandatory)
+ return set_error (GPG_ERR_ASS_PARAMETER, "no protocol specified");
+
+ return 0;
+}
+
+
+static void
+close_message_fd (conn_ctrl_t ctrl)
+{
+ if (ctrl->message_fd != -1)
+ {
+ close (ctrl->message_fd);
+ ctrl->message_fd = -1;
+ }
+}
+
+
+static void
+finish_io_streams (assuan_context_t ctx,
+ gpgme_data_t *r_input_data, gpgme_data_t *r_output_data,
+ gpgme_data_t *r_message_data)
+{
+ conn_ctrl_t ctrl = assuan_get_pointer (ctx);
+
+ if (r_input_data)
+ gpgme_data_release (*r_input_data);
+ if (r_output_data)
+ gpgme_data_release (*r_output_data);
+ if (r_message_data)
+ gpgme_data_release (*r_message_data);
+ if (ctrl->input_channel)
+ {
+ g_io_channel_shutdown (ctrl->input_channel, 0, NULL);
+ ctrl->input_channel = NULL;
+ }
+ if (ctrl->output_channel)
+ {
+ g_io_channel_shutdown (ctrl->output_channel, 0, NULL);
+ ctrl->output_channel = NULL;
+ }
+ if (ctrl->message_channel)
+ {
+ g_io_channel_shutdown (ctrl->message_channel, 0, NULL);
+ ctrl->message_channel = NULL;
+ }
+}
+
+
+/* Translate the input and output file descriptors and return an error
+ if they are not set. */
+static gpg_error_t
+translate_io_streams (assuan_context_t ctx)
+{
+ conn_ctrl_t ctrl = assuan_get_pointer (ctx);
+
+ ctrl->input_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
+ if (ctrl->input_fd == -1)
+ return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
+ ctrl->output_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
+ if (ctrl->output_fd == -1)
+ return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
+ return 0;
+}
+
+
+static gpg_error_t
+prepare_io_streams (assuan_context_t ctx,
+ gpgme_data_t *r_input_data, gpgme_data_t *r_output_data,
+ gpgme_data_t *r_message_data)
+{
+ gpg_error_t err;
+ conn_ctrl_t ctrl = assuan_get_pointer (ctx);
+
+ if (r_input_data)
+ *r_input_data = NULL;
+ if (r_output_data)
+ *r_output_data = NULL;
+ if (r_message_data)
+ *r_message_data = NULL;
+
+ if (ctrl->input_fd != -1 && r_input_data)
+ {
+#ifdef HAVE_W32_SYSTEM
+ ctrl->input_channel = g_io_channel_win32_new_fd (ctrl->input_fd);
+#else
+ ctrl->input_channel = g_io_channel_unix_new (ctrl->input_fd);
+#endif
+ if (!ctrl->input_channel)
+ {
+ g_debug ("error creating input channel");
+ err = gpg_error (GPG_ERR_EIO);
+ goto leave;
+ }
+ g_io_channel_set_encoding (ctrl->input_channel, NULL, NULL);
+ g_io_channel_set_buffered (ctrl->input_channel, FALSE);
+ }
+
+ if (ctrl->output_fd != -1 && r_output_data)
+ {
+#ifdef HAVE_W32_SYSTEM
+ ctrl->output_channel = g_io_channel_win32_new_fd (ctrl->output_fd);
+#else
+ ctrl->output_channel = g_io_channel_unix_new (ctrl->output_fd);
+#endif
+ if (!ctrl->output_channel)
+ {
+ g_debug ("error creating output channel");
+ err = gpg_error (GPG_ERR_EIO);
+ goto leave;
+ }
+ g_io_channel_set_encoding (ctrl->output_channel, NULL, NULL);
+ g_io_channel_set_buffered (ctrl->output_channel, FALSE);
+ }
+
+ if (ctrl->message_fd != -1 && r_message_data)
+ {
+#ifdef HAVE_W32_SYSTEM
+ ctrl->message_channel = g_io_channel_win32_new_fd (ctrl->message_fd);
+#else
+ ctrl->message_channel = g_io_channel_unix_new (ctrl->message_fd);
+#endif
+ if (!ctrl->message_channel)
+ {
+ g_debug ("error creating message channel");
+ err = gpg_error (GPG_ERR_EIO);
+ goto leave;
+ }
+ g_io_channel_set_encoding (ctrl->message_channel, NULL, NULL);
+ g_io_channel_set_buffered (ctrl->message_channel, FALSE);
+ }
+
+ if (ctrl->input_fd != -1 && r_input_data)
+ {
+ err = gpgme_data_new_from_cbs (r_input_data, &my_gpgme_data_cbs, ctrl);
+ if (err)
+ goto leave;
+ }
+ if (ctrl->output_fd != -1 && r_output_data)
+ {
+ err = gpgme_data_new_from_cbs (r_output_data, &my_gpgme_data_cbs, ctrl);
+ if (err)
+ goto leave;
+ }
+ if (ctrl->message_fd != -1 && r_message_data)
+ {
+ err = gpgme_data_new_from_cbs (r_message_data,
+ &my_gpgme_message_cbs, ctrl);
+ if (err)
+ goto leave;
+ }
+
+ leave:
+ if (err)
+ finish_io_streams (ctx, r_input_data, r_output_data, r_message_data);
+ return err;
+}
+
+
-/* Forward declaration. */
-static void run_server_continuation (assuan_context_t ctx, gpg_error_t err);
+/* SESSION <number> [<string>]
+ The NUMBER is an arbitrary value, a server may use to associate
+ simultaneous running sessions. It is a 32 bit unsigned integer
+ with 0 as a special value indicating that no session association
+ shall be done.
+
+ If STRING is given, the server may use this as the title of a
+ window or, in the case of an email operation, to extract the
+ sender's address. The string may contain spaces; thus no
+ plus-escaping is used.
+
+ This command may be used at any time and overrides the effect of
+ the last command. A RESET command undoes the effect of this
+ command.
+*/
+static int
+cmd_session (assuan_context_t ctx, char *line)
+{
+ gpg_error_t err = 0;
+
+ line = skip_options (line);
+
+ /* FIXME implement the command. */
+
+ return assuan_process_done (ctx, err);
+}
+
+
+
/* RECIPIENT <recipient>
Set the recipient for the encryption. <recipient> is an RFC2822
@@ -295,7 +541,35 @@
}
+
+/* MESSAGE FD=<n>
+ Set the file descriptor to read a message which is used with
+ detached signatures.
+ */
+static int
+cmd_message (assuan_context_t ctx, char *line)
+{
+ conn_ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err;;
+ assuan_fd_t sysfd;
+ int fd;
+
+ err = assuan_command_parse_fd (ctx, line, &sysfd);
+ if (!err)
+ {
+ fd = translate_sys2libc_fd (sysfd, 0);
+ if (fd == -1)
+ err = set_error (GPG_ERR_ASS_NO_INPUT, NULL);
+ else
+ ctrl->message_fd = fd;
+ }
+ return assuan_process_done (ctx, err);
+}
+
+
+
+
/* Continuation for cmd_encrypt. */
static void
@@ -306,16 +580,7 @@
g_debug ("cont_encrypt called with with ERR=%s <%s>",
gpg_strerror (err), gpg_strsource (err));
- if (ctrl->input_channel)
- {
- g_io_channel_shutdown (ctrl->input_channel, 0, NULL);
- ctrl->input_channel = NULL;
- }
- if (ctrl->output_channel)
- {
- g_io_channel_shutdown (ctrl->output_channel, 0, NULL);
- ctrl->output_channel = NULL;
- }
+ finish_io_streams (ctx, NULL, NULL, NULL);
if (!err)
release_recipients (ctrl);
assuan_process_done (ctx, err);
@@ -336,26 +601,14 @@
gpgme_data_t input_data = NULL;
gpgme_data_t output_data = NULL;
+ err = parse_protocol_option (ctx, line, 1, &protocol);
+ if (err)
+ goto leave;
- if (has_option (line, "--protocol=OpenPGP"))
- protocol = GPGME_PROTOCOL_OpenPGP;
- else if (has_option (line, "--protocol=CMS"))
- protocol = GPGME_PROTOCOL_CMS;
- else if (has_option_name (line, "--protocol"))
- {
- err = set_error (GPG_ERR_ASS_PARAMETER, "invalid protocol");
- goto leave;
- }
- else
- {
- err = set_error (GPG_ERR_ASS_PARAMETER, "no protocol specified");
- goto leave;
- }
-
if (protocol != ctrl->selected_protocol)
{
if (ctrl->selected_protocol != GPGME_PROTOCOL_UNKNOWN)
- g_debug ("note: protocol does not macth the one from PREP_ENCRYPT");
+ g_debug ("note: protocol does not match the one from PREP_ENCRYPT");
reset_prepared_keys (ctrl);
}
@@ -366,52 +619,10 @@
goto leave;
}
- ctrl->input_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
- if (ctrl->input_fd == -1)
- {
- err = set_error (GPG_ERR_ASS_NO_INPUT, NULL);
- goto leave;
- }
- ctrl->output_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
- if (ctrl->output_fd == -1)
- {
- err = set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
- goto leave;
- }
-
-#ifdef HAVE_W32_SYSTEM
- ctrl->input_channel = g_io_channel_win32_new_fd (ctrl->input_fd);
-#else
- ctrl->input_channel = g_io_channel_unix_new (ctrl->input_fd);
-#endif
- if (!ctrl->input_channel)
- {
- g_debug ("error creating input channel");
- err = GPG_ERR_EIO;
- goto leave;
- }
- g_io_channel_set_encoding (ctrl->input_channel, NULL, NULL);
- g_io_channel_set_buffered (ctrl->input_channel, FALSE);
-
-#ifdef HAVE_W32_SYSTEM
- ctrl->output_channel = g_io_channel_win32_new_fd (ctrl->output_fd);
-#else
- ctrl->output_channel = g_io_channel_unix_new (ctrl->output_fd);
-#endif
- if (!ctrl->output_channel)
- {
- g_debug ("error creating output channel");
- err = GPG_ERR_EIO;
- goto leave;
- }
- g_io_channel_set_encoding (ctrl->output_channel, NULL, NULL);
- g_io_channel_set_buffered (ctrl->output_channel, FALSE);
-
-
- err = gpgme_data_new_from_cbs (&input_data, &my_gpgme_data_cbs, ctrl);
+ err = translate_io_streams (ctx);
if (err)
goto leave;
- err = gpgme_data_new_from_cbs (&output_data, &my_gpgme_data_cbs, ctrl);
+ err = prepare_io_streams (ctx, &input_data, &output_data, NULL);
if (err)
goto leave;
@@ -431,18 +642,8 @@
return not_finished (ctrl);
leave:
- gpgme_data_release (input_data);
- gpgme_data_release (output_data);
- if (ctrl->input_channel)
- {
- g_io_channel_shutdown (ctrl->input_channel, 0, NULL);
- ctrl->input_channel = NULL;
- }
- if (ctrl->output_channel)
- {
- g_io_channel_shutdown (ctrl->output_channel, 0, NULL);
- ctrl->output_channel = NULL;
- }
+ finish_io_streams (ctx, &input_data, &output_data, NULL);
+ close_message_fd (ctrl);
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
return assuan_process_done (ctx, err);
@@ -489,18 +690,12 @@
{
conn_ctrl_t ctrl = assuan_get_pointer (ctx);
gpg_error_t err;
- gpgme_protocol_t protocol = GPGME_PROTOCOL_UNKNOWN;
+ gpgme_protocol_t protocol;
GpaStreamEncryptOperation *op;
- if (has_option (line, "--protocol=OpenPGP"))
- protocol = GPGME_PROTOCOL_OpenPGP;
- else if (has_option (line, "--protocol=CMS"))
- protocol = GPGME_PROTOCOL_CMS;
- else if (has_option_name (line, "--protocol"))
- {
- err = set_error (GPG_ERR_ASS_PARAMETER, "invalid protocol");
- goto leave;
- }
+ err = parse_protocol_option (ctx, line, 0, &protocol);
+ if (err)
+ goto leave;
line = skip_options (line);
if (*line)
@@ -577,16 +772,7 @@
g_debug ("cont_sign called with with ERR=%s <%s>",
gpg_strerror (err), gpg_strsource (err));
- if (ctrl->input_channel)
- {
- g_io_channel_shutdown (ctrl->input_channel, 0, NULL);
- ctrl->input_channel = NULL;
- }
- if (ctrl->output_channel)
- {
- g_io_channel_shutdown (ctrl->output_channel, 0, NULL);
- ctrl->output_channel = NULL;
- }
+ finish_io_streams (ctx, NULL, NULL, NULL);
if (!err)
{
xfree (ctrl->sender);
@@ -605,26 +791,15 @@
{
conn_ctrl_t ctrl = assuan_get_pointer (ctx);
gpg_error_t err;
- gpgme_protocol_t protocol = 0;
+ gpgme_protocol_t protocol;
gboolean detached;
GpaStreamSignOperation *op;
gpgme_data_t input_data = NULL;
gpgme_data_t output_data = NULL;
- if (has_option (line, "--protocol=OpenPGP"))
- protocol = GPGME_PROTOCOL_OpenPGP;
- else if (has_option (line, "--protocol=CMS"))
- protocol = GPGME_PROTOCOL_CMS;
- else if (has_option_name (line, "--protocol"))
- {
- err = set_error (GPG_ERR_ASS_PARAMETER, "invalid protocol");
- goto leave;
- }
- else
- {
- err = set_error (GPG_ERR_ASS_PARAMETER, "no protocol specified");
- goto leave;
- }
+ err = parse_protocol_option (ctx, line, 1, &protocol);
+ if (err)
+ goto leave;
detached = has_option (line, "--detached");
@@ -635,58 +810,101 @@
goto leave;
}
- ctrl->input_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
- if (ctrl->input_fd == -1)
- {
- err = set_error (GPG_ERR_ASS_NO_INPUT, NULL);
- goto leave;
- }
- ctrl->output_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
- if (ctrl->output_fd == -1)
- {
- err = set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
- goto leave;
- }
+ err = translate_io_streams (ctx);
+ if (err)
+ goto leave;
+ err = prepare_io_streams (ctx, &input_data, &output_data, NULL);
+ if (err)
+ goto leave;
-#ifdef HAVE_W32_SYSTEM
- ctrl->input_channel = g_io_channel_win32_new_fd (ctrl->input_fd);
-#else
- ctrl->input_channel = g_io_channel_unix_new (ctrl->input_fd);
-#endif
- if (!ctrl->input_channel)
+ ctrl->cont_cmd = cont_sign;
+ op = gpa_stream_sign_operation_new (NULL, input_data, output_data,
+ ctrl->sender, protocol, detached);
+ input_data = output_data = NULL;
+ g_signal_connect_swapped (G_OBJECT (op), "completed",
+ G_CALLBACK (run_server_continuation), ctx);
+ g_signal_connect (G_OBJECT (op), "completed",
+ G_CALLBACK (g_object_unref), NULL);
+ g_signal_connect_swapped (G_OBJECT (op), "status",
+ G_CALLBACK (assuan_write_status), ctx);
+
+ return not_finished (ctrl);
+
+ leave:
+ finish_io_streams (ctx, &input_data, &output_data, NULL);
+ close_message_fd (ctrl);
+ assuan_close_input_fd (ctx);
+ assuan_close_output_fd (ctx);
+ return assuan_process_done (ctx, err);
+}
+
+
+
+/* Continuation for cmd_decrypt. */
+static void
+cont_decrypt (assuan_context_t ctx, gpg_error_t err)
+{
+ conn_ctrl_t ctrl = assuan_get_pointer (ctx);
+
+ g_debug ("cont_decrypt called with with ERR=%s <%s>",
+ gpg_strerror (err), gpg_strsource (err));
+
+ finish_io_streams (ctx, NULL, NULL, NULL);
+ if (!err)
{
- g_debug ("error creating input channel");
- err = GPG_ERR_EIO;
- goto leave;
+ xfree (ctrl->sender);
+ ctrl->sender = NULL;
}
- g_io_channel_set_encoding (ctrl->input_channel, NULL, NULL);
- g_io_channel_set_buffered (ctrl->input_channel, FALSE);
+ assuan_process_done (ctx, err);
+}
-#ifdef HAVE_W32_SYSTEM
- ctrl->output_channel = g_io_channel_win32_new_fd (ctrl->output_fd);
-#else
- ctrl->output_channel = g_io_channel_unix_new (ctrl->output_fd);
-#endif
- if (!ctrl->output_channel)
+
+/* DECRYPT --protocol=OpenPGP|CMS [--no-verify]
+
+ Decrypt a message given by the source set with the INPUT command
+ and write the plaintext to the sink set with the OUTPUT command.
+
+ If the option --no-verify is given, the server should not try to
+ verify a signature, in case the input data is an OpenPGP combined
+ message.
+*/
+static int
+cmd_decrypt (assuan_context_t ctx, char *line)
+{
+ conn_ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err;
+ gpgme_protocol_t protocol = 0;
+ int no_verify;
+ GpaStreamSignOperation *op; /* Fixme: use GpaStreamDecryptOperatio!!!*/
+ gpgme_data_t input_data = NULL;
+ gpgme_data_t output_data = NULL;
+
+ err = parse_protocol_option (ctx, line, 1, &protocol);
+ if (err)
+ goto leave;
+
+ no_verify= has_option (line, "--no-verify");
+
+ line = skip_options (line);
+ if (*line)
{
- g_debug ("error creating output channel");
- err = GPG_ERR_EIO;
+ err = set_error (GPG_ERR_ASS_SYNTAX, NULL);
goto leave;
}
- g_io_channel_set_encoding (ctrl->output_channel, NULL, NULL);
- g_io_channel_set_buffered (ctrl->output_channel, FALSE);
-
- err = gpgme_data_new_from_cbs (&input_data, &my_gpgme_data_cbs, ctrl);
+ err = translate_io_streams (ctx);
if (err)
goto leave;
- err = gpgme_data_new_from_cbs (&output_data, &my_gpgme_data_cbs, ctrl);
+ err = prepare_io_streams (ctx, &input_data, &output_data, NULL);
if (err)
goto leave;
- ctrl->cont_cmd = cont_sign;
+ ctrl->cont_cmd = cont_decrypt;
+
+#warning FIXME: Use decrypt.
op = gpa_stream_sign_operation_new (NULL, input_data, output_data,
- ctrl->sender, protocol, detached);
+ ctrl->sender, protocol, 1);
+
input_data = output_data = NULL;
g_signal_connect_swapped (G_OBJECT (op), "completed",
G_CALLBACK (run_server_continuation), ctx);
@@ -698,18 +916,146 @@
return not_finished (ctrl);
leave:
- gpgme_data_release (input_data);
- gpgme_data_release (output_data);
- if (ctrl->input_channel)
+ finish_io_streams (ctx, &input_data, &output_data, NULL);
+ close_message_fd (ctrl);
+ assuan_close_input_fd (ctx);
+ assuan_close_output_fd (ctx);
+ return assuan_process_done (ctx, err);
+}
+
+
+
+
+/* Continuation for cmd_verify. */
+static void
+cont_verify (assuan_context_t ctx, gpg_error_t err)
+{
+ conn_ctrl_t ctrl = assuan_get_pointer (ctx);
+
+ g_debug ("cont_verify called with with ERR=%s <%s>",
+ gpg_strerror (err), gpg_strsource (err));
+
+ finish_io_streams (ctx, NULL, NULL, NULL);
+ if (!err)
{
- g_io_channel_shutdown (ctrl->input_channel, 0, NULL);
- ctrl->input_channel = NULL;
+ xfree (ctrl->sender);
+ ctrl->sender = NULL;
}
- if (ctrl->output_channel)
+ assuan_process_done (ctx, err);
+}
+
+
+/* VERIFY --protocol=OpenPGP|CMS [--silent]
+
+ Verify a message. Depending on the combination of the
+ sources/sinks set by the commands MESSAGE, INPUT and OUTPUT, the
+ verification mode is selected like this:
+
+ MESSAGE and INPUT
+ This indicates a detached signature. Output data is not applicable.
+
+ INPUT
+ This indicates an opaque signature. As no output command has
+ been given, we are only required to check the signature.
+
+ INPUT and OUTPUT
+ This indicates an opaque signature. We write the signed data to
+ the file descriptor set by the OUTPUT command. This data is even
+ written if the signature can't be verified.
+
+ With the option --silent we won't display any dialog; this is for
+ example used by the client to get the content of an opaque signed
+ message. Sending the follwoing status message is mandatory before
+ sending the OK response:
+
+ SIGSTATUS <flag> <displaystring>
+
+ Defines FLAGS are:
+
+ none
+ The message has a signature but it could not not be verified
+ due to a missing key.
+
+ green
+ The signature is fully valid.
+
+ yellow
+ The signature is valid but additional information was shown
+ regarding the validity of the key.
+
+ red
+ The signature is not valid.
+
+ The DISPLAYSTRING is a percent-and-plus-encoded string with a short
+ human readable description of the status.
+*/
+static int
+cmd_verify (assuan_context_t ctx, char *line)
+{
+ conn_ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err;
+ gpgme_protocol_t protocol = 0;
+ int silent;
+ GpaStreamSignOperation *op; /* Fixme: use GpaStreamDecryptOperatio!!!*/
+ gpgme_data_t input_data = NULL;
+ gpgme_data_t output_data = NULL;
+ gpgme_data_t message_data = NULL;
+
+ err = parse_protocol_option (ctx, line, 1, &protocol);
+ if (err)
+ goto leave;
+
+ silent = has_option (line, "--silent");
+
+ line = skip_options (line);
+ if (*line)
{
- g_io_channel_shutdown (ctrl->output_channel, 0, NULL);
- ctrl->output_channel = NULL;
+ err = set_error (GPG_ERR_ASS_SYNTAX, NULL);
+ goto leave;
}
+
+ /* Note: We can't use translate_io_streams becuase that returns an
+ error if one is not opened but that is not an error here. */
+ ctrl->input_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
+ ctrl->output_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
+ if (ctrl->message_fd != -1 && ctrl->input_fd != -1
+ && ctrl->output_fd == -1)
+ ; /* Mode = detached. */
+ else if (ctrl->message_fd == -1 && ctrl->input_fd != -1
+ && ctrl->output_fd == -1)
+ ; /* Mode = opaque. */
+ else if (ctrl->message_fd == -1 && ctrl->input_fd != -1
+ && ctrl->output_fd != -1)
+ ; /* Mode = opaque with output. */
+ else
+ {
+ err = set_error (GPG_ERR_CONFLICT, "invalid verify mode");
+ goto leave;
+ }
+
+ err = prepare_io_streams (ctx, &input_data, &output_data, &message_data);
+ if (err)
+ goto leave;
+
+ ctrl->cont_cmd = cont_decrypt;
+
+#warning FIXME: Use verify.
+ op = gpa_stream_sign_operation_new (NULL, input_data, output_data,
+ ctrl->sender, protocol, 1);
+
+ input_data = output_data = message_data = NULL;
+ g_signal_connect_swapped (G_OBJECT (op), "completed",
+ G_CALLBACK (run_server_continuation), ctx);
+ g_signal_connect (G_OBJECT (op), "completed",
+ G_CALLBACK (g_object_unref), NULL);
+ g_signal_connect_swapped (G_OBJECT (op), "status",
+ G_CALLBACK (assuan_write_status), ctx);
+
+ return not_finished (ctrl);
+
+ leave:
+ finish_io_streams (ctx, &input_data, &output_data, &message_data);
+ close_message_fd (ctrl);
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
return assuan_process_done (ctx, err);
@@ -775,16 +1121,8 @@
release_recipients (ctrl);
xfree (ctrl->sender);
ctrl->sender = NULL;
- if (ctrl->input_channel)
- {
- g_io_channel_shutdown (ctrl->input_channel, 0, NULL);
- ctrl->input_channel = NULL;
- }
- if (ctrl->output_channel)
- {
- g_io_channel_shutdown (ctrl->output_channel, 0, NULL);
- ctrl->output_channel = NULL;
- }
+ finish_io_streams (ctx, NULL, NULL, NULL);
+ close_message_fd (ctrl);
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
if (ctrl->gpa_op)
@@ -805,13 +1143,17 @@
const char *name;
int (*handler)(assuan_context_t, char *line);
} table[] = {
+ { "SESSION", cmd_session },
{ "RECIPIENT", cmd_recipient },
{ "INPUT", NULL },
{ "OUTPUT", NULL },
+ { "MESSAGE", cmd_message },
{ "ENCRYPT", cmd_encrypt },
{ "PREP_ENCRYPT", cmd_prep_encrypt },
{ "SENDER", cmd_sender },
{ "SIGN", cmd_sign },
+ { "DECRYPT", cmd_decrypt },
+ { "VERIFY", cmd_verify },
{ "START_KEYMANAGER", cmd_start_keymanager },
{ "GETINFO", cmd_getinfo },
{ NULL }
@@ -859,6 +1201,7 @@
assuan_set_pointer (ctx, ctrl);
assuan_set_log_stream (ctx, stderr);
assuan_register_reset_notify (ctx, reset_notify);
+ ctrl->message_fd = -1;
connection_counter++;
return ctx;
Modified: trunk/src/settingsdlg.c
===================================================================
--- trunk/src/settingsdlg.c 2008-05-06 16:13:33 UTC (rev 885)
+++ trunk/src/settingsdlg.c 2008-05-07 11:19:25 UTC (rev 886)
@@ -84,7 +84,9 @@
/* Data for the auto-key-locate frame. */
struct {
- GtkWidget *frame;
+ int enabled; /* True if the AKL feature is enabled. */
+
+ GtkWidget *frame;
GtkComboBox *methods;
GtkWidget *addr_hbox;
GtkEntry *addr_entry;
@@ -162,12 +164,14 @@
if (gpa_options_get_show_advanced_options (options))
{
gtk_widget_show_all (dialog->keyserver.frame);
- gtk_widget_show_all (dialog->akl.frame);
+ if (dialog->akl.enabled)
+ gtk_widget_show_all (dialog->akl.frame);
}
else
{
gtk_widget_hide_all (dialog->keyserver.frame);
- gtk_widget_hide_all (dialog->akl.frame);
+ if (dialog->akl.enabled)
+ gtk_widget_hide_all (dialog->akl.frame);
}
}
@@ -677,7 +681,8 @@
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
GTK_RESPONSE_APPLY, newstate);
- gtk_widget_set_sensitive (dialog->akl.addr_hbox, dialog->akl.require_addr);
+ if (dialog->akl.enabled)
+ gtk_widget_set_sensitive (dialog->akl.addr_hbox, dialog->akl.require_addr);
}
@@ -706,7 +711,8 @@
gpa_options_get_default_keyserver (options));
/* AKL section. */
- parse_akl (dialog);
+ if (dialog->akl.enabled)
+ parse_akl (dialog);
update_modified (dialog, 0);
@@ -737,7 +743,7 @@
return -1;
}
- if ((errwdg = check_akl (dialog)))
+ if ( dialog->akl.enabled && (errwdg = check_akl (dialog)))
{
gpa_window_error
(_("The data given for \"Auto key locate\" is not valid."),
@@ -753,8 +759,9 @@
gpa_options_set_default_keyserver (gpa_options_get_instance (),
dialog->keyserver.url);
-
- if (dialog->akl.method_idx == -1)
+ if (!dialog->akl.enabled)
+ ;
+ else if (dialog->akl.method_idx == -1)
; /* oops: none selected. */
else if (!akl_table[dialog->akl.method_idx].list)
{
@@ -904,9 +911,13 @@
FALSE, FALSE, 0);
/* The auto key locate section. */
- frame = auto_key_locate_frame (dialog);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame,
- FALSE, FALSE, 0);
+ dialog->akl.enabled = is_gpg_version_at_least ("2.0.10");
+ if (dialog->akl.enabled)
+ {
+ frame = auto_key_locate_frame (dialog);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame,
+ FALSE, FALSE, 0);
+ }
/* Connect the response signal. */
g_signal_connect (GTK_OBJECT (dialog), "response",
More information about the Gpa-commits
mailing list