gchar *get_part_as_string(MimeInfo *mimeinfo) { gchar *textdata = NULL; gchar *filename = NULL; FILE *fp; cm_return_val_if_fail(mimeinfo != NULL, 0); procmime_decode_content(mimeinfo); if (mimeinfo->content == MIMECONTENT_MEM) textdata = g_strdup(mimeinfo->data.mem); else { filename = procmime_get_tmp_file_name(mimeinfo); if (procmime_get_part(filename, mimeinfo) < 0) { g_warning("error dumping temporary file '%s'", filename); g_free(filename); return NULL; } fp = claws_fopen(filename,"rb"); if (!fp) { g_warning("error opening temporary file '%s'", filename); g_free(filename); return NULL; } textdata = fp_read_noconv(fp); claws_fclose(fp); g_unlink(filename); g_free(filename); } if (!g_utf8_validate(textdata, -1, NULL)) { gchar *tmp = NULL; codeconv_set_strict(TRUE); if (procmime_mimeinfo_get_parameter(mimeinfo, "charset")) { tmp = conv_codeset_strdup(textdata, procmime_mimeinfo_get_parameter(mimeinfo, "charset"), CS_UTF_8); } if (!tmp) { tmp = conv_codeset_strdup(textdata, conv_get_locale_charset_str_no_utf8(), CS_UTF_8); } codeconv_set_strict(FALSE); if (!tmp) { tmp = conv_codeset_strdup(textdata, conv_get_locale_charset_str_no_utf8(), CS_UTF_8); } if (tmp) { g_free(textdata); textdata = tmp; } } return textdata; }
static gboolean pgpinline_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data) { MimeInfo *msgcontent; FILE *fp; gchar *enccontent; size_t len; gchar *textstr, *tmp; gpgme_data_t gpgtext, gpgenc; gpgme_ctx_t ctx; gpgme_key_t *kset = NULL; gchar **fprs = g_strsplit(encrypt_data, " ", -1); gpgme_error_t err; gint i = 0; while (fprs[i] && strlen(fprs[i])) { i++; } kset = g_malloc(sizeof(gpgme_key_t)*(i+1)); memset(kset, 0, sizeof(gpgme_key_t)*(i+1)); if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) { debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); g_free(kset); return FALSE; } i = 0; while (fprs[i] && strlen(fprs[i])) { gpgme_key_t key; err = gpgme_get_key(ctx, fprs[i], &key, 0); if (err) { debug_print("can't add key '%s'[%d] (%s)\n", fprs[i],i, gpgme_strerror(err)); privacy_set_error(_("Couldn't add GPG key %s, %s"), fprs[i], gpgme_strerror(err)); g_free(kset); return FALSE; } debug_print("found %s at %d\n", fprs[i], i); kset[i] = key; i++; } debug_print("Encrypting message content\n"); /* get content node from message */ msgcontent = (MimeInfo *) mimeinfo->node->children->data; if (msgcontent->type == MIMETYPE_MULTIPART) { if (!msgcontent->node->children) { debug_print("msgcontent->node->children NULL, bailing\n"); privacy_set_error(_("Malformed message")); g_free(kset); return FALSE; } msgcontent = (MimeInfo *) msgcontent->node->children->data; } /* get rid of quoted-printable or anything */ procmime_decode_content(msgcontent); fp = my_tmpfile(); if (fp == NULL) { privacy_set_error(_("Couldn't create temporary file, %s"), g_strerror(errno)); perror("my_tmpfile"); g_free(kset); return FALSE; } procmime_write_mimeinfo(msgcontent, fp); rewind(fp); /* read temporary file into memory */ textstr = fp_read_noconv(fp); fclose(fp); /* encrypt data */ gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0); gpgme_data_new(&gpgenc); if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) { debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); g_free(kset); return FALSE; } gpgme_set_armor(ctx, 1); err = gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc); enccontent = sgpgme_data_release_and_get_mem(gpgenc, &len); g_free(kset); if (enccontent == NULL || len <= 0) { g_warning("sgpgme_data_release_and_get_mem failed"); privacy_set_error(_("Encryption failed, %s"), gpgme_strerror(err)); gpgme_data_release(gpgtext); g_free(textstr); gpgme_release(ctx); g_free(enccontent); return FALSE; } tmp = g_malloc(len+1); g_memmove(tmp, enccontent, len+1); tmp[len] = '\0'; g_free(enccontent); gpgme_data_release(gpgtext); g_free(textstr); if (msgcontent->content == MIMECONTENT_FILE && msgcontent->data.filename != NULL) { if (msgcontent->tmp == TRUE) claws_unlink(msgcontent->data.filename); g_free(msgcontent->data.filename); } msgcontent->data.mem = g_strdup(tmp); msgcontent->content = MIMECONTENT_MEM; g_free(tmp); gpgme_release(ctx); return TRUE; }
static gboolean pgpinline_sign(MimeInfo *mimeinfo, PrefsAccount *account, const gchar *from_addr) { MimeInfo *msgcontent; gchar *textstr, *tmp; FILE *fp; gchar *sigcontent; gpgme_ctx_t ctx; gpgme_data_t gpgtext, gpgsig; size_t len; gpgme_error_t err; struct passphrase_cb_info_s info; gpgme_sign_result_t result = NULL; memset (&info, 0, sizeof info); /* get content node from message */ msgcontent = (MimeInfo *) mimeinfo->node->children->data; if (msgcontent->type == MIMETYPE_MULTIPART) { if (!msgcontent->node->children) { debug_print("msgcontent->node->children NULL, bailing\n"); privacy_set_error(_("Malformed message")); return FALSE; } msgcontent = (MimeInfo *) msgcontent->node->children->data; } /* get rid of quoted-printable or anything */ procmime_decode_content(msgcontent); fp = my_tmpfile(); if (fp == NULL) { perror("my_tmpfile"); privacy_set_error(_("Couldn't create temporary file.")); return FALSE; } procmime_write_mimeinfo(msgcontent, fp); rewind(fp); /* read temporary file into memory */ textstr = fp_read_noconv(fp); fclose(fp); gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0); gpgme_data_new(&gpgsig); if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) { debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); return FALSE; } gpgme_set_textmode(ctx, 1); gpgme_set_armor(ctx, 1); if (!sgpgme_setup_signers(ctx, account, from_addr)) { gpgme_release(ctx); return FALSE; } prefs_gpg_enable_agent(prefs_gpg_get_config()->use_gpg_agent); if (!getenv("GPG_AGENT_INFO") || !prefs_gpg_get_config()->use_gpg_agent) { info.c = ctx; gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info); } err = gpgme_op_sign(ctx, gpgtext, gpgsig, GPGME_SIG_MODE_CLEAR); if (err != GPG_ERR_NO_ERROR) { if (err == GPG_ERR_CANCELED) { /* ignore cancelled signing */ privacy_reset_error(); debug_print("gpgme_op_sign cancelled\n"); } else { privacy_set_error(_("Data signing failed, %s"), gpgme_strerror(err)); debug_print("gpgme_op_sign error : %x\n", err); } gpgme_release(ctx); return FALSE; } result = gpgme_op_sign_result(ctx); if (result && result->signatures) { gpgme_new_signature_t sig = result->signatures; while (sig) { debug_print("valid signature: %s\n", sig->fpr); sig = sig->next; } } else if (result && result->invalid_signers) { gpgme_invalid_key_t invalid = result->invalid_signers; while (invalid) { g_warning("invalid signer: %s (%s)", invalid->fpr, gpgme_strerror(invalid->reason)); privacy_set_error(_("Data signing failed due to invalid signer: %s"), gpgme_strerror(invalid->reason)); invalid = invalid->next; } gpgme_release(ctx); return FALSE; } else { /* can't get result (maybe no signing key?) */ debug_print("gpgme_op_sign_result error\n"); privacy_set_error(_("Data signing failed, no results.")); gpgme_release(ctx); return FALSE; } sigcontent = sgpgme_data_release_and_get_mem(gpgsig, &len); if (sigcontent == NULL || len <= 0) { g_warning("sgpgme_data_release_and_get_mem failed"); privacy_set_error(_("Data signing failed, no contents.")); gpgme_data_release(gpgtext); g_free(textstr); g_free(sigcontent); gpgme_release(ctx); return FALSE; } tmp = g_malloc(len+1); g_memmove(tmp, sigcontent, len+1); tmp[len] = '\0'; gpgme_data_release(gpgtext); g_free(textstr); g_free(sigcontent); if (msgcontent->content == MIMECONTENT_FILE && msgcontent->data.filename != NULL) { if (msgcontent->tmp == TRUE) claws_unlink(msgcontent->data.filename); g_free(msgcontent->data.filename); } msgcontent->data.mem = g_strdup(tmp); msgcontent->content = MIMECONTENT_MEM; g_free(tmp); /* avoid all sorts of clear-signing problems with non ascii * chars */ procmime_encode_content(msgcontent, ENC_BASE64); gpgme_release(ctx); return TRUE; }