aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog15
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-gpg-context.c1179
-rw-r--r--camel/camel-gpg-context.h68
-rw-r--r--camel/camel-pgp-context.c4
-rw-r--r--camel/camel-pgp-context.h15
-rw-r--r--camel/camel-pgp-mime.c24
-rw-r--r--camel/camel-pgp-mime.h8
-rw-r--r--camel/camel.h3
9 files changed, 1286 insertions, 32 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 0341cafb34..b50345b9b7 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,18 @@
+2002-06-21 Jeffrey Stedfast <fejj@ximian.com>
+
+ * camel-gpg-context.[c,h]: New source files implementing the
+ CamelCipherContext class for gnupg.
+
+ * camel-pgp-context.c (camel_pgp_context_new): Return a
+ CamelCipherContext.
+
+ * camel-pgp-mime.c (camel_pgp_mime_part_decrypt): Take a
+ CamelCipherContext argument rather than a CamelPgpContext since we
+ now have a CamelGpgContext also.
+ (camel_pgp_mime_part_encrypt): Same.
+ (camel_pgp_mime_part_verify): Same.
+ (camel_pgp_mime_part_sign): Same.
+
2002-06-20 Jeffrey Stedfast <fejj@ximian.com>
* camel-digest-folder.c: Updated to support searching as well as
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 000b66c0b0..2c5d77486d 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -40,6 +40,7 @@ libcamel_la_SOURCES = \
camel-folder-summary.c \
camel-folder-thread.c \
camel-folder.c \
+ camel-gpg-context.c \
camel-html-parser.c \
camel-http-stream.c \
camel-index.c \
@@ -140,6 +141,7 @@ libcamelinclude_HEADERS = \
camel-folder-summary.h \
camel-folder-thread.h \
camel-folder.h \
+ camel-gpg-context.h \
camel-http-stream.h \
camel-index.h \
camel-internet-address.h \
diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c
new file mode 100644
index 0000000000..32764374ed
--- /dev/null
+++ b/camel/camel-gpg-context.c
@@ -0,0 +1,1179 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ *
+ * This program 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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 Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "camel-gpg-context.h"
+#include "camel-stream-fs.h"
+#include "camel-operation.h"
+
+static void camel_gpg_context_class_init (CamelGpgContextClass *klass);
+static void camel_gpg_context_init (CamelGpgContext *obj);
+static void camel_gpg_context_finalise (CamelObject *obj);
+
+static int gpg_sign (CamelCipherContext *ctx, const char *userid, CamelCipherHash hash,
+ CamelStream *istream, CamelStream *ostream, CamelException *ex);
+static int gpg_clearsign (CamelCipherContext *context, const char *userid,
+ CamelCipherHash hash, CamelStream *istream,
+ CamelStream *ostream, CamelException *ex);
+static CamelCipherValidity *gpg_verify (CamelCipherContext *context, CamelCipherHash hash,
+ CamelStream *istream, CamelStream *sigstream,
+ CamelException *ex);
+static int gpg_encrypt (CamelCipherContext *context, gboolean sign, const char *userid,
+ GPtrArray *recipients, CamelStream *istream, CamelStream *ostream,
+ CamelException *ex);
+static int gpg_decrypt (CamelCipherContext *context, CamelStream *istream,
+ CamelStream *ostream, CamelException *ex);
+
+static const char *gpg_hash_to_id (CamelCipherContext *context, CamelCipherHash hash);
+static CamelCipherHash gpg_id_to_hash (CamelCipherContext *context, const char *id);
+
+
+static CamelCipherContextClass *parent_class = NULL;
+
+
+CamelType
+camel_gpg_context_get_type (void)
+{
+ static CamelType type = CAMEL_INVALID_TYPE;
+
+ if (type == CAMEL_INVALID_TYPE) {
+ type = camel_type_register (camel_cipher_context_get_type (),
+ "CamelGpgContext",
+ sizeof (CamelGpgContext),
+ sizeof (CamelGpgContextClass),
+ (CamelObjectClassInitFunc) camel_gpg_context_class_init,
+ NULL,
+ (CamelObjectInitFunc) camel_gpg_context_init,
+ (CamelObjectFinalizeFunc) camel_gpg_context_finalise);
+ }
+
+ return type;
+}
+
+static void
+camel_gpg_context_class_init (CamelGpgContextClass *klass)
+{
+ CamelCipherContextClass *cipher_class = CAMEL_CIPHER_CONTEXT_CLASS (klass);
+
+ parent_class = CAMEL_CIPHER_CONTEXT_CLASS (camel_type_get_global_classfuncs (camel_cipher_context_get_type ()));
+
+ cipher_class->sign = gpg_sign;
+ cipher_class->clearsign = gpg_clearsign;
+ cipher_class->verify = gpg_verify;
+ cipher_class->encrypt = gpg_encrypt;
+ cipher_class->decrypt = gpg_decrypt;
+ cipher_class->hash_to_id = gpg_hash_to_id;
+ cipher_class->id_to_hash = gpg_id_to_hash;
+}
+
+static void
+camel_gpg_context_init (CamelGpgContext *context)
+{
+ CamelCipherContext *cipher = (CamelCipherContext *) context;
+
+ context->path = NULL;
+ context->always_trust = FALSE;
+
+ cipher->sign_protocol = "application/pgp-signature";
+ cipher->encrypt_protocol = "application/pgp-encrypted";
+}
+
+static void
+camel_gpg_context_finalise (CamelObject *object)
+{
+ CamelGpgContext *ctx = (CamelGpgContext *) object;
+
+ g_free (ctx->path);
+}
+
+
+static const char *
+gpg_hash_to_id (CamelCipherContext *context, CamelCipherHash hash)
+{
+ switch (hash) {
+ case CAMEL_CIPHER_HASH_MD2:
+ return "pgp-md2";
+ case CAMEL_CIPHER_HASH_MD5:
+ return "pgp-md5";
+ case CAMEL_CIPHER_HASH_SHA1:
+ case CAMEL_CIPHER_HASH_DEFAULT:
+ return "pgp-sha1";
+ case CAMEL_CIPHER_HASH_RIPEMD160:
+ return "pgp-ripemd160";
+ }
+
+ return NULL;
+}
+
+static CamelCipherHash
+gpg_id_to_hash (CamelCipherContext *context, const char *id)
+{
+ if (!strcmp (id, "pgp-md2"))
+ return CAMEL_CIPHER_HASH_MD2;
+ else if (!strcmp (id, "pgp-md5"))
+ return CAMEL_CIPHER_HASH_MD5;
+ else if (!strcmp (id, "pgp-sha1"))
+ return CAMEL_CIPHER_HASH_SHA1;
+ else if (!strcmp (id, "pgp-ripemd160"))
+ return CAMEL_CIPHER_HASH_RIPEMD160;
+
+ return CAMEL_CIPHER_HASH_DEFAULT;
+}
+
+
+enum _GpgCtxMode {
+ GPG_CTX_MODE_SIGN,
+ GPG_CTX_MODE_VERIFY,
+ GPG_CTX_MODE_ENCRYPT,
+ GPG_CTX_MODE_DECRYPT,
+};
+
+struct _GpgCtx {
+ enum _GpgCtxMode mode;
+ CamelSession *session;
+ GHashTable *userid_hint;
+ gboolean complete;
+ pid_t pid;
+
+ char *path;
+ char *userid;
+ char *sigfile;
+ GPtrArray *recipients;
+ CamelCipherHash hash;
+ gboolean always_trust;
+ gboolean armor;
+
+ int stdin;
+ int stdout;
+ int stderr;
+ int status_fd;
+ int passwd_fd; /* only needed for sign/decrypt */
+
+ FILE *status_fp;
+
+ gboolean need_passwd;
+ char *passwd;
+
+ CamelStream *istream;
+ CamelStream *ostream;
+
+ GByteArray *diagnostics;
+};
+
+static struct _GpgCtx *
+gpg_ctx_new (CamelSession *session, const char *path)
+{
+ struct _GpgCtx *gpg;
+
+ gpg = g_new (struct _GpgCtx, 1);
+ gpg->mode = GPG_CTX_MODE_SIGN;
+ gpg->session = session;
+ camel_object_ref (CAMEL_OBJECT (session));
+ gpg->userid_hint = g_hash_table_new (g_str_hash, g_str_equal);
+ gpg->complete = FALSE;
+ gpg->pid = (pid_t) -1;
+
+ gpg->path = g_strdup (path);
+ gpg->userid = NULL;
+ gpg->sigfile = NULL;
+ gpg->recipients = NULL;
+ gpg->hash = CAMEL_CIPHER_HASH_DEFAULT;
+ gpg->always_trust = FALSE;
+ gpg->armor = FALSE;
+
+ gpg->stdin = -1;
+ gpg->stdout = -1;
+ gpg->stderr = -1;
+ gpg->status_fd = -1;
+ gpg->passwd_fd = -1;
+
+ gpg->status_fp = NULL;
+
+ gpg->need_passwd = FALSE;
+ gpg->passwd = NULL;
+
+ gpg->istream = NULL;
+ gpg->ostream = NULL;
+
+ gpg->diagnostics = g_byte_array_new ();
+
+ return gpg;
+}
+
+static void
+gpg_ctx_set_mode (struct _GpgCtx *gpg, enum _GpgCtxMode mode)
+{
+ gpg->mode = mode;
+ gpg->need_passwd = mode == GPG_CTX_MODE_SIGN || mode == GPG_CTX_MODE_DECRYPT;
+}
+
+static void
+gpg_ctx_set_hash (struct _GpgCtx *gpg, CamelCipherHash hash)
+{
+ gpg->hash = hash;
+}
+
+static void
+gpg_ctx_set_always_trust (struct _GpgCtx *gpg, gboolean trust)
+{
+ gpg->always_trust = trust;
+}
+
+static void
+gpg_ctx_set_userid (struct _GpgCtx *gpg, const char *userid)
+{
+ g_free (gpg->userid);
+ gpg->userid = g_strdup (userid);
+}
+
+static void
+gpg_ctx_add_recipient (struct _GpgCtx *gpg, const char *keyid)
+{
+ if (gpg->mode != GPG_CTX_MODE_ENCRYPT)
+ return;
+
+ if (!gpg->recipients)
+ gpg->recipients = g_ptr_array_new ();
+
+ g_ptr_array_add (gpg->recipients, g_strdup (keyid));
+}
+
+static void
+gpg_ctx_set_sigfile (struct _GpgCtx *gpg, const char *sigfile)
+{
+ g_free (gpg->sigfile);
+ gpg->sigfile = g_strdup (sigfile);
+}
+
+static void
+gpg_ctx_set_armor (struct _GpgCtx *gpg, gboolean armor)
+{
+ gpg->armor = armor;
+}
+
+static void
+gpg_ctx_set_istream (struct _GpgCtx *gpg, CamelStream *istream)
+{
+ camel_object_ref (CAMEL_OBJECT (istream));
+ if (gpg->istream)
+ camel_object_unref (CAMEL_OBJECT (gpg->istream));
+ gpg->istream = istream;
+}
+
+static void
+gpg_ctx_set_ostream (struct _GpgCtx *gpg, CamelStream *ostream)
+{
+ camel_object_ref (CAMEL_OBJECT (ostream));
+ if (gpg->ostream)
+ camel_object_unref (CAMEL_OBJECT (gpg->ostream));
+ gpg->istream = ostream;
+}
+
+static char *
+gpg_ctx_get_diagnostics (struct _GpgCtx *gpg)
+{
+ return g_strndup (gpg->diagnostics->data, gpg->diagnostics->len);
+}
+
+static void
+userid_hint_free (gpointer key, gpointer value, gpointer user_data)
+{
+ g_free (key);
+ g_free (value);
+}
+
+static void
+gpg_ctx_free (struct _GpgCtx *gpg)
+{
+ int i;
+
+ if (gpg->session)
+ camel_object_unref (CAMEL_OBJECT (gpg->session));
+
+ g_hash_table_foreach (gpg->userid_hint, userid_hint_free, NULL);
+ g_hash_table_destroy (gpg->userid_hint);
+
+ g_free (gpg->path);
+
+ g_free (gpg->userid);
+
+ g_free (gpg->sigfile);
+
+ if (gpg->recipients) {
+ for (i = 0; i < gpg->recipients->len; i++)
+ g_free (gpg->recipients->pdata[i]);
+
+ g_ptr_array_free (gpg->recipients, TRUE);
+ }
+
+ if (gpg->stdin != -1)
+ close (gpg->stdin);
+ if (gpg->stdout != -1)
+ close (gpg->stdout);
+ if (gpg->stderr != -1)
+ close (gpg->stderr);
+ if (gpg->status_fd != -1 && gpg->status_fp == NULL)
+ close (gpg->status_fd);
+ if (gpg->passwd_fd != -1)
+ close (gpg->passwd_fd);
+
+ if (gpg->status_fp != NULL)
+ fclose (gpg->status_fp);
+
+ if (gpg->passwd)
+ g_free (gpg->passwd);
+
+ if (gpg->istream)
+ camel_object_unref (CAMEL_OBJECT (gpg->istream));
+
+ if (gpg->ostream)
+ camel_object_unref (CAMEL_OBJECT (gpg->ostream));
+
+ g_byte_array_free (gpg->diagnostics, TRUE);
+
+ g_free (gpg);
+}
+
+static const char *
+gpg_hash_str (CamelCipherHash hash)
+{
+ switch (hash) {
+ case CAMEL_CIPHER_HASH_MD2:
+ return "MD2";
+ case CAMEL_CIPHER_HASH_MD5:
+ return "MD5";
+ case CAMEL_CIPHER_HASH_SHA1:
+ return "SHA1";
+ case CAMEL_CIPHER_HASH_RIPEMD160:
+ return "RIPEMD160";
+ default:
+ return NULL;
+ }
+}
+
+static GPtrArray *
+gpg_ctx_get_argv (struct _GpgCtx *gpg, int status_fd, char **sfd, int passwd_fd, char **pfd)
+{
+ const char *hash_str;
+ GPtrArray *argv;
+ char *buf;
+ int i;
+
+ argv = g_ptr_array_new ();
+ g_ptr_array_add (argv, "gpg");
+
+ g_ptr_array_add (argv, "--verbose");
+ g_ptr_array_add (argv, "--no-secmem-warning");
+ g_ptr_array_add (argv, "--no-greeting");
+ g_ptr_array_add (argv, "--batch");
+ g_ptr_array_add (argv, "--yes");
+
+ *sfd = buf = g_strdup_printf ("%d", status_fd);
+ g_ptr_array_add (argv, "--status-fd");
+ g_ptr_array_add (argv, buf);
+
+ switch (gpg->mode) {
+ case GPG_CTX_MODE_SIGN:
+ g_ptr_array_add (argv, "--sign");
+ g_ptr_array_add (argv, "-b");
+ if (gpg->armor)
+ g_ptr_array_add (argv, "--armor");
+ hash_str = gpg_hash_str (gpg->hash);
+ if (hash_str) {
+ g_ptr_array_add (argv, "--digest-algo");
+ g_ptr_array_add (argv, (char *) hash_str);
+ }
+ if (gpg->userid) {
+ g_ptr_array_add (argv, "-u");
+ g_ptr_array_add (argv, (char *) gpg->userid);
+ }
+ g_ptr_array_add (argv, "--output");
+ g_ptr_array_add (argv, "-");
+ break;
+ case GPG_CTX_MODE_VERIFY:
+ if (!camel_session_is_online (gpg->session))
+ g_ptr_array_add (argv, "--no-auto-key-retrieve");
+ g_ptr_array_add (argv, "--no-tty");
+ g_ptr_array_add (argv, "--verify");
+ if (gpg->sigfile)
+ g_ptr_array_add (argv, gpg->sigfile);
+ g_ptr_array_add (argv, "-");
+ break;
+ case GPG_CTX_MODE_ENCRYPT:
+ g_ptr_array_add (argv, "--encrypt");
+ if (gpg->armor)
+ g_ptr_array_add (argv, "--armor");
+ if (gpg->always_trust)
+ g_ptr_array_add (argv, "--always-trust");
+ if (gpg->userid) {
+ g_ptr_array_add (argv, "-u");
+ g_ptr_array_add (argv, (char *) gpg->userid);
+ }
+ if (gpg->recipients) {
+ for (i = 0; i < gpg->recipients->len; i++) {
+ g_ptr_array_add (argv, "-r");
+ g_ptr_array_add (argv, gpg->recipients->pdata[i]);
+ }
+ }
+ g_ptr_array_add (argv, "--output");
+ g_ptr_array_add (argv, "-");
+ break;
+ case GPG_CTX_MODE_DECRYPT:
+ g_ptr_array_add (argv, "--decrypt");
+ g_ptr_array_add (argv, "--output");
+ g_ptr_array_add (argv, "-");
+ break;
+ }
+
+ if (gpg->need_passwd && passwd_fd != -1) {
+ *pfd = buf = g_strdup_printf ("%d", passwd_fd);
+ g_ptr_array_add (argv, "--passphrase-fd");
+ g_ptr_array_add (argv, buf);
+ }
+
+ g_ptr_array_add (argv, NULL);
+
+ return argv;
+}
+
+static int
+gpg_ctx_op_start (struct _GpgCtx *gpg)
+{
+ char *status_fd = NULL, *passwd_fd = NULL;
+ int i, maxfd, fds[10];
+ GPtrArray *argv;
+
+ for (i = 0; i < 10; i++)
+ fds[i] = -1;
+
+ maxfd = gpg->need_passwd ? 10 : 8;
+ for (i = 0; i < maxfd; i += 2) {
+ if (pipe (fds + i) == -1)
+ goto exception;
+ }
+
+ argv = gpg_ctx_get_argv (gpg, fds[6], &status_fd, fds[9], &passwd_fd);
+
+ if (!(gpg->pid = fork ())) {
+ /* child process */
+
+ if ((dup2 (fds[0], STDIN_FILENO) < 0 ) ||
+ (dup2 (fds[3], STDOUT_FILENO) < 0 ) ||
+ (dup2 (fds[5], STDERR_FILENO) < 0 )) {
+ _exit (255);
+ }
+
+ /* Dissociate from camel's controlling terminal so
+ * that gpg won't be able to read from it.
+ */
+ setsid ();
+
+ maxfd = sysconf (_SC_OPEN_MAX);
+ if (maxfd > 0) {
+ /* Loop over all fds. */
+ for (i = 0; i < maxfd; i++) {
+ if ((i != STDIN_FILENO) &&
+ (i != STDOUT_FILENO) &&
+ (i != STDERR_FILENO) &&
+ (i != fds[7]) && /* status fd */
+ (i != fds[8])) /* passwd fd */
+ close (i);
+ }
+ }
+
+ /* run gpg */
+ execvp (gpg->path, (char **) argv->pdata);
+ _exit (255);
+ } else if (gpg->pid < 0) {
+ g_ptr_array_free (argv, TRUE);
+ g_free (status_fd);
+ g_free (passwd_fd);
+ goto exception;
+ }
+
+ g_ptr_array_free (argv, TRUE);
+ g_free (status_fd);
+ g_free (passwd_fd);
+
+ /* Parent */
+ close (fds[0]);
+ gpg->stdin = fds[1];
+ gpg->stdout = fds[2];
+ close (fds[3]);
+ gpg->stderr = fds[4];
+ close (fds[5]);
+ gpg->status_fd = fds[6];
+ close (fds[7]);
+ if (gpg->need_passwd) {
+ close (fds[8]);
+ gpg->passwd_fd = fds[9];
+ fcntl (gpg->passwd_fd, F_SETFL, O_NONBLOCK);
+ }
+
+ fcntl (gpg->stdin, F_SETFL, O_NONBLOCK);
+ fcntl (gpg->stdout, F_SETFL, O_NONBLOCK);
+ fcntl (gpg->stderr, F_SETFL, O_NONBLOCK);
+
+ return 0;
+
+ exception:
+
+ for (i = 0; i < 10; i++) {
+ if (fds[i] != -1)
+ close (fds[i]);
+ }
+
+ return -1;
+}
+
+static const char *
+next_token (const char *in, char **token)
+{
+ const char *start, *inptr = in;
+
+ while (*inptr == ' ')
+ inptr++;
+
+ if (*inptr == '\0' || *inptr == '\n') {
+ if (token)
+ *token = NULL;
+ return inptr;
+ }
+
+ start = inptr;
+ while (*inptr && *inptr != ' ' && *inptr != '\n')
+ inptr++;
+
+ if (token)
+ *token = g_strndup (start, inptr - start);
+
+ return inptr;
+}
+
+static int
+gpg_ctx_parse_status (struct _GpgCtx *gpg, const char *status, CamelException *ex)
+{
+ if (strncmp (status, "[GNUPG:] ", 9) != 0)
+ return -1;
+
+ status += 9;
+
+ if (!strncmp (status, "USERID_HINT ", 12)) {
+ char *hint, *user;
+
+ status += 12;
+ status = next_token (status, &hint);
+ if (!hint) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to parse gpg userid hint."));
+ return -1;
+ }
+
+ if (g_hash_table_lookup (gpg->userid_hint, hint)) {
+ /* we already have this userid hint... */
+ g_free (hint);
+ return 0;
+ }
+
+ user = g_strdup (status);
+ g_strstrip (user);
+
+ g_hash_table_insert (gpg->userid_hint, hint, user);
+ } else if (!strncmp (status, "NEED_PASSPHRASE ", 16)) {
+ char *prompt, *userid;
+ const char *name;
+
+ status += 16;
+
+ status = next_token (status, &userid);
+ if (!userid) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to parse gpg passphrase request."));
+ return -1;
+ }
+
+ name = g_hash_table_lookup (gpg->userid_hint, userid);
+ if (!name)
+ name = userid;
+
+ prompt = g_strdup_printf (_("You need a passphrase to unlock the key for\n"
+ "user: \"%s\""), name);
+
+ gpg->passwd = camel_session_get_password (gpg->session, prompt, TRUE, NULL, userid, ex);
+ g_free (prompt);
+ g_free (userid);
+
+ if (gpg->passwd == NULL) {
+ if (!camel_exception_is_set (ex))
+ camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Cancelled."));
+ return -1;
+ }
+ } else if (!strncmp (status, "GOOD_PASSPHRASE ", 16)) {
+ g_free (gpg->passwd);
+ gpg->passwd = NULL;
+ gpg->need_passwd = FALSE;
+ } else if (!strncmp (status, "BAD_PASSPHRASE ", 15)) {
+ g_free (gpg->passwd);
+ gpg->passwd = NULL;
+ gpg->need_passwd = TRUE;
+ } else if (!strncmp (status, "UNEXPECTED ", 11)) {
+ /* this is an error */
+ return -1;
+ } else {
+ /* check to see if we are complete */
+ switch (gpg->mode) {
+ case GPG_CTX_MODE_SIGN:
+ if (!strncmp (status, "SIG_CREATED ", 12))
+ gpg->complete = TRUE;
+ break;
+ case GPG_CTX_MODE_VERIFY:
+ if (!strncmp (status, "TRUST_", 6))
+ gpg->complete = TRUE;
+ break;
+ case GPG_CTX_MODE_ENCRYPT:
+ if (!strncmp (status, "END_ENCRYPTION", 14))
+ gpg->complete = TRUE;
+ break;
+ case GPG_CTX_MODE_DECRYPT:
+ if (!strncmp (status, "END_DECRYPTION", 14))
+ gpg->complete = TRUE;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int
+gpg_ctx_op_step (struct _GpgCtx *gpg, CamelException *ex)
+{
+ struct timeval timeout;
+ fd_set rdset, wrset;
+ const char *mode;
+ int maxfd = 0;
+ int ret;
+
+ do {
+ FD_ZERO (&rdset);
+ FD_SET (gpg->stdout, &rdset);
+ FD_SET (gpg->stderr, &rdset);
+ FD_SET (gpg->status_fd, &rdset);
+
+ maxfd = MAX (gpg->stdout, gpg->stderr);
+ maxfd = MAX (maxfd, gpg->status_fd);
+
+ FD_ZERO (&wrset);
+ FD_SET (gpg->stdin, &wrset);
+ maxfd = MAX (maxfd, gpg->stdin);
+ if (gpg->passwd_fd != -1) {
+ FD_SET (gpg->passwd_fd, &wrset);
+ maxfd = MAX (maxfd, gpg->passwd_fd);
+ }
+
+ timeout.tv_sec = 10; /* timeout in seconds */
+ timeout.tv_usec = 0;
+
+ if ((ret = select (maxfd + 1, &rdset, &wrset, NULL, &timeout)) == 0)
+ return 0;
+
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+
+ return -1;
+ }
+
+ if (FD_ISSET (gpg->status_fd, &rdset)) {
+ /* read the status message and decide what to do... */
+ char buffer[4096];
+ FILE *fp;
+
+ if (gpg->status_fp == NULL) {
+ gpg->status_fp = fdopen (gpg->status_fd, "r");
+ if (gpg->status_fp == NULL)
+ goto exception;
+ }
+
+ fp = gpg->status_fp;
+
+ fgets (buffer, sizeof (buffer), fp);
+ return gpg_ctx_parse_status (gpg, buffer, ex);
+ }
+
+ if (FD_ISSET (gpg->stdout, &rdset) && gpg->ostream) {
+ char buffer[4096];
+ ssize_t nread;
+
+ nread = read (gpg->stdout, buffer, sizeof (buffer));
+ if (nread > 0)
+ ret = camel_stream_write (gpg->ostream, buffer, (size_t) nread);
+
+ if (ret == -1)
+ goto exception;
+
+ return 0;
+ }
+
+ if (FD_ISSET (gpg->stderr, &rdset)) {
+ char buffer[4096];
+ ssize_t nread;
+
+ nread = read (gpg->stdout, buffer, sizeof (buffer));
+ if (nread > 0)
+ g_byte_array_append (gpg->diagnostics, buffer, nread);
+
+ return 0;
+ }
+
+ if (gpg->passwd_fd != -1 && gpg->need_passwd && gpg->passwd && FD_ISSET (gpg->passwd_fd, &wrset)) {
+ ssize_t w, nwritten = 0;
+ size_t n;
+
+ /* send the passphrase to gpg */
+ n = strlen (gpg->passwd);
+ do {
+ do {
+ w = write (gpg->passwd_fd, gpg->passwd + nwritten, n - nwritten);
+ } while (w == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (w > 0)
+ nwritten += w;
+ } while (nwritten < n && w != -1);
+
+ if (ret == -1)
+ goto exception;
+
+ return 0;
+ }
+
+ if (FD_ISSET (gpg->stdin, &wrset) && gpg->istream && !camel_stream_eos (gpg->istream)) {
+ CamelStream *stream;
+
+ /* write our stream to gpg's stdin */
+ stream = camel_stream_fs_new_with_fd (gpg->stdin);
+ ret = camel_stream_write_to_stream (gpg->istream, stream);
+ if (ret != -1)
+ ret = camel_stream_flush (stream);
+ CAMEL_STREAM_FS (stream)->fd = -1;
+ camel_object_unref (CAMEL_OBJECT (stream));
+
+ if (ret == -1)
+ goto exception;
+
+ return 0;
+ }
+ } while (1);
+
+ return 0;
+
+ exception:
+
+ switch (gpg->mode) {
+ case GPG_CTX_MODE_SIGN:
+ mode = "sign";
+ break;
+ case GPG_CTX_MODE_VERIFY:
+ mode = "verify";
+ break;
+ case GPG_CTX_MODE_ENCRYPT:
+ mode = "encrypt";
+ break;
+ case GPG_CTX_MODE_DECRYPT:
+ mode = "decrypt";
+ break;
+ default:
+ g_assert_not_reached ();
+ mode = NULL;
+ break;
+ }
+
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to GPG %s message: %s\n"),
+ mode, g_strerror (errno));
+
+ return -1;
+}
+
+static gboolean
+gpg_ctx_op_complete (struct _GpgCtx *gpg)
+{
+ return gpg->complete;
+}
+
+static void
+gpg_ctx_op_cancel (struct _GpgCtx *gpg)
+{
+ pid_t retval;
+ int status;
+
+ kill (gpg->pid, SIGTERM);
+ sleep (1);
+ retval = waitpid (gpg->pid, &status, WNOHANG);
+ if (retval == 0) {
+ /* no more mr nice guy... */
+ kill (gpg->pid, SIGKILL);
+ sleep (1);
+ waitpid (gpg->pid, &status, WNOHANG);
+ }
+}
+
+static int
+gpg_ctx_op_wait (struct _GpgCtx *gpg)
+{
+ sigset_t mask, omask;
+ pid_t retval;
+ int status;
+
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGALRM);
+ sigprocmask (SIG_BLOCK, &mask, &omask);
+ alarm (1);
+ retval = waitpid (gpg->pid, &status, 0);
+ alarm (0);
+ sigprocmask (SIG_SETMASK, &omask, NULL);
+
+ if (retval == (pid_t) -1 && errno == EINTR) {
+ /* The child is hanging: send a friendly reminder. */
+ kill (gpg->pid, SIGTERM);
+ sleep (1);
+ retval = waitpid (gpg->pid, &status, WNOHANG);
+ if (retval == (pid_t) 0) {
+ /* Still hanging; use brute force. */
+ kill (gpg->pid, SIGKILL);
+ sleep (1);
+ retval = waitpid (gpg->pid, &status, WNOHANG);
+ }
+ }
+
+ if (retval != (pid_t) -1 && WIFEXITED (status))
+ return WEXITSTATUS (status);
+ else
+ return -1;
+}
+
+
+
+static int
+gpg_sign (CamelCipherContext *context, const char *userid, CamelCipherHash hash,
+ CamelStream *istream, CamelStream *ostream, CamelException *ex)
+{
+ CamelGpgContext *ctx = (CamelGpgContext *) context;
+ struct _GpgCtx *gpg;
+
+ gpg = gpg_ctx_new (context->session, ctx->path);
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_SIGN);
+ gpg_ctx_set_hash (gpg, hash);
+ gpg_ctx_set_armor (gpg, TRUE);
+ gpg_ctx_set_userid (gpg, userid);
+ gpg_ctx_set_istream (gpg, istream);
+ gpg_ctx_set_ostream (gpg, ostream);
+
+ if (gpg_ctx_op_start (gpg) == -1) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to execute gpg."));
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ while (!gpg_ctx_op_complete (gpg)) {
+ if (camel_operation_cancel_check (NULL)) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+ _("Cancelled."));
+ gpg_ctx_op_cancel (gpg);
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ if (gpg_ctx_op_step (gpg, ex) == -1) {
+ gpg_ctx_op_cancel (gpg);
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+ }
+
+ if (gpg_ctx_op_wait (gpg) != 0) {
+ char *diagnostics;
+
+ diagnostics = gpg_ctx_get_diagnostics (gpg);
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, diagnostics);
+ g_free (diagnostics);
+ }
+ gpg_ctx_free (gpg);
+
+ return 0;
+}
+
+
+static int
+gpg_clearsign (CamelCipherContext *context, const char *userid,
+ CamelCipherHash hash, CamelStream *istream,
+ CamelStream *ostream, CamelException *ex)
+{
+ return -1;
+}
+
+
+static char *
+swrite (CamelStream *istream)
+{
+ CamelStream *ostream;
+ char *template;
+ int fd, ret;
+
+ template = g_strdup ("/tmp/evolution-pgp.XXXXXX");
+ fd = mkstemp (template);
+ if (fd == -1) {
+ g_free (template);
+ return NULL;
+ }
+
+ ostream = camel_stream_fs_new_with_fd (fd);
+ ret = camel_stream_write_to_stream (istream, ostream);
+ if (ret != -1) {
+ ret = camel_stream_flush (ostream);
+ if (ret != -1)
+ ret = camel_stream_close (ostream);
+ }
+ camel_object_unref (CAMEL_OBJECT (ostream));
+
+ if (ret == -1) {
+ unlink (template);
+ g_free (template);
+ return NULL;
+ }
+
+ return template;
+}
+
+static CamelCipherValidity *
+gpg_verify (CamelCipherContext *context, CamelCipherHash hash,
+ CamelStream *istream, CamelStream *sigstream,
+ CamelException *ex)
+{
+ CamelGpgContext *ctx = (CamelGpgContext *) context;
+ CamelCipherValidity *validity;
+ char *diagnostics = NULL;
+ struct _GpgCtx *gpg;
+ char *sigfile = NULL;
+ gboolean valid;
+
+ if (sigstream != NULL) {
+ /* We are going to verify a detached signature so save
+ the signature to a temp file. */
+ sigfile = swrite (sigstream);
+ if (sigfile == NULL) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Cannot verify this message: couldn't create temp file: %s"),
+ g_strerror (errno));
+ return NULL;
+ }
+ }
+
+ gpg = gpg_ctx_new (context->session, ctx->path);
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_VERIFY);
+ gpg_ctx_set_hash (gpg, hash);
+ gpg_ctx_set_sigfile (gpg, sigfile);
+ gpg_ctx_set_istream (gpg, istream);
+
+ if (gpg_ctx_op_start (gpg) == -1) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to execute gpg."));
+ gpg_ctx_free (gpg);
+ goto exception;
+ }
+
+ while (!gpg_ctx_op_complete (gpg)) {
+ if (camel_operation_cancel_check (NULL)) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+ _("Cancelled."));
+ gpg_ctx_op_cancel (gpg);
+ goto exception;
+ }
+
+ if (gpg_ctx_op_step (gpg, ex) == -1) {
+ gpg_ctx_op_cancel (gpg);
+ goto exception;
+ }
+ }
+
+ diagnostics = gpg_ctx_get_diagnostics (gpg);
+
+ valid = gpg_ctx_op_wait (gpg) == 0;
+ gpg_ctx_free (gpg);
+
+ validity = camel_cipher_validity_new ();
+ camel_cipher_validity_set_valid (validity, valid);
+ camel_cipher_validity_set_description (validity, diagnostics);
+ g_free (diagnostics);
+
+ if (sigfile) {
+ unlink (sigfile);
+ g_free (sigfile);
+ }
+
+ return validity;
+
+ exception:
+
+ gpg_ctx_free (gpg);
+
+ if (sigfile) {
+ unlink (sigfile);
+ g_free (sigfile);
+ }
+
+ return NULL;
+}
+
+
+static int
+gpg_encrypt (CamelCipherContext *context, gboolean sign, const char *userid,
+ GPtrArray *recipients, CamelStream *istream, CamelStream *ostream,
+ CamelException *ex)
+{
+ CamelGpgContext *ctx = (CamelGpgContext *) context;
+ struct _GpgCtx *gpg;
+ int i;
+
+ gpg = gpg_ctx_new (context->session, ctx->path);
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_ENCRYPT);
+ gpg_ctx_set_armor (gpg, TRUE);
+ gpg_ctx_set_userid (gpg, userid);
+ gpg_ctx_set_istream (gpg, istream);
+ gpg_ctx_set_ostream (gpg, ostream);
+ gpg_ctx_set_always_trust (gpg, TRUE);
+
+ for (i = 0; i < recipients->len; i++) {
+ gpg_ctx_add_recipient (gpg, recipients->pdata[i]);
+ }
+
+ if (gpg_ctx_op_start (gpg) == -1) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to execute gpg."));
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ while (!gpg_ctx_op_complete (gpg)) {
+ if (camel_operation_cancel_check (NULL)) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+ _("Cancelled."));
+ gpg_ctx_op_cancel (gpg);
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ if (gpg_ctx_op_step (gpg, ex) == -1) {
+ gpg_ctx_op_cancel (gpg);
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+ }
+
+ if (gpg_ctx_op_wait (gpg) != 0) {
+ char *diagnostics;
+
+ diagnostics = gpg_ctx_get_diagnostics (gpg);
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, diagnostics);
+ g_free (diagnostics);
+ }
+
+ gpg_ctx_free (gpg);
+
+ return 0;
+}
+
+
+static int
+gpg_decrypt (CamelCipherContext *context, CamelStream *istream,
+ CamelStream *ostream, CamelException *ex)
+{
+ CamelGpgContext *ctx = (CamelGpgContext *) context;
+ struct _GpgCtx *gpg;
+
+ gpg = gpg_ctx_new (context->session, ctx->path);
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_DECRYPT);
+ gpg_ctx_set_istream (gpg, istream);
+ gpg_ctx_set_ostream (gpg, ostream);
+
+ if (gpg_ctx_op_start (gpg) == -1) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to execute gpg."));
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ while (!gpg_ctx_op_complete (gpg)) {
+ if (camel_operation_cancel_check (NULL)) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+ _("Cancelled."));
+ gpg_ctx_op_cancel (gpg);
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+
+ if (gpg_ctx_op_step (gpg, ex) == -1) {
+ gpg_ctx_op_cancel (gpg);
+ gpg_ctx_free (gpg);
+
+ return -1;
+ }
+ }
+
+ if (gpg_ctx_op_wait (gpg) != 0) {
+ char *diagnostics;
+
+ diagnostics = gpg_ctx_get_diagnostics (gpg);
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, diagnostics);
+ g_free (diagnostics);
+ }
+
+ gpg_ctx_free (gpg);
+
+ return 0;
+}
diff --git a/camel/camel-gpg-context.h b/camel/camel-gpg-context.h
new file mode 100644
index 0000000000..263e76fa0b
--- /dev/null
+++ b/camel/camel-gpg-context.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ *
+ * This program 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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 Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef __CAMEL_GPG_CONTEXT_H__
+#define __CAMEL_GPG_CONTEXT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+#include <camel/camel-cipher-context.h>
+
+#define CAMEL_GPG_CONTEXT_TYPE (camel_gpg_context_get_type ())
+#define CAMEL_GPG_CONTEXT(obj) (CAMEL_CHECK_CAST((obj), CAMEL_GPG_CONTEXT_TYPE, CamelGpgContext))
+#define CAMEL_GPG_CONTEXT_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_GPG_CONTEXT_TYPE, CamelGpgContextClass))
+#define CAMEL_IS_GPG_CONTEXT(o) (CAMEL_CHECK_TYPE((o), CAMEL_GPG_CONTEXT_TYPE))
+
+typedef struct _CamelGpgContext CamelGpgContext;
+typedef struct _CamelGpgContextClass CamelGpgContextClass;
+
+struct _CamelGpgContext {
+ CamelCipherContext parent_object;
+
+ char *path;
+
+ gboolean always_trust;
+};
+
+struct _CamelGpgContextClass {
+ CamelCipherContextClass parent_class;
+
+};
+
+
+CamelType camel_gpg_context_get_type (void);
+
+CamelCipherContext *camel_gpg_context_new (CamelSession *session, const char *path);
+
+void camel_gpg_context_set_always_trust (CamelGpgContext *ctx, gboolean trust);
+gboolean camel_gpg_context_get_always_trust (CamelGpgContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CAMEL_GPG_CONTEXT_H__ */
+
diff --git a/camel/camel-pgp-context.c b/camel/camel-pgp-context.c
index 0b5916bca2..eb315c3a18 100644
--- a/camel/camel-pgp-context.c
+++ b/camel/camel-pgp-context.c
@@ -155,7 +155,7 @@ camel_pgp_context_get_type (void)
*
* Return value: the new CamelPgpContext
**/
-CamelPgpContext *
+CamelCipherContext *
camel_pgp_context_new (CamelSession *session, CamelPgpType type, const char *path)
{
CamelPgpContext *context;
@@ -172,7 +172,7 @@ camel_pgp_context_new (CamelSession *session, CamelPgpType type, const char *pat
context->priv->type = type;
context->priv->path = g_strdup (path);
- return context;
+ return (CamelCipherContext *) context;
}
diff --git a/camel/camel-pgp-context.h b/camel/camel-pgp-context.h
index 0eaa3ec4e3..36d91f7007 100644
--- a/camel/camel-pgp-context.h
+++ b/camel/camel-pgp-context.h
@@ -60,19 +60,8 @@ typedef struct _CamelPgpContextClass {
CamelType camel_pgp_context_get_type (void);
-CamelPgpContext *camel_pgp_context_new (CamelSession *session, CamelPgpType type,
- const char *path);
-
-/* PGP routines */
-#define camel_pgp_sign(c, u, h, i, o, e) camel_cipher_sign (CAMEL_CIPHER_CONTEXT (c), u, h, i, o, e)
-
-#define camel_pgp_clearsign(c, u, h, i, o, e) camel_cipher_clearsign (CAMEL_CIPHER_CONTEXT (c), u, h, i, o, e)
-
-#define camel_pgp_verify(c, i, s, e) camel_cipher_verify (CAMEL_CIPHER_CONTEXT (c), CAMEL_CIPHER_HASH_DEFAULT, i, s, e)
-
-#define camel_pgp_encrypt(c, s, u, r, i, o, e) camel_cipher_encrypt (CAMEL_CIPHER_CONTEXT (c), s, u, r, i, o, e)
-
-#define camel_pgp_decrypt(c, i, o, e) camel_cipher_decrypt (CAMEL_CIPHER_CONTEXT (c), i, o, e)
+CamelCipherContext *camel_pgp_context_new (CamelSession *session, CamelPgpType type,
+ const char *path);
#ifdef __cplusplus
}
diff --git a/camel/camel-pgp-mime.c b/camel/camel-pgp-mime.c
index b0e3ab379e..c297194bd3 100644
--- a/camel/camel-pgp-mime.c
+++ b/camel/camel-pgp-mime.c
@@ -240,7 +240,7 @@ pgp_mime_part_sign_prepare_part (CamelMimePart *mime_part, GSList **encodings)
/**
* camel_pgp_mime_part_sign:
- * @context: PGP Context
+ * @cipher: PGP Cipher Context
* @mime_part: a MIME part that will be replaced by a pgp signed part
* @userid: userid to sign with
* @hash: one of CAMEL_PGP_HASH_TYPE_MD5 or CAMEL_PGP_HASH_TYPE_SHA1
@@ -251,7 +251,7 @@ pgp_mime_part_sign_prepare_part (CamelMimePart *mime_part, GSList **encodings)
* @ex will be set and #part will remain untouched.
**/
void
-camel_pgp_mime_part_sign (CamelPgpContext *context, CamelMimePart **mime_part, const char *userid,
+camel_pgp_mime_part_sign (CamelCipherContext *cipher, CamelMimePart **mime_part, const char *userid,
CamelCipherHash hash, CamelException *ex)
{
CamelMimePart *part, *signed_part;
@@ -327,7 +327,7 @@ camel_pgp_mime_part_sign (CamelPgpContext *context, CamelMimePart **mime_part, c
}
/* get the signature */
- if (camel_pgp_sign (context, userid, hash, stream, sigstream, ex) == -1) {
+ if (camel_cipher_sign (cipher, userid, hash, stream, sigstream, ex) == -1) {
GSList *list;
camel_object_unref (CAMEL_OBJECT (stream));
@@ -381,14 +381,14 @@ camel_pgp_mime_part_sign (CamelPgpContext *context, CamelMimePart **mime_part, c
/**
* camel_pgp_mime_part_verify:
- * @context: PGP Context
+ * @cipher: PGP Cipher Context
* @mime_part: a multipart/signed MIME Part
* @ex: exception
*
* Returns a CamelCipherValidity on success or NULL on fail.
**/
CamelCipherValidity *
-camel_pgp_mime_part_verify (CamelPgpContext *context, CamelMimePart *mime_part, CamelException *ex)
+camel_pgp_mime_part_verify (CamelCipherContext *cipher, CamelMimePart *mime_part, CamelException *ex)
{
CamelDataWrapper *wrapper;
CamelMultipart *multipart;
@@ -437,7 +437,7 @@ camel_pgp_mime_part_verify (CamelPgpContext *context, CamelMimePart *mime_part,
camel_stream_reset (sigstream);
/* verify */
- valid = camel_pgp_verify (context, stream, sigstream, ex);
+ valid = camel_cipher_verify (cipher, CAMEL_CIPHER_HASH_DEFAULT, stream, sigstream, ex);
d(printf ("attempted to verify data:\n----- BEGIN SIGNED PART -----\n%.*s----- END SIGNED PART -----\n",
CAMEL_STREAM_MEM (stream)->buffer->len, CAMEL_STREAM_MEM (stream)->buffer->data));
@@ -451,7 +451,7 @@ camel_pgp_mime_part_verify (CamelPgpContext *context, CamelMimePart *mime_part,
/**
* camel_pgp_mime_part_encrypt:
- * @context: PGP Context
+ * @cipher: PGP Cipher Context
* @mime_part: a MIME part that will be replaced by a pgp encrypted part
* @recipients: list of recipient PGP Key IDs
* @ex: exception which will be set if there are any errors.
@@ -461,7 +461,7 @@ camel_pgp_mime_part_verify (CamelPgpContext *context, CamelMimePart *mime_part,
* #ex will be set and #part will remain untouched.
**/
void
-camel_pgp_mime_part_encrypt (CamelPgpContext *context, CamelMimePart **mime_part,
+camel_pgp_mime_part_encrypt (CamelCipherContext *cipher, CamelMimePart **mime_part,
GPtrArray *recipients, CamelException *ex)
{
CamelMultipart *multipart;
@@ -490,7 +490,7 @@ camel_pgp_mime_part_encrypt (CamelPgpContext *context, CamelMimePart **mime_part
/* pgp encrypt */
ciphertext = camel_stream_mem_new ();
- if (camel_pgp_encrypt (context, FALSE, NULL, recipients, stream, ciphertext, ex) == -1) {
+ if (camel_cipher_encrypt (cipher, FALSE, NULL, recipients, stream, ciphertext, ex) == -1) {
camel_object_unref (CAMEL_OBJECT (stream));
camel_object_unref (CAMEL_OBJECT (ciphertext));
return;
@@ -540,14 +540,14 @@ camel_pgp_mime_part_encrypt (CamelPgpContext *context, CamelMimePart **mime_part
/**
* camel_pgp_mime_part_decrypt:
- * @context: PGP Context
+ * @cipher: PGP Cipher Context
* @mime_part: a multipart/encrypted MIME Part
* @ex: exception
*
* Returns the decrypted MIME Part on success or NULL on fail.
**/
CamelMimePart *
-camel_pgp_mime_part_decrypt (CamelPgpContext *context, CamelMimePart *mime_part, CamelException *ex)
+camel_pgp_mime_part_decrypt (CamelCipherContext *cipher, CamelMimePart *mime_part, CamelException *ex)
{
CamelDataWrapper *wrapper;
CamelMultipart *multipart;
@@ -580,7 +580,7 @@ camel_pgp_mime_part_decrypt (CamelPgpContext *context, CamelMimePart *mime_part,
/* get the cleartext */
stream = camel_stream_mem_new ();
- if (camel_pgp_decrypt (context, ciphertext, stream, ex) == -1) {
+ if (camel_cipher_decrypt (cipher, ciphertext, stream, ex) == -1) {
camel_object_unref (CAMEL_OBJECT (ciphertext));
camel_object_unref (CAMEL_OBJECT (stream));
return NULL;
diff --git a/camel/camel-pgp-mime.h b/camel/camel-pgp-mime.h
index 7f7928967d..e5dec18cce 100644
--- a/camel/camel-pgp-mime.h
+++ b/camel/camel-pgp-mime.h
@@ -38,22 +38,22 @@ extern "C" {
gboolean camel_pgp_mime_is_rfc2015_signed (CamelMimePart *part);
gboolean camel_pgp_mime_is_rfc2015_encrypted (CamelMimePart *part);
-void camel_pgp_mime_part_sign (CamelPgpContext *context,
+void camel_pgp_mime_part_sign (CamelCipherContext *cipher,
CamelMimePart **mime_part,
const char *userid,
CamelCipherHash hash,
CamelException *ex);
-CamelCipherValidity *camel_pgp_mime_part_verify (CamelPgpContext *context,
+CamelCipherValidity *camel_pgp_mime_part_verify (CamelCipherContext *cipher,
CamelMimePart *mime_part,
CamelException *ex);
-void camel_pgp_mime_part_encrypt (CamelPgpContext *context,
+void camel_pgp_mime_part_encrypt (CamelCipherContext *cipher,
CamelMimePart **mime_part,
GPtrArray *recipients,
CamelException *ex);
-CamelMimePart *camel_pgp_mime_part_decrypt (CamelPgpContext *context,
+CamelMimePart *camel_pgp_mime_part_decrypt (CamelCipherContext *cipher,
CamelMimePart *mime_part,
CamelException *ex);
diff --git a/camel/camel.h b/camel/camel.h
index 722b6190fd..1deebd1431 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -30,7 +30,7 @@
#ifdef __cplusplus
extern "C" {
#pragma }
-#endif /* __cplusplus }*/
+#endif /* __cplusplus */
#include <camel/camel-cipher-context.h>
#include <camel/camel-cms-context.h>
@@ -59,6 +59,7 @@ extern "C" {
#include <camel/camel-movemail.h>
#include <camel/camel-multipart.h>
#include <camel/camel-pgp-context.h>
+#include <camel/camel-gpg-context.h>
#include <camel/camel-pgp-mime.h>
#include <camel/camel-provider.h>
#include <camel/camel-seekable-stream.h>