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;
- gpgme_data_new_from_filepart(&sigdata,
- signature->filename,
- NULL,
- signature->offset,
- signature->length);
+ sigdata = sgpgme_data_from_mimeinfo(signature);
data->sigstatus =
sgpgme_verify_signature (data->ctx, sigdata, textdata);
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;
+ }
+
+ 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 = {
"PGP/Mime", /* name */
pgpmime_get_sig_info_short, /* get_sig_info_short(MimeInfo *) */
pgpmime_get_sig_info_full, /* get_sig_info_full(MimeInfo *) */
- /* NOT YET */
pgpmime_is_encrypted, /* is_encrypted(MimeInfo *) */
- NULL, /* decrypt(MimeInfo *) */
+ pgpmime_decrypt, /* decrypt(MimeInfo *) */
};
void pgpmime_init()
NULL
};
-static void sig_expiration_check (GString *str,
- GpgmeCtx ctx,
- GpgmeKey key,
- GpgmeSigStat status,
- int idx);
-static void sig_expired (GString *str,
- GpgmeCtx ctx,
- int idx);
-static void sig_key_expired (GString *str,
- GpgmeKey key,
- int idx);
-
#if 0
static void dump_mimeinfo (const char *text, MimeInfo *x)
{
}
-/*
- * Copy a gpgme data object to a temporary file and
- * return this filename
- */
-#if 0
-static char *
-copy_gpgmedata_to_temp (GpgmeData data, guint *length)
-{
- static int id;
- char *tmp;
- FILE *fp;
- char buf[100];
- size_t nread;
- GpgmeError err;
-
- tmp = g_strdup_printf("%s%cgpgtmp.%08x",
- get_mime_tmp_dir(), G_DIR_SEPARATOR, ++id );
-
- if ((fp = fopen(tmp, "wb")) == NULL) {
- FILE_OP_ERROR(tmp, "fopen");
- g_free(tmp);
- return NULL;
- }
-
- err = gpgme_data_rewind ( data );
- if (err)
- debug_print ("gpgme_data_rewind failed: %s\n", gpgme_strerror (err));
-
- while (!(err = gpgme_data_read (data, buf, 100, &nread))) {
- fwrite ( buf, nread, 1, fp );
- }
-
- if (err != GPGME_EOF)
- debug_print ("gpgme_data_read failed: %s\n", gpgme_strerror (err));
-
- fclose (fp);
- *length = nread;
-
- return tmp;
-}
-#endif
-
-static GpgmeData
-pgp_decrypt (MimeInfo *partinfo, FILE *fp)
-{
- GpgmeCtx ctx = NULL;
- GpgmeError err;
- GpgmeData cipher = NULL, plain = NULL;
- struct passphrase_cb_info_s info;
-
- memset (&info, 0, sizeof info);
-
- err = gpgme_new (&ctx);
- if (err) {
- debug_print ("gpgme_new failed: %s\n", gpgme_strerror (err));
- goto leave;
- }
-
- err = gpgme_data_new_from_filepart (&cipher, NULL, fp,
- partinfo->offset, partinfo->length);
- if (err) {
- debug_print ("gpgme_data_new_from_filepart failed: %s\n",
- gpgme_strerror (err));
- goto leave;
- }
-
- err = gpgme_data_new (&plain);
- if (err) {
- debug_print ("gpgme_new failed: %s\n", gpgme_strerror (err));
- goto leave;
- }
-
- if (!getenv("GPG_AGENT_INFO")) {
- info.c = ctx;
- gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info);
- }
-
- err = gpgme_op_decrypt (ctx, cipher, plain);
-
-leave:
- gpgme_data_release (cipher);
- if (err) {
- gpgmegtk_free_passphrase();
- debug_print ("decryption failed: %s\n", gpgme_strerror (err));
- gpgme_data_release (plain);
- plain = NULL;
- }
- else
- debug_print ("** decryption succeeded\n");
-
- gpgme_release (ctx);
- return plain;
-}
-
-int rfc2015_is_encrypted (MimeInfo *mimeinfo)
-{
- if (!mimeinfo || mimeinfo->type != MIMETYPE_MULTIPART)
- return 0;
- if (g_strcasecmp (mimeinfo->subtype, "encrypted"))
- return 0;
- /* fixme: we should check the protocol parameter */
- return 1;
-}
-
-gboolean rfc2015_msg_is_encrypted (const gchar *file)
-{
- FILE *fp;
- MimeInfo *mimeinfo;
- int ret = 0;
-
-#if 0 /* FIXME */
- if ((fp = fopen(file, "rb")) == NULL)
- return FALSE;
-
- mimeinfo = procmime_scan_mime_header(fp);
- if(!mimeinfo) {
- fclose(fp);
- return FALSE;
- }
- ret = rfc2015_is_encrypted(mimeinfo);
- procmime_mimeinfo_free_all(mimeinfo);
-#endif
- return ret != 0 ? TRUE : FALSE;
-}
static int
name_cmp(const char *a, const char *b)
return names[i] != NULL;
}
-
-#define DECRYPTION_ABORT() \
-{ \
- procmime_mimeinfo_free_all(tmpinfo); \
- msginfo->decryption_failed = 1; \
- return; \
-}
-
-void rfc2015_decrypt_message (MsgInfo *msginfo, MimeInfo *mimeinfo, FILE *fp)
-{
- static int id;
- MimeInfo *tmpinfo, *partinfo;
- int ver_ok = 0;
- char *fname;
- GpgmeData plain;
- FILE *dstfp;
- size_t nread;
- char buf[BUFFSIZE];
- int in_cline;
- GpgmeError err;
-
- g_return_if_fail (msginfo != NULL);
- g_return_if_fail (mimeinfo != NULL);
- g_return_if_fail (fp != NULL);
- g_return_if_fail (mimeinfo->type == MIMETYPE_MULTIPART);
-
- debug_print ("** decrypting multipart/encrypted message\n");
-
-#if 0 /* FIXME */
-
- /* skip headers */
- if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0)
- perror("fseek");
- tmpinfo = procmime_scan_mime_header(fp);
- if (!tmpinfo || tmpinfo->type != MIMETYPE_MULTIPART) {
- DECRYPTION_ABORT();
- }
-
- procmime_scan_message(tmpinfo);
-
- /* check that we have the 2 parts */
- partinfo = tmpinfo->children;
- if (!partinfo || !partinfo->next) {
- DECRYPTION_ABORT();
- }
- if ((partinfo->type == MIMETYPE_APPLICATION) && !g_strcasecmp(partinfo->subtype, "pgp-encrypted")) {
- /* Fixme: check that the version is 1 */
- ver_ok = 1;
- }
- partinfo = partinfo->next;
- if (ver_ok && (partinfo->type == MIMETYPE_APPLICATION) &&
- !g_strcasecmp (partinfo->subtype, "octet-stream")) {
- if (partinfo->next)
- g_warning ("oops: pgp_encrypted with more than 2 parts");
- }
- else {
- DECRYPTION_ABORT();
- }
-
- debug_print ("** yep, it is pgp encrypted\n");
-
- plain = pgp_decrypt (partinfo, fp);
- if (!plain) {
- DECRYPTION_ABORT();
- }
-
- 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);
- DECRYPTION_ABORT();
- }
-
- /* write the orginal header to the new file */
- if (fseek(fp, tmpinfo->offset, SEEK_SET) < 0)
- perror("fseek");
-
- in_cline = 0;
- while (fgets(buf, sizeof(buf), fp)) {
- if (headerp (buf, content_names)) {
- in_cline = 1;
- continue;
- }
- if (in_cline) {
- if (buf[0] == ' ' || buf[0] == '\t')
- continue;
- in_cline = 0;
- }
- if (buf[0] == '\r' || buf[0] == '\n')
- break;
- fputs (buf, dstfp);
- }
-
- err = gpgme_data_rewind (plain);
- if (err)
- debug_print ("gpgme_data_rewind failed: %s\n", gpgme_strerror (err));
-
- while (!(err = gpgme_data_read (plain, buf, sizeof(buf), &nread))) {
- fwrite (buf, nread, 1, dstfp);
- }
-
- if (err != GPGME_EOF) {
- debug_print ("gpgme_data_read failed: %s\n", gpgme_strerror (err));
- }
-
- fclose (dstfp);
- procmime_mimeinfo_free_all(tmpinfo);
-
- msginfo->plaintext_file = fname;
- msginfo->decryption_failed = 0;
-
-#endif
-}
-
-#undef DECRYPTION_ABORT
-
-
/*
* plain contains an entire mime object.
* Encrypt it and return an GpgmeData object with the encrypted version of