Пример #1
0
static MimeInfo *tnef_dump_file(const gchar *filename, char *data, size_t size)
{
	MimeInfo *sub_info = NULL;
	gchar *tmpfilename = NULL;
	FILE *fp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmpfilename);
	GStatBuf statbuf;
	gchar *content_type = NULL;
	if (!fp) {
		g_free(tmpfilename);
		return NULL;
	}
	sub_info = procmime_mimeinfo_new();
	sub_info->content = MIMECONTENT_FILE;
	sub_info->data.filename = tmpfilename;
	sub_info->type = MIMETYPE_APPLICATION;
	sub_info->subtype = g_strdup("octet-stream");
	
	if (filename) {
		g_hash_table_insert(sub_info->typeparameters,
				    g_strdup("filename"),
				    g_strdup(filename));
	
		content_type = procmime_get_mime_type(filename);
		if (content_type && strchr(content_type, '/')) {
			g_free(sub_info->subtype);
			sub_info->subtype = g_strdup(strchr(content_type, '/')+1);
			*(strchr(content_type, '/')) = '\0';
			sub_info->type = procmime_get_media_type(content_type);
			g_free(content_type);
		}
	} 

	if (claws_fwrite(data, 1, size, fp) < size) {
		FILE_OP_ERROR(tmpfilename, "claws_fwrite");
		claws_fclose(fp);
		claws_unlink(tmpfilename);
		procmime_mimeinfo_free_all(&sub_info);
		return tnef_broken_mimeinfo(_("Failed to write the part data."));
	}
	claws_fclose(fp);

	if (g_stat(tmpfilename, &statbuf) < 0) {
		claws_unlink(tmpfilename);
		procmime_mimeinfo_free_all(&sub_info);
		return tnef_broken_mimeinfo(_("Failed to write the part data."));
	} else {
		sub_info->tmp = TRUE;
		sub_info->length = statbuf.st_size;
		sub_info->encoding_type = ENC_BINARY;
	}

	return sub_info;
}
Пример #2
0
MimeInfo *tnef_parse_vcard(TNEFStruct tnef)
{
	MimeInfo *sub_info = NULL;
	gchar *tmpfilename = NULL;
	FILE *fp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmpfilename);
	struct stat statbuf;
	gboolean result = FALSE;
	if (!fp) {
		g_free(tmpfilename);
		return NULL;
	}
	sub_info = procmime_mimeinfo_new();
	sub_info->content = MIMECONTENT_FILE;
	sub_info->data.filename = tmpfilename;
	sub_info->type = MIMETYPE_TEXT;
	sub_info->subtype = g_strdup("x-vcard");
	g_hash_table_insert(sub_info->typeparameters,
			    g_strdup("filename"),
			    g_strdup("contact.vcf"));
	
	result = SaveVCard(fp, tnef);
	
	fclose(fp);
	g_stat(tmpfilename, &statbuf);
	sub_info->tmp = TRUE;
	sub_info->length = statbuf.st_size;
	sub_info->encoding_type = ENC_BINARY;
	
	if (!result) {
		claws_unlink(tmpfilename);
		procmime_mimeinfo_free_all(sub_info);
		return tnef_broken_mimeinfo(_("Failed to parse VCard data."));
	}
	return sub_info;
}
Пример #3
0
static gboolean mail_filtering_hook(gpointer source, gpointer data)
{
    MailFilteringData *mail_filtering_data = (MailFilteringData *) source;
    MsgInfo *msginfo = mail_filtering_data->msginfo;
    MimeInfo *mimeinfo;

    struct clamd_result result;

    if (!config.clamav_enable)
        return FALSE;

    mimeinfo = procmime_scan_message(msginfo);
    if (!mimeinfo) return FALSE;

    debug_print("Scanning message %d for viruses\n", msginfo->msgnum);
    if (message_callback != NULL)
        message_callback(_("ClamAV: scanning message..."));

    g_node_traverse(mimeinfo->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, scan_func, &result);
    debug_print("status: %d\n", result.status);

    if (result.status == VIRUS) {
        if (config.clamav_recv_infected) {
            FolderItem *clamav_save_folder;

            if ((!config.clamav_save_folder) ||
                    (config.clamav_save_folder[0] == '\0') ||
                    ((clamav_save_folder = folder_find_item_from_identifier(config.clamav_save_folder)) == NULL))
                clamav_save_folder = folder_get_default_trash();

            procmsg_msginfo_unset_flags(msginfo, ~0, 0);
            msginfo->filter_op = IS_MOVE;
            msginfo->to_filter_folder = clamav_save_folder;
        } else {
            folder_item_remove_msg(msginfo->folder, msginfo->msgnum);
        }
    }

    procmime_mimeinfo_free_all(mimeinfo);

    return (result.status == OK) ? FALSE : TRUE;
}
Пример #4
0
void mimeview_destroy(MimeView *mimeview)
{
	GSList *cur;
	
	for (cur = mimeview->viewers; cur != NULL; cur = g_slist_next(cur)) {
		MimeViewer *viewer = (MimeViewer *) cur->data;
		gtk_container_remove(GTK_CONTAINER(mimeview->mime_notebook),
			GTK_WIDGET(viewer->get_widget(viewer)));
		viewer->destroy_viewer(viewer);
	}
	g_slist_free(mimeview->viewers);
	gtk_target_list_unref(mimeview->target_list);

	procmime_mimeinfo_free_all(mimeview->mimeinfo);
	g_free(mimeview->file);
	g_free(mimeview);

	mimeviews = g_slist_remove(mimeviews, mimeview);
	
}
Пример #5
0
static gint decrypt(MimeInfo *mimeinfo, PrivacySystem *system)
{
	MimeInfo *decryptedinfo, *parentinfo;
	gint childnumber;
	
	cm_return_val_if_fail(system->decrypt != NULL, -1);
	
	decryptedinfo = system->decrypt(mimeinfo);
	if (decryptedinfo == NULL)
		return -1;

	parentinfo = procmime_mimeinfo_parent(mimeinfo);
	childnumber = g_node_child_index(parentinfo->node, mimeinfo);
	
	procmime_mimeinfo_free_all(&mimeinfo);

	g_node_insert(parentinfo->node, childnumber, decryptedinfo->node);

	return 0;
}
Пример #6
0
void mimeview_clear(MimeView *mimeview)
{
	GtkCList *clist = GTK_CLIST(mimeview->ctree);

	noticeview_hide(mimeview->siginfoview);

	gtk_clist_clear(clist);
	textview_clear(mimeview->textview);
	if (mimeview->mimeviewer != NULL)
		mimeview->mimeviewer->clear_viewer(mimeview->mimeviewer);

	if (mimeview->mimeinfo != NULL)
		procmime_mimeinfo_free_all(mimeview->mimeinfo);
	mimeview->mimeinfo = NULL;

	mimeview->opened = NULL;

	g_free(mimeview->file);
	mimeview->file = NULL;

	icon_list_clear(mimeview);
}
Пример #7
0
MimeInfo *tnef_parse_vtask(TNEFStruct *tnef)
{
	MimeInfo *sub_info = NULL;
	gchar *tmpfilename = NULL;
	FILE *fp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmpfilename);
	GStatBuf statbuf;
	gboolean result = FALSE;
	if (!fp) {
		g_free(tmpfilename);
		return NULL;
	}
	sub_info = procmime_mimeinfo_new();
	sub_info->content = MIMECONTENT_FILE;
	sub_info->data.filename = tmpfilename;
	sub_info->type = MIMETYPE_TEXT;
	sub_info->subtype = g_strdup("calendar");
	g_hash_table_insert(sub_info->typeparameters,
			    g_strdup("filename"),
			    g_strdup("task.ics"));

	result = SaveVTask(fp, tnef);

	claws_fclose(fp);

	if (g_stat(tmpfilename, &statbuf) < 0) {
		result = FALSE;
	} else {
		sub_info->tmp = TRUE;
		sub_info->length = statbuf.st_size;
		sub_info->encoding_type = ENC_BINARY;
	}
	if (!result) {
		claws_unlink(tmpfilename);
		procmime_mimeinfo_free_all(&sub_info);
		return tnef_broken_mimeinfo(_("Failed to parse VTask data."));
	}
	return sub_info;
}
Пример #8
0
static MimeInfo *tnef_broken_mimeinfo(const gchar *reason)
{
	MimeInfo *sub_info = NULL;
	gchar *tmpfilename = NULL;
	FILE *fp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmpfilename);
	GStatBuf statbuf;

	if (!fp) {
		g_free(tmpfilename);
		return NULL;
	}
	sub_info = procmime_mimeinfo_new();
	sub_info->content = MIMECONTENT_FILE;
	sub_info->data.filename = tmpfilename;
	sub_info->type = MIMETYPE_TEXT;
	sub_info->subtype = g_strdup("plain");

	fprintf(fp, _("\n"
			"Claws Mail TNEF parser:\n\n"
			"%s\n"), reason?reason:_("Unknown error"));

	claws_fclose(fp);
	if (g_stat(tmpfilename, &statbuf) < 0) {
		claws_unlink(tmpfilename);
		procmime_mimeinfo_free_all(&sub_info);
		return NULL;

	}

	sub_info->tmp = TRUE;
	sub_info->length = statbuf.st_size;
	sub_info->encoding_type = ENC_BINARY;

	return sub_info;

}
Пример #9
0
gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
		      gboolean all_headers)
{
	gchar *file;
	MimeInfo *mimeinfo;

	g_return_val_if_fail(msginfo != NULL, -1);

	mimeinfo = procmime_scan_message(msginfo);
	if (!mimeinfo) {
		messageview_change_view_type(messageview, MVIEW_TEXT);
		textview_show_error(messageview->textview);
		return -1;
	}

	file = procmsg_get_message_file_path(msginfo);
	if (!file) {
		g_warning("can't get message file path.\n");
		procmime_mimeinfo_free_all(mimeinfo);
		messageview_change_view_type(messageview, MVIEW_TEXT);
		textview_show_error(messageview->textview);
		return -1;
	}

	if (messageview->msginfo != msginfo) {
		procmsg_msginfo_free(messageview->msginfo);
		messageview->msginfo = procmsg_msginfo_get_full_info(msginfo);
		if (!messageview->msginfo)
			messageview->msginfo = procmsg_msginfo_copy(msginfo);
	}

	if (messageview->window && msginfo->subject) {
		gchar *title;

		title = g_strconcat(msginfo->subject, " - Sylpheed", NULL);
		gtk_window_set_title(GTK_WINDOW(messageview->window), title);
		g_free(title);
	}
	headerview_show(messageview->headerview, messageview->msginfo);

	textview_set_all_headers(messageview->textview, all_headers);
	textview_set_all_headers(messageview->mimeview->textview, all_headers);

	if (mimeinfo->mime_type != MIME_TEXT &&
	    (prefs_common.html_only_as_attach ||
	     mimeinfo->mime_type != MIME_TEXT_HTML)) {
		messageview_change_view_type(messageview, MVIEW_MIME);
		mimeview_show_message(messageview->mimeview, mimeinfo, file);
	} else {
		messageview_change_view_type(messageview, MVIEW_TEXT);
		textview_show_message(messageview->textview, mimeinfo, file);
		procmime_mimeinfo_free_all(mimeinfo);
	}

	if (messageview->new_window)
		messageview_set_menu_state(messageview);

	g_free(file);

	return 0;
}
Пример #10
0
static MimeInfo *pgpinline_decrypt(MimeInfo *mimeinfo)
{
    MimeInfo *decinfo, *parseinfo;
    gpgme_data_t cipher, plain;
    FILE *dstfp;
    gchar *fname;
    gchar *textdata = NULL;
    static gint id = 0;
    const gchar *src_codeset = NULL;
    gpgme_verify_result_t sigstat = 0;
    PrivacyDataPGP *data = NULL;
    gpgme_ctx_t ctx;
    gchar *chars;
    size_t len;
    const gchar *begin_indicator = "-----BEGIN PGP MESSAGE-----";
    const gchar *end_indicator = "-----END PGP MESSAGE-----";
    gchar *pos;

    if (gpgme_new(&ctx) != GPG_ERR_NO_ERROR)
        return NULL;

    gpgme_set_textmode(ctx, 1);
    gpgme_set_armor(ctx, 1);

    cm_return_val_if_fail(mimeinfo != NULL, NULL);
    cm_return_val_if_fail(pgpinline_is_encrypted(mimeinfo), NULL);

    if (procmime_mimeinfo_parent(mimeinfo) == NULL ||
            mimeinfo->type != MIMETYPE_TEXT) {
        gpgme_release(ctx);
        privacy_set_error(_("Couldn't parse mime part."));
        return NULL;
    }

    textdata = get_part_as_string(mimeinfo);
    if (!textdata) {
        gpgme_release(ctx);
        privacy_set_error(_("Couldn't get text data."));
        return NULL;
    }

    debug_print("decrypting '%s'\n", textdata);
    gpgme_data_new_from_mem(&cipher, textdata, (size_t)strlen(textdata), 1);

    plain = sgpgme_decrypt_verify(cipher, &sigstat, ctx);
    if (sigstat && !sigstat->signatures)
        sigstat = NULL;

    gpgme_data_release(cipher);

    if (plain == NULL) {
        gpgme_release(ctx);
        return NULL;
    }

    fname = g_strdup_printf("%s%cplaintext.%08x",
                            get_mime_tmp_dir(), G_DIR_SEPARATOR, ++id);

    if ((dstfp = g_fopen(fname, "wb")) == NULL) {
        FILE_OP_ERROR(fname, "fopen");
        privacy_set_error(_("Couldn't open decrypted file %s"), fname);
        g_free(fname);
        gpgme_data_release(plain);
        gpgme_release(ctx);
        return NULL;
    }

    src_codeset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
    if (src_codeset == NULL)
        src_codeset = CS_ISO_8859_1;

    if (fprintf(dstfp, "MIME-Version: 1.0\r\n"
                "Content-Type: text/plain; charset=%s\r\n"
                "Content-Transfer-Encoding: 8bit\r\n"
                "\r\n",
                src_codeset) < 0) {
        FILE_OP_ERROR(fname, "fprintf");
        privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
        goto FILE_ERROR;
    }

    /* Store any part before encrypted text */
    pos = pgp_locate_armor_header(textdata, begin_indicator);
    if (pos != NULL && (pos - textdata) > 0) {
        if (fwrite(textdata, 1, pos - textdata, dstfp) < pos - textdata) {
            FILE_OP_ERROR(fname, "fwrite");
            privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
            goto FILE_ERROR;
        }
    }

    if (fwrite(_("\n--- Start of PGP/Inline encrypted data ---\n"), 1,
               strlen(_("\n--- Start of PGP/Inline encrypted data ---\n")),
               dstfp) < strlen(_("\n--- Start of PGP/Inline encrypted data ---\n"))) {
        FILE_OP_ERROR(fname, "fwrite");
        privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
        goto FILE_ERROR;
    }
    chars = sgpgme_data_release_and_get_mem(plain, &len);
    if (len > 0) {
        if (fwrite(chars, 1, len, dstfp) < len) {
            FILE_OP_ERROR(fname, "fwrite");
            g_free(chars);
            privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
            goto FILE_ERROR;
        }
    }
    g_free(chars);
    /* Store any part after encrypted text */
    if (fwrite(_("--- End of PGP/Inline encrypted data ---\n"), 1,
               strlen(_("--- End of PGP/Inline encrypted data ---\n")),
               dstfp) < strlen(_("--- End of PGP/Inline encrypted data ---\n"))) {
        FILE_OP_ERROR(fname, "fwrite");
        privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
        goto FILE_ERROR;
    }
    if (pos != NULL) {
        pos = pgp_locate_armor_header(pos, end_indicator);
        if (pos != NULL && *pos != '\0') {
            pos += strlen(end_indicator);
            if (fwrite(pos, 1, strlen(pos), dstfp) < strlen(pos)) {
                FILE_OP_ERROR(fname, "fwrite");
                privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
                goto FILE_ERROR;
            }
        }
    }

    if (fclose(dstfp) == EOF) {
        FILE_OP_ERROR(fname, "fclose");
        privacy_set_error(_("Couldn't close decrypted file %s"), fname);
        g_free(fname);
        gpgme_data_release(plain);
        gpgme_release(ctx);
        return NULL;
    }

    parseinfo = procmime_scan_file(fname);
    g_free(fname);

    if (parseinfo == NULL) {
        gpgme_release(ctx);
        privacy_set_error(_("Couldn't scan decrypted file."));
        return NULL;
    }
    decinfo = g_node_first_child(parseinfo->node) != NULL ?
              g_node_first_child(parseinfo->node)->data : NULL;

    if (decinfo == NULL) {
        gpgme_release(ctx);
        privacy_set_error(_("Couldn't scan decrypted file parts."));
        return NULL;
    }

    g_node_unlink(decinfo->node);
    procmime_mimeinfo_free_all(parseinfo);

    decinfo->tmp = TRUE;

    if (sigstat != GPGME_SIG_STAT_NONE) {
        if (decinfo->privacy != NULL) {
            data = (PrivacyDataPGP *) decinfo->privacy;
        } else {
            data = pgpinline_new_privacydata();
            decinfo->privacy = (PrivacyData *) data;
        }
        if (data != NULL) {
            data->done_sigtest = TRUE;
            data->is_signed = TRUE;
            data->sigstatus = sigstat;
            if (data->ctx)
                gpgme_release(data->ctx);
            data->ctx = ctx;
        }
    } else
        gpgme_release(ctx);

    return decinfo;

FILE_ERROR:
    fclose(dstfp);
    g_free(fname);
    gpgme_data_release(plain);
    gpgme_release(ctx);
    return NULL;
}
Пример #11
0
gint procmsg_send_message_queue(const gchar *file)
{
	static HeaderEntry qentry[] = {{"S:",    NULL, FALSE},
				       {"SSV:",  NULL, FALSE},
				       {"R:",    NULL, FALSE},
				       {"NG:",   NULL, FALSE},
				       {"MAID:", NULL, FALSE},
				       {"NAID:", NULL, FALSE},
				       {"SCF:",  NULL, FALSE},
				       {"RMID:", NULL, FALSE},
				       {"FMID:", NULL, FALSE},
				       {"X-Sylpheed-Privacy-System:", NULL, FALSE},
				       {"X-Sylpheed-Encrypt:", NULL, FALSE},
				       {"X-Sylpheed-Encrypt-Data:", NULL, FALSE},
				       {NULL,    NULL, FALSE}};
	FILE *fp;
	gint filepos;
	gint mailval = 0, newsval = 0;
	gchar *from = NULL;
	gchar *smtpserver = NULL;
	GSList *to_list = NULL;
	GSList *newsgroup_list = NULL;
	gchar *savecopyfolder = NULL;
	gchar *replymessageid = NULL;
	gchar *fwdmessageid = NULL;
	gchar *privacy_system = NULL;
	gboolean encrypt = FALSE;
	gchar *encrypt_data = NULL;
	gchar buf[BUFFSIZE];
	gint hnum;
	PrefsAccount *mailac = NULL, *newsac = NULL;
	gboolean save_clear_text = TRUE;
	gchar *tmp_enc_file = NULL;

	int local = 0;

	g_return_val_if_fail(file != NULL, -1);

	if ((fp = fopen(file, "rb")) == NULL) {
		FILE_OP_ERROR(file, "fopen");
		return -1;
	}

	while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, qentry))
	       != -1) {
		gchar *p = buf + strlen(qentry[hnum].name);

		switch (hnum) {
		case Q_SENDER:
			if (from == NULL) 
				from = g_strdup(p);
			break;
		case Q_SMTPSERVER:
			if (smtpserver == NULL) 
				smtpserver = g_strdup(p);
			break;
		case Q_RECIPIENTS:
			to_list = address_list_append(to_list, p);
			break;
		case Q_NEWSGROUPS:
			newsgroup_list = newsgroup_list_append(newsgroup_list, p);
			break;
		case Q_MAIL_ACCOUNT_ID:
			mailac = account_find_from_id(atoi(p));
			break;
		case Q_NEWS_ACCOUNT_ID:
			newsac = account_find_from_id(atoi(p));
			break;
		case Q_SAVE_COPY_FOLDER:
			if (savecopyfolder == NULL) 
				savecopyfolder = g_strdup(p);
			break;
		case Q_REPLY_MESSAGE_ID:
			if (replymessageid == NULL) 
				replymessageid = g_strdup(p);
			break;
		case Q_FWD_MESSAGE_ID:
			if (fwdmessageid == NULL) 
				fwdmessageid = g_strdup(p);
			break;
		case Q_PRIVACY_SYSTEM:
			if (privacy_system == NULL) 
				privacy_system = g_strdup(p);
			break;
		case Q_ENCRYPT:
			if (p[0] == '1') 
				encrypt = TRUE;
			break;
		case Q_ENCRYPT_DATA:
			if (encrypt_data == NULL) 
				encrypt_data = g_strdup(p);
			break;
		}
	}
	filepos = ftell(fp);

	if (encrypt) {
		MimeInfo *mimeinfo;

		save_clear_text = (mailac != NULL && mailac->save_encrypted_as_clear_text);

		fclose(fp);
		fp = NULL;

		mimeinfo = procmime_scan_queue_file(file);
		if (!privacy_encrypt(privacy_system, mimeinfo, encrypt_data)
		|| (fp = my_tmpfile()) == NULL
		||  procmime_write_mimeinfo(mimeinfo, fp) < 0) {
			if (fp)
				fclose(fp);
			procmime_mimeinfo_free_all(mimeinfo);
			g_free(from);
			g_free(smtpserver);
			slist_free_strings(to_list);
			g_slist_free(to_list);
			slist_free_strings(newsgroup_list);
			g_slist_free(newsgroup_list);
			g_free(savecopyfolder);
			g_free(replymessageid);
			g_free(fwdmessageid);
			g_free(privacy_system);
			g_free(encrypt_data);
			return -1;
		}
		
		rewind(fp);
		if (!save_clear_text) {
			gchar *content = NULL;
			FILE *tmpfp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmp_enc_file);
			if (tmpfp) {
				fclose(tmpfp);

				content = file_read_stream_to_str(fp);
				rewind(fp);

				str_write_to_file(content, tmp_enc_file);
				g_free(content);
			} else {
				g_warning("couldn't get tempfile\n");
			}
		} 
		
		procmime_mimeinfo_free_all(mimeinfo);
		
		filepos = 0;
    	}

	if (to_list) {
		debug_print("Sending message by mail\n");
		if (!from) {
			g_warning("Queued message header is broken.\n");
			mailval = -1;
		} else if (mailac && mailac->use_mail_command &&
			   mailac->mail_command && (* mailac->mail_command)) {
			mailval = send_message_local(mailac->mail_command, fp);
			local = 1;
		} else {
			if (!mailac) {
				mailac = account_find_from_smtp_server(from, smtpserver);
				if (!mailac) {
					g_warning("Account not found. "
						    "Using current account...\n");
					mailac = cur_account;
				}
			}

			if (mailac)
				mailval = send_message_smtp(mailac, to_list, fp);
			else {
				PrefsAccount tmp_ac;

				g_warning("Account not found.\n");

				memset(&tmp_ac, 0, sizeof(PrefsAccount));
				tmp_ac.address = from;
				tmp_ac.smtp_server = smtpserver;
				tmp_ac.smtpport = SMTP_PORT;
				mailval = send_message_smtp(&tmp_ac, to_list, fp);
			}
		}
	}

	fseek(fp, filepos, SEEK_SET);
	if (newsgroup_list && (mailval == 0)) {
		Folder *folder;
		gchar *tmp = NULL;
		FILE *tmpfp;

    		/* write to temporary file */
    		tmp = g_strdup_printf("%s%ctmp%d", g_get_tmp_dir(),
                    	    G_DIR_SEPARATOR, (gint)file);
    		if ((tmpfp = fopen(tmp, "wb")) == NULL) {
            		FILE_OP_ERROR(tmp, "fopen");
            		newsval = -1;
			alertpanel_error(_("Could not create temporary file for news sending."));
    		} else {
    			if (change_file_mode_rw(tmpfp, tmp) < 0) {
            			FILE_OP_ERROR(tmp, "chmod");
            			g_warning("can't change file mode\n");
    			}

			while ((newsval == 0) && fgets(buf, sizeof(buf), fp) != NULL) {
				if (fputs(buf, tmpfp) == EOF) {
					FILE_OP_ERROR(tmp, "fputs");
					newsval = -1;
					alertpanel_error(_("Error when writing temporary file for news sending."));
				}
			}
			fclose(tmpfp);

			if (newsval == 0) {
				debug_print("Sending message by news\n");

				folder = FOLDER(newsac->folder);

    				newsval = news_post(folder, tmp);
    				if (newsval < 0) {
            				alertpanel_error(_("Error occurred while posting the message to %s ."),
                            			 newsac->nntp_server);
    				}
			}
			unlink(tmp);
		}
		g_free(tmp);
	}

	fclose(fp);

	/* save message to outbox */
	if (mailval == 0 && newsval == 0 && savecopyfolder) {
		FolderItem *outbox;

		debug_print("saving sent message...\n");

		outbox = folder_find_item_from_identifier(savecopyfolder);
		if (!outbox)
			outbox = folder_get_default_outbox();
			
		if (save_clear_text || tmp_enc_file == NULL) {
			procmsg_save_to_outbox(outbox, file, TRUE);
		} else {
			procmsg_save_to_outbox(outbox, tmp_enc_file, FALSE);
		}
	}

	if (tmp_enc_file != NULL) {
		unlink(tmp_enc_file);
		free(tmp_enc_file);
		tmp_enc_file = NULL;
	}

	if (replymessageid != NULL || fwdmessageid != NULL) {
		gchar **tokens;
		FolderItem *item;
		
		if (replymessageid != NULL)
			tokens = g_strsplit(replymessageid, "\x7f", 0);
		else
			tokens = g_strsplit(fwdmessageid, "\x7f", 0);
		item = folder_find_item_from_identifier(tokens[0]);

		/* check if queued message has valid folder and message id */
		if (item != NULL && tokens[2] != NULL) {
			MsgInfo *msginfo;
			
			msginfo = folder_item_get_msginfo(item, atoi(tokens[1]));
		
			/* check if referring message exists and has a message id */
			if ((msginfo != NULL) && 
			    (msginfo->msgid != NULL) &&
			    (strcmp(msginfo->msgid, tokens[2]) != 0)) {
				procmsg_msginfo_free(msginfo);
				msginfo = NULL;
			}
			
			if (msginfo == NULL) {
				msginfo = folder_item_get_msginfo_by_msgid(item, tokens[2]);
			}
			
			if (msginfo != NULL) {
				if (replymessageid != NULL) {
					procmsg_msginfo_unset_flags(msginfo, MSG_FORWARDED, 0);
					procmsg_msginfo_set_flags(msginfo, MSG_REPLIED, 0);
				}  else {
					procmsg_msginfo_unset_flags(msginfo, MSG_REPLIED, 0);
					procmsg_msginfo_set_flags(msginfo, MSG_FORWARDED, 0);
				}
				procmsg_msginfo_free(msginfo);
			}
		}
		g_strfreev(tokens);
	}

	g_free(from);
	g_free(smtpserver);
	slist_free_strings(to_list);
	g_slist_free(to_list);
	slist_free_strings(newsgroup_list);
	g_slist_free(newsgroup_list);
	g_free(savecopyfolder);
	g_free(replymessageid);
	g_free(fwdmessageid);
	g_free(privacy_system);
	g_free(encrypt_data);

	return (newsval != 0 ? newsval : mailval);
}
Пример #12
0
gboolean pgpmime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
{
	MimeInfo *msgcontent, *encmultipart, *newinfo;
	FILE *fp;
	gchar *boundary, *enccontent;
	size_t len;
	gchar *textstr;
	gpgme_data_t gpgtext = NULL, gpgenc = NULL;
	gpgme_ctx_t ctx = NULL;
	gpgme_key_t *kset = NULL;
	gchar **fprs = g_strsplit(encrypt_data, " ", -1);
	gint i = 0;
	gpgme_error_t err;
	
	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\n"), 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");

	/* remove content node from message */
	msgcontent = (MimeInfo *) mimeinfo->node->children->data;
	g_node_unlink(msgcontent->node);

	/* create temporary multipart for content */
	encmultipart = procmime_mimeinfo_new();
	encmultipart->type = MIMETYPE_MULTIPART;
	encmultipart->subtype = g_strdup("encrypted");
	boundary = generate_mime_boundary("Encrypt");
	g_hash_table_insert(encmultipart->typeparameters, g_strdup("boundary"),
                            g_strdup(boundary));
	g_hash_table_insert(encmultipart->typeparameters, g_strdup("protocol"),
                            g_strdup("application/pgp-encrypted"));
	g_node_append(encmultipart->node, msgcontent->node);

	/* write message content to temporary file */
	fp = my_tmpfile();
	if (fp == NULL) {
		perror("my_tmpfile");
		privacy_set_error(_("Couldn't create temporary file, %s"), g_strerror(errno));
		g_free(kset);
		return FALSE;
	}
	procmime_write_mimeinfo(encmultipart, fp);
	rewind(fp);

	/* read temporary file into memory */
	textstr = get_canonical_content(fp, boundary);

	g_free(boundary);
	claws_fclose(fp);

	/* encrypt data */
	gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0);
	gpgme_data_new(&gpgenc);
	gpgme_set_armor(ctx, 1);
	cm_gpgme_data_rewind(gpgtext);
	
	err = gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc);

	enccontent = sgpgme_data_release_and_get_mem(gpgenc, &len);
	gpgme_data_release(gpgtext);
	g_free(textstr);
	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_release(ctx);
		g_free(enccontent);
		return FALSE;
	}

	/* create encrypted multipart */
	g_node_unlink(msgcontent->node);
	procmime_mimeinfo_free_all(&msgcontent);
	g_node_append(mimeinfo->node, encmultipart->node);

	newinfo = procmime_mimeinfo_new();
	newinfo->type = MIMETYPE_APPLICATION;
	newinfo->subtype = g_strdup("pgp-encrypted");
	newinfo->content = MIMECONTENT_MEM;
	newinfo->data.mem = g_strdup("Version: 1\n");
	g_node_append(encmultipart->node, newinfo->node);

	newinfo = procmime_mimeinfo_new();
	newinfo->type = MIMETYPE_APPLICATION;
	newinfo->subtype = g_strdup("octet-stream");
	newinfo->content = MIMECONTENT_MEM;
	newinfo->data.mem = g_malloc(len + 1);
	g_memmove(newinfo->data.mem, enccontent, len);
	newinfo->data.mem[len] = '\0';
	g_node_append(encmultipart->node, newinfo->node);

	g_free(enccontent);
	gpgme_release(ctx);

	return TRUE;
}
Пример #13
0
static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo)
{
	MimeInfo *encinfo, *decinfo, *parseinfo;
	gpgme_data_t cipher = NULL, plain = NULL;
	static gint id = 0;
	FILE *dstfp;
	gchar *fname;
	gpgme_verify_result_t sigstat = NULL;
	PrivacyDataPGP *data = NULL;
	gpgme_ctx_t ctx;
	gchar *chars;
	size_t len;
	gpgme_error_t err;

	if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) {
		debug_print(("Couldn't initialize GPG context, %s\n"), gpgme_strerror(err));
		privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
		return NULL;
	}
	
	cm_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_verify(cipher, &sigstat, ctx);

	gpgme_data_release(cipher);
	if (plain == NULL) {
		debug_print("plain is null!\n");
		gpgme_release(ctx);
		return NULL;
	}

    	fname = g_strdup_printf("%s%cplaintext.%08x",
		get_mime_tmp_dir(), G_DIR_SEPARATOR, ++id);

    	if ((dstfp = claws_fopen(fname, "wb")) == NULL) {
        	FILE_OP_ERROR(fname, "claws_fopen");
		privacy_set_error(_("Couldn't open decrypted file %s"), fname);
        	g_free(fname);
        	gpgme_data_release(plain);
		gpgme_release(ctx);
		debug_print("can't open!\n");
		return NULL;
    	}

	if (fprintf(dstfp, "MIME-Version: 1.0\n") < 0) {
        	FILE_OP_ERROR(fname, "fprintf");
		claws_fclose(dstfp);
		privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
        	g_free(fname);
        	gpgme_data_release(plain);
		gpgme_release(ctx);
		debug_print("can't open!\n");
		return NULL;
	}

	chars = sgpgme_data_release_and_get_mem(plain, &len);
	if (len > 0) {
		if (claws_fwrite(chars, 1, len, dstfp) < len) {
        		FILE_OP_ERROR(fname, "claws_fwrite");
			g_free(chars);
			claws_fclose(dstfp);
			privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
        		g_free(fname);
        		gpgme_data_release(plain);
			gpgme_release(ctx);
			debug_print("can't open!\n");
			return NULL;
		}
	}
	g_free(chars);

	if (claws_safe_fclose(dstfp) == EOF) {
        	FILE_OP_ERROR(fname, "claws_fclose");
		privacy_set_error(_("Couldn't close decrypted file %s"), fname);
        	g_free(fname);
        	gpgme_data_release(plain);
		gpgme_release(ctx);
		debug_print("can't open!\n");
		return NULL;
	}

	parseinfo = procmime_scan_file(fname);
	g_free(fname);
	if (parseinfo == NULL) {
		gpgme_release(ctx);
		privacy_set_error(_("Couldn't parse decrypted file."));
		return NULL;
	}
	decinfo = g_node_first_child(parseinfo->node) != NULL ?
		g_node_first_child(parseinfo->node)->data : NULL;
	if (decinfo == NULL) {
		privacy_set_error(_("Couldn't parse decrypted file parts."));
		gpgme_release(ctx);
		return NULL;
	}

	g_node_unlink(decinfo->node);
	procmime_mimeinfo_free_all(&parseinfo);

	decinfo->tmp = TRUE;

	if (sigstat != NULL && sigstat->signatures != NULL) {
		if (decinfo->privacy != NULL) {
			data = (PrivacyDataPGP *) decinfo->privacy;
		} else {
			data = pgpmime_new_privacydata();
			decinfo->privacy = (PrivacyData *) data;	
		}
		if (data != NULL) {
			data->done_sigtest = TRUE;
			data->is_signed = TRUE;
			data->sigstatus = sigstat;
			if (data->ctx)
				gpgme_release(data->ctx);
			data->ctx = ctx;
		}
	} else
		gpgme_release(ctx);

	return decinfo;
}