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; }
gint privacy_mimeinfo_decrypt(MimeInfo *mimeinfo) { GSList *cur; cm_return_val_if_fail(mimeinfo != NULL, FALSE); procmime_decode_content(mimeinfo); for(cur = systems; cur != NULL; cur = g_slist_next(cur)) { PrivacySystem *system = (PrivacySystem *) cur->data; if(system->is_encrypted != NULL && system->is_encrypted(mimeinfo)) return decrypt(mimeinfo, system); } return -1; }
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; }
static gboolean tnef_parse (MimeParser *parser, MimeInfo *mimeinfo) { TNEFStruct *tnef; MimeInfo *sub_info = NULL; variableLength *tmp_var; Attachment *att; int parse_result = 0; gboolean cal_done = FALSE; if (!procmime_decode_content(mimeinfo)) { debug_print("error decoding\n"); return FALSE; } debug_print("Tnef parser parsing part (%d).\n", mimeinfo->length); if (mimeinfo->content == MIMECONTENT_FILE) debug_print("content: %s\n", mimeinfo->data.filename); else debug_print("contents in memory (len %zd)\n", strlen(mimeinfo->data.mem)); tnef = g_new0(TNEFStruct, 1); TNEFInitialize(tnef); tnef->Debug = debug_get_mode(); if (mimeinfo->content == MIMECONTENT_MEM) parse_result = TNEFParseMemory(mimeinfo->data.mem, mimeinfo->length, tnef); else parse_result = TNEFParseFile(mimeinfo->data.filename, tnef); mimeinfo->type = MIMETYPE_MULTIPART; mimeinfo->subtype = g_strdup("mixed"); g_hash_table_insert(mimeinfo->typeparameters, g_strdup("description"), g_strdup("Parsed from MS-TNEF")); if (parse_result != 0) { g_warning("Failed to parse TNEF data."); TNEFFree(tnef); return FALSE; } sub_info = NULL; if (tnef->messageClass[0] != '\0') { if (strcmp(tnef->messageClass, "IPM.Contact") == 0) sub_info = tnef_parse_vcard(tnef); else if (strcmp(tnef->messageClass, "IPM.Task") == 0) sub_info = tnef_parse_vtask(tnef); else if (strcmp(tnef->messageClass, "IPM.Appointment") == 0) { sub_info = tnef_parse_vcal(tnef); cal_done = TRUE; } } if (sub_info) g_node_append(mimeinfo->node, sub_info->node); sub_info = NULL; if (tnef->MapiProperties.count > 0) { tmp_var = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG(PT_BINARY,PR_RTF_COMPRESSED)); if (tmp_var != MAPI_UNDEFINED) { sub_info = tnef_parse_rtf(tnef, tmp_var); } } if (sub_info) g_node_append(mimeinfo->node, sub_info->node); sub_info = NULL; tmp_var = MAPIFindUserProp(&(tnef->MapiProperties), PROP_TAG(PT_STRING8,0x24)); if (tmp_var != MAPI_UNDEFINED) { if (!cal_done && strcmp(tmp_var->data, "IPM.Appointment") == 0) { sub_info = tnef_parse_vcal(tnef); } } if (sub_info) g_node_append(mimeinfo->node, sub_info->node); sub_info = NULL; att = tnef->starting_attach.next; while (att) { gchar *filename = NULL; gboolean is_object = TRUE; DWORD signature; tmp_var = MAPIFindProperty(&(att->MAPI), PROP_TAG(30,0x3707)); if (tmp_var == MAPI_UNDEFINED) tmp_var = MAPIFindProperty(&(att->MAPI), PROP_TAG(30,0x3001)); if (tmp_var == MAPI_UNDEFINED) tmp_var = &(att->Title); if (tmp_var->data) filename = g_strdup(tmp_var->data); tmp_var = MAPIFindProperty(&(att->MAPI), PROP_TAG(PT_OBJECT, PR_ATTACH_DATA_OBJ)); if (tmp_var == MAPI_UNDEFINED) tmp_var = MAPIFindProperty(&(att->MAPI), PROP_TAG(PT_BINARY, PR_ATTACH_DATA_OBJ)); if (tmp_var == MAPI_UNDEFINED) { tmp_var = &(att->FileData); is_object = FALSE; } sub_info = tnef_dump_file(filename, tmp_var->data + (is_object ? 16:0), tmp_var->size - (is_object ? 16:0)); if (sub_info) g_node_append(mimeinfo->node, sub_info->node); memcpy(&signature, tmp_var->data+(is_object ? 16:0), sizeof(DWORD)); if (TNEFCheckForSignature(signature) == 0) { debug_print("that's TNEF stuff, process it\n"); tnef_parse(parser, sub_info); } sub_info = NULL; att = att->next; g_free(filename); } TNEFFree(tnef); return TRUE; }