From: Claws Mail Team Date: Sun, 8 Aug 2004 12:56:12 +0000 (+0000) Subject: This commit was manufactured by cvs2svn to create branch 'gtk2'. X-Git-Tag: gtk2_win32_last_merge~239 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=a5957781e265d33fe9245e8934de25ae028beac4;ds=sidebyside This commit was manufactured by cvs2svn to create branch 'gtk2'. Cherrypick from master 2004-08-08 12:56:11 UTC reboot ' new plugin for PGP/MIME': src/plugins/pgpmime/.cvsignore src/plugins/pgpmime/Makefile.am src/plugins/pgpmime/pgpmime.c src/plugins/pgpmime/pgpmime.h src/plugins/pgpmime/plugin.c src/plugins/pgpmime/sgpgme.c src/plugins/pgpmime/sgpgme.h --- diff --git a/src/plugins/pgpmime/.cvsignore b/src/plugins/pgpmime/.cvsignore new file mode 100644 index 000000000..2a6ab490b --- /dev/null +++ b/src/plugins/pgpmime/.cvsignore @@ -0,0 +1,7 @@ +.deps +.libs +Makefile +Makefile.in +*.o +*.lo +*.la diff --git a/src/plugins/pgpmime/Makefile.am b/src/plugins/pgpmime/Makefile.am new file mode 100644 index 000000000..e0922667c --- /dev/null +++ b/src/plugins/pgpmime/Makefile.am @@ -0,0 +1,21 @@ +plugindir = $(pkglibdir)/plugins + +plugin_LTLIBRARIES = pgpmime.la + +pgpmime_la_SOURCES = \ + plugin.c \ + pgpmime.c pgpmime.h \ + sgpgme.c sgpgme.h + +pgpmime_la_LDFLAGS = \ + -avoid-version -module + +INCLUDES = \ + -I../../ \ + -I../../common \ + -I../../gtk + +AM_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GTK_CFLAGS) \ + $(GPGME_CFLAGS) diff --git a/src/plugins/pgpmime/pgpmime.c b/src/plugins/pgpmime/pgpmime.c new file mode 100644 index 000000000..fe0793daa --- /dev/null +++ b/src/plugins/pgpmime/pgpmime.c @@ -0,0 +1,319 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2003 Hiroyuki Yamamoto & the Sylpheed-Claws team + * + * 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 Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef USE_GPGME + +#include "defs.h" +#include +#include + +#include "utils.h" +#include "privacy.h" +#include "procmime.h" +#include "pgpmime.h" +#include "sgpgme.h" +#include "prefs_common.h" + +typedef struct _PrivacyDataPGP PrivacyDataPGP; + +struct _PrivacyDataPGP +{ + PrivacyData data; + + gboolean done_sigtest; + gboolean is_signed; + GpgmeSigStat sigstatus; + GpgmeCtx ctx; +}; + +static PrivacySystem pgpmime_system; + +static gint pgpmime_check_signature(MimeInfo *mimeinfo); + +static PrivacyDataPGP *pgpmime_new_privacydata() +{ + PrivacyDataPGP *data; + + data = g_new0(PrivacyDataPGP, 1); + data->data.system = &pgpmime_system; + data->done_sigtest = FALSE; + data->is_signed = FALSE; + data->sigstatus = GPGME_SIG_STAT_NONE; + gpgme_new(&data->ctx); + + return data; +} + +static void pgpmime_free_privacydata(PrivacyData *_data) +{ + PrivacyDataPGP *data = (PrivacyDataPGP *) _data; + + g_free(data); +} + +static gboolean pgpmime_is_signed(MimeInfo *mimeinfo) +{ + MimeInfo *parent; + MimeInfo *signature; + const gchar *protocol; + PrivacyDataPGP *data = NULL; + + g_return_val_if_fail(mimeinfo != NULL, FALSE); + if (mimeinfo->privacy != NULL) { + data = (PrivacyDataPGP *) mimeinfo->privacy; + if (data->done_sigtest) + return data->is_signed; + } + + /* check parent */ + parent = procmime_mimeinfo_parent(mimeinfo); + if (parent == NULL) + return FALSE; + if ((parent->type != MIMETYPE_MULTIPART) || + g_strcasecmp(parent->subtype, "signed")) + return FALSE; + protocol = procmime_mimeinfo_get_parameter(parent, "protocol"); + if ((protocol == NULL) || g_strcasecmp(protocol, "application/pgp-signature")) + return FALSE; + + /* check if mimeinfo is the first child */ + if (parent->node->children->data != mimeinfo) + return FALSE; + + /* check signature */ + signature = parent->node->children->next != NULL ? + (MimeInfo *) parent->node->children->next->data : NULL; + if (signature == NULL) + return FALSE; + if ((signature->type != MIMETYPE_APPLICATION) || + g_strcasecmp(signature->subtype, "pgp-signature")) + return FALSE; + + if (data == NULL) { + data = pgpmime_new_privacydata(); + mimeinfo->privacy = (PrivacyData *) data; + } + data->done_sigtest = TRUE; + data->is_signed = TRUE; + + if (prefs_common.auto_check_signatures) + pgpmime_check_signature(mimeinfo); + + return TRUE; +} + +static gint pgpmime_check_signature(MimeInfo *mimeinfo) +{ + PrivacyDataPGP *data; + MimeInfo *parent, *signature; + FILE *fp; + gchar buf[BUFFSIZE]; + gchar *boundary; + GString *textstr; + gint boundary_len; + GpgmeData sigdata, textdata; + + g_return_val_if_fail(mimeinfo != NULL, -1); + g_return_val_if_fail(mimeinfo->privacy != NULL, -1); + data = (PrivacyDataPGP *) mimeinfo->privacy; + + debug_print("Checking PGP/MIME signature\n"); + parent = procmime_mimeinfo_parent(mimeinfo); + + fp = fopen(parent->filename, "rb"); + g_return_val_if_fail(fp != NULL, SIGNATURE_INVALID); + + boundary = g_hash_table_lookup(parent->parameters, "boundary"); + boundary_len = strlen(boundary); + while (fgets(buf, sizeof(buf), fp) != NULL) + if (IS_BOUNDARY(buf, boundary, boundary_len)) + break; + + textstr = g_string_new(""); + while (fgets(buf, sizeof(buf), fp) != NULL) { + gchar *buf2; + + if (IS_BOUNDARY(buf, boundary, boundary_len)) + break; + + buf2 = canonicalize_str(buf); + g_string_append(textstr, buf2); + g_free(buf2); + } + g_string_truncate(textstr, textstr->len - 2); + + gpgme_data_new_from_mem(&textdata, textstr->str, textstr->len, 0); + signature = (MimeInfo *) mimeinfo->node->next->data; + sigdata = sgpgme_data_from_mimeinfo(signature); + + data->sigstatus = + sgpgme_verify_signature (data->ctx, sigdata, textdata); + + gpgme_data_release(sigdata); + gpgme_data_release(textdata); + g_string_free(textstr, TRUE); + fclose(fp); + + return 0; +} + +static SignatureStatus pgpmime_get_sig_status(MimeInfo *mimeinfo) +{ + PrivacyDataPGP *data = (PrivacyDataPGP *) mimeinfo->privacy; + + g_return_val_if_fail(data != NULL, SIGNATURE_INVALID); + + return sgpgme_sigstat_gpgme_to_privacy(data->ctx, data->sigstatus); +} + +static gchar *pgpmime_get_sig_info_short(MimeInfo *mimeinfo) +{ + PrivacyDataPGP *data = (PrivacyDataPGP *) mimeinfo->privacy; + + g_return_val_if_fail(data != NULL, g_strdup("Error")); + + return sgpgme_sigstat_info_short(data->ctx, data->sigstatus); +} + +static gchar *pgpmime_get_sig_info_full(MimeInfo *mimeinfo) +{ + PrivacyDataPGP *data = (PrivacyDataPGP *) mimeinfo->privacy; + + g_return_val_if_fail(data != NULL, g_strdup("Error")); + + return sgpgme_sigstat_info_full(data->ctx, data->sigstatus); +} + +static gboolean pgpmime_is_encrypted(MimeInfo *mimeinfo) +{ + MimeInfo *tmpinfo; + const gchar *tmpstr; + + if (mimeinfo->type != MIMETYPE_MULTIPART) + return FALSE; + if (g_strcasecmp(mimeinfo->subtype, "encrypted")) + return FALSE; + tmpstr = procmime_mimeinfo_get_parameter(mimeinfo, "protocol"); + if ((tmpstr == NULL) || g_strcasecmp(tmpstr, "application/pgp-encrypted")) + return FALSE; + if (g_node_n_children(mimeinfo->node) != 2) + return FALSE; + + tmpinfo = (MimeInfo *) g_node_nth_child(mimeinfo->node, 0)->data; + if (tmpinfo->type != MIMETYPE_APPLICATION) + return FALSE; + if (g_strcasecmp(tmpinfo->subtype, "pgp-encrypted")) + return FALSE; + + tmpinfo = (MimeInfo *) g_node_nth_child(mimeinfo->node, 1)->data; + if (tmpinfo->type != MIMETYPE_APPLICATION) + return FALSE; + if (g_strcasecmp(tmpinfo->subtype, "octet-stream")) + return FALSE; + + return TRUE; +} + +static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo) +{ + MimeInfo *encinfo, *decinfo, *parseinfo; + GpgmeData cipher, plain; + static gint id = 0; + FILE *dstfp; + gint nread; + gchar *fname; + gchar buf[BUFFSIZE]; + + g_return_val_if_fail(pgpmime_is_encrypted(mimeinfo), NULL); + + encinfo = (MimeInfo *) g_node_nth_child(mimeinfo->node, 1)->data; + + cipher = sgpgme_data_from_mimeinfo(encinfo); + plain = sgpgme_decrypt(cipher); + gpgme_data_release(cipher); + if (plain == NULL) + return NULL; + + fname = g_strdup_printf("%s%cplaintext.%08x", + get_mime_tmp_dir(), G_DIR_SEPARATOR, ++id); + + if ((dstfp = fopen(fname, "wb")) == NULL) { + FILE_OP_ERROR(fname, "fopen"); + g_free(fname); + gpgme_data_release(plain); + return NULL; + } + + fprintf(dstfp, "MIME-Version: 1.0\n"); + gpgme_data_rewind (plain); + while (gpgme_data_read(plain, buf, sizeof(buf), &nread) == GPGME_No_Error) { + fwrite (buf, nread, 1, dstfp); + } + fclose(dstfp); + + gpgme_data_release(plain); + + parseinfo = procmime_scan_file(fname); + g_free(fname); + if (parseinfo == NULL) + return NULL; + decinfo = g_node_first_child(parseinfo->node) != NULL ? + g_node_first_child(parseinfo->node)->data : NULL; + if (decinfo == NULL) + return NULL; + + g_node_unlink(decinfo->node); + procmime_mimeinfo_free_all(parseinfo); + + decinfo->tmpfile = TRUE; + + return decinfo; +} + +static PrivacySystem pgpmime_system = { + "pgpmime", /* id */ + "PGP/Mime", /* name */ + + pgpmime_free_privacydata, /* free_privacydata */ + + pgpmime_is_signed, /* is_signed(MimeInfo *) */ + pgpmime_check_signature, /* check_signature(MimeInfo *) */ + pgpmime_get_sig_status, /* get_sig_status(MimeInfo *) */ + pgpmime_get_sig_info_short, /* get_sig_info_short(MimeInfo *) */ + pgpmime_get_sig_info_full, /* get_sig_info_full(MimeInfo *) */ + + pgpmime_is_encrypted, /* is_encrypted(MimeInfo *) */ + pgpmime_decrypt, /* decrypt(MimeInfo *) */ +}; + +void pgpmime_init() +{ + privacy_register_system(&pgpmime_system); +} + +void pgpmime_done() +{ + privacy_unregister_system(&pgpmime_system); +} + +#endif /* USE_GPGME */ diff --git a/src/plugins/pgpmime/pgpmime.h b/src/plugins/pgpmime/pgpmime.h new file mode 100644 index 000000000..a6ce4cece --- /dev/null +++ b/src/plugins/pgpmime/pgpmime.h @@ -0,0 +1,26 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2003 Hiroyuki Yamamoto & the Sylpheed-Claws team + * + * 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 Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef PGPMIME_H +#define PGPMIME_H 1 + +void pgpmime_init(void); +void pgpmime_done(void); + +#endif /* PGPMIME_H */ diff --git a/src/plugins/pgpmime/plugin.c b/src/plugins/pgpmime/plugin.c new file mode 100644 index 000000000..2453546ab --- /dev/null +++ b/src/plugins/pgpmime/plugin.c @@ -0,0 +1,69 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2003 Hiroyuki Yamamoto + * + * 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 Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "intl.h" + +#include "version.h" +#include "sgpgme.h" +#include "pgpmime.h" + +gint plugin_init(gchar **error) +{ + if ((sylpheed_get_version() > VERSION_NUMERIC)) { + *error = g_strdup("Your sylpheed version is newer than the version the plugin was built with"); + return -1; + } + + if ((sylpheed_get_version() < MAKE_NUMERIC_VERSION(0, 9, 12, 34))) { + *error = g_strdup("Your sylpheed version is too old"); + return -1; + } + + sgpgme_init(); + pgpmime_init(); + + return 0; +} + +void plugin_done(void) +{ + pgpmime_done(); + sgpgme_done(); +} + +const gchar *plugin_name(void) +{ + return _("PGP/MIME"); +} + +const gchar *plugin_desc(void) +{ + return _(""); +} + +const gchar *plugin_type(void) +{ + return "GTK"; +} diff --git a/src/plugins/pgpmime/sgpgme.c b/src/plugins/pgpmime/sgpgme.c new file mode 100644 index 000000000..7c9551032 --- /dev/null +++ b/src/plugins/pgpmime/sgpgme.c @@ -0,0 +1,305 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2003 Hiroyuki Yamamoto & the Sylpheed-Claws team + * + * 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 Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef USE_GPGME + +#include +#include +#include + +#include "sgpgme.h" +#include "privacy.h" +#include "prefs_common.h" +#include "utils.h" +#include "alertpanel.h" +#include "passphrase.h" +#include "intl.h" + +static void idle_function_for_gpgme(void) +{ + while (gtk_events_pending()) + gtk_main_iteration(); +} + +static void sgpgme_disable_all(void) +{ + /* FIXME: set a flag, so that we don't bother the user with failed + * gpgme messages */ +} + +GpgmeSigStat sgpgme_verify_signature(GpgmeCtx ctx, GpgmeData sig, + GpgmeData plain) +{ + GpgmeSigStat status; + + if (gpgme_op_verify(ctx, sig, plain, &status) != GPGME_No_Error) + return GPGME_SIG_STAT_ERROR; + + return status; +} + +SignatureStatus sgpgme_sigstat_gpgme_to_privacy(GpgmeCtx ctx, GpgmeSigStat status) +{ + unsigned long validity = 0; + + validity = gpgme_get_sig_ulong_attr(ctx, 0, + GPGME_ATTR_VALIDITY, 0); + + switch (status) { + case GPGME_SIG_STAT_GOOD: + if ((validity != GPGME_VALIDITY_MARGINAL) && + (validity != GPGME_VALIDITY_FULL) && + (validity != GPGME_VALIDITY_ULTIMATE)) + return SIGNATURE_WARN; + return SIGNATURE_OK; + case GPGME_SIG_STAT_GOOD_EXP: + case GPGME_SIG_STAT_GOOD_EXPKEY: + case GPGME_SIG_STAT_DIFF: + return SIGNATURE_WARN; + case GPGME_SIG_STAT_BAD: + return SIGNATURE_INVALID; + case GPGME_SIG_STAT_NOKEY: + case GPGME_SIG_STAT_NOSIG: + case GPGME_SIG_STAT_ERROR: + return SIGNATURE_CHECK_FAILED; + case GPGME_SIG_STAT_NONE: + return SIGNATURE_UNCHECKED; + } + return SIGNATURE_CHECK_FAILED; +} + +static const gchar *get_validity_str(unsigned long validity) +{ + switch (validity) { + case GPGME_VALIDITY_UNKNOWN: + return _("Unknown"); + case GPGME_VALIDITY_UNDEFINED: + return _("Undefined"); + case GPGME_VALIDITY_NEVER: + return _("Never"); + case GPGME_VALIDITY_MARGINAL: + return _("Marginal"); + case GPGME_VALIDITY_FULL: + return _("Full"); + case GPGME_VALIDITY_ULTIMATE: + return _("Ultimate"); + default: + return _("Error"); + } +} + +gchar *sgpgme_sigstat_info_short(GpgmeCtx ctx, GpgmeSigStat status) +{ + switch (status) { + case GPGME_SIG_STAT_GOOD: + { + GpgmeKey key; + unsigned long validity = 0; + + if (gpgme_get_sig_key(ctx, 0, &key) != GPGME_No_Error) + return g_strdup(_("Error")); + + validity = gpgme_get_sig_ulong_attr(ctx, 0, + GPGME_ATTR_VALIDITY, 0); + + return g_strdup_printf(_("Valid signature by %s (Trust: %s)"), + gpgme_key_get_string_attr(key, GPGME_ATTR_NAME, NULL, 0), + get_validity_str(validity)); + } + case GPGME_SIG_STAT_GOOD_EXP: + return g_strdup(_("The signature has expired")); + case GPGME_SIG_STAT_GOOD_EXPKEY: + return g_strdup(_("The key that was used to sign this part has expired")); + case GPGME_SIG_STAT_DIFF: + return g_strdup(_("Not all signatures are valid")); + case GPGME_SIG_STAT_BAD: + return g_strdup(_("This signature is invalid")); + case GPGME_SIG_STAT_NOKEY: + return g_strdup(_("You have no key to verify this signature")); + case GPGME_SIG_STAT_NOSIG: + return g_strdup(_("No signature found")); + case GPGME_SIG_STAT_ERROR: + return g_strdup(_("An error occured")); + case GPGME_SIG_STAT_NONE: + return g_strdup(_("The signature has not been checked")); + } + return g_strdup(_("Error")); +} + +gchar *sgpgme_sigstat_info_full(GpgmeCtx ctx, GpgmeSigStat status) +{ + gint i = 0; + gchar *ret; + GString *siginfo; + GpgmeKey key; + + siginfo = g_string_sized_new(64); + while (gpgme_get_sig_key(ctx, i, &key) != GPGME_EOF) { + time_t sigtime, expiretime; + GpgmeSigStat sigstatus; + gchar timestr[64]; + const gchar *keytype, *keyid, *uid; + + sigtime = gpgme_get_sig_ulong_attr(ctx, i, GPGME_ATTR_CREATED, 0); + strftime(timestr, 64, "%c", gmtime(&sigtime)); + keytype = gpgme_key_get_string_attr(key, GPGME_ATTR_ALGO, NULL, 0); + keyid = gpgme_key_get_string_attr(key, GPGME_ATTR_KEYID, NULL, 0); + g_string_sprintfa(siginfo, + _("Signature made %s using %s key ID %s\n"), + timestr, keytype, keyid); + + sigstatus = gpgme_get_sig_ulong_attr(ctx, i, GPGME_ATTR_SIG_STATUS, 0); + uid = gpgme_key_get_string_attr(key, GPGME_ATTR_USERID, NULL, 0); + switch (sigstatus) { + case GPGME_SIG_STAT_GOOD: + case GPGME_SIG_STAT_GOOD_EXPKEY: + g_string_sprintfa(siginfo, + _("Good signature from \"%s\"\n"), + uid); + break; + case GPGME_SIG_STAT_GOOD_EXP: + g_string_sprintfa(siginfo, + _("Expired signature from \"%s\"\n"), + uid); + break; + case GPGME_SIG_STAT_BAD: + g_string_sprintfa(siginfo, + _("BAD signature from \"%s\"\n"), + uid); + break; + default: + break; + } + if (sigstatus != GPGME_SIG_STAT_BAD) { + gint j = 1; + + while ((uid = gpgme_key_get_string_attr(key, GPGME_ATTR_USERID, NULL, j)) != 0) { + g_string_sprintfa(siginfo, + _(" aka \"%s\"\n"), + uid); + j++; + } + g_string_sprintfa(siginfo, + _("Primary key fingerprint: %s\n"), + gpgme_key_get_string_attr(key, GPGME_ATTR_FPR, NULL, 0)); + } + + + expiretime = gpgme_get_sig_ulong_attr(ctx, i, GPGME_ATTR_EXPIRE, 0); + if (expiretime > 0) { + const gchar *format; + + strftime(timestr, 64, "%c", gmtime(&expiretime)); + if (time(NULL) < expiretime) + format = _("Signature expires %s\n"); + else + format = _("Signature expired %s\n"); + g_string_sprintfa(siginfo, format, timestr); + } + + g_string_append(siginfo, "\n"); + i++; + } + + ret = siginfo->str; + g_string_free(siginfo, FALSE); + return ret; +} + +GpgmeData sgpgme_data_from_mimeinfo(MimeInfo *mimeinfo) +{ + GpgmeData data; + + gpgme_data_new_from_filepart(&data, + mimeinfo->filename, + NULL, + mimeinfo->offset, + mimeinfo->length); + + return data; +} + +GpgmeData sgpgme_decrypt(GpgmeData cipher) +{ + GpgmeCtx ctx; + struct passphrase_cb_info_s info; + GpgmeData plain; + GpgmeError err; + + memset (&info, 0, sizeof info); + + if (gpgme_new(&ctx) != GPGME_No_Error) + return NULL; + + if (gpgme_data_new(&plain) != GPGME_No_Error) { + gpgme_release(ctx); + return NULL; + } + + if (!getenv("GPG_AGENT_INFO")) { + info.c = ctx; + gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info); + } + + err = gpgme_op_decrypt(ctx, cipher, plain); + gpgme_release(ctx); + + if (err != GPGME_No_Error) { + gpgmegtk_free_passphrase(); + gpgme_data_release(plain); + return NULL; + } + + return plain; +} + +void sgpgme_init() +{ + if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) != + GPGME_No_Error) { /* Also does some gpgme init */ + sgpgme_disable_all(); + debug_print("gpgme_engine_version:\n%s\n", + gpgme_get_engine_info()); + + if (prefs_common.gpg_warning) { + AlertValue val; + + val = alertpanel_message_with_disable + (_("Warning"), + _("GnuPG is not installed properly, or needs " + "to be upgraded.\n" + "OpenPGP support disabled."), ALERT_WARNING); + if (val & G_ALERTDISABLE) + prefs_common.gpg_warning = FALSE; + } + } + + gpgme_register_idle(idle_function_for_gpgme); +} + +void sgpgme_done() +{ + gpgmegtk_free_passphrase(); +} + +#endif /* USE_GPGME */ diff --git a/src/plugins/pgpmime/sgpgme.h b/src/plugins/pgpmime/sgpgme.h new file mode 100644 index 000000000..ddcf1a84e --- /dev/null +++ b/src/plugins/pgpmime/sgpgme.h @@ -0,0 +1,43 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2003 Hiroyuki Yamamoto & the Sylpheed-Claws team + * + * 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 Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef SGPGME_H +#define SGPGME_H 1 + +#include + +#include "privacy.h" + +void sgpgme_init(void); +void sgpgme_done(void); + +GpgmeSigStat sgpgme_verify_signature (GpgmeCtx ctx, + GpgmeData sig, + GpgmeData plain); +SignatureStatus sgpgme_sigstat_gpgme_to_privacy + (GpgmeCtx ctx, + GpgmeSigStat status); +gchar *sgpgme_sigstat_info_short (GpgmeCtx ctx, + GpgmeSigStat status); +gchar *sgpgme_sigstat_info_full (GpgmeCtx ctx, + GpgmeSigStat status); +GpgmeData sgpgme_data_from_mimeinfo (MimeInfo *mimeinfo); +GpgmeData sgpgme_decrypt (GpgmeData cipher); + +#endif /* SGPGME_H */