Compare commits

...

2 Commits

Author SHA1 Message Date
gfgit 79d84cc2d4 My fixes to the patch
See git.disroot.org/gfgit/claws-mail
2023-09-06 18:09:11 +02:00
gfgit 72e49c6443 Apply old patch from BUG 3904
See: https://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?
id=3904

Fixed code formatting and patch conflicts
2023-08-30 12:17:39 +02:00
13 changed files with 473 additions and 93 deletions

View File

@ -348,3 +348,4 @@ contributors (in addition to the above; based on Changelog)
Sakaguchi Takayuki
Charles Huber
nycex
Holger Smolinski

View File

@ -1416,6 +1416,15 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
g_free(text);
break;
}
if (mimeinfo->extra_headers){
g_message("messageview_show: found extra headers after encryption");
for(int i = 0; i < mimeinfo->extra_headers->len; i++) {
Header *hp = g_ptr_array_index(mimeinfo->extra_headers, i);
g_message("Extra Header %d - %s %s", i, hp->name, hp->body);
msginfo_add_protected_header(msginfo, hp);
}
}
}
if (messageview->msginfo != msginfo) {

View File

@ -1690,7 +1690,7 @@ static void mimeview_drag_data_get(GtkWidget *widget,
subst_for_filename(name);
}
}
procheader_header_array_destroy(headers);
g_ptr_array_free(headers, TRUE);
}
}
if (fp != NULL)

View File

@ -33,6 +33,7 @@
#include "utils.h"
#include "privacy.h"
#include "procmime.h"
#include "procheader.h"
#include "plugin.h"
#include "pgpmime.h"
@ -325,6 +326,18 @@ static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo)
return NULL;
}
if (parseinfo->extra_headers != NULL) {
g_message("PGP Plugin: decrypted message has protected headers");
for(int i = 0; i < parseinfo->extra_headers->len; i++) {
Header *hp = g_ptr_array_index(parseinfo->extra_headers, i);
g_message("Extra Header %d - %s %s", i, hp->name, hp->body);
}
decinfo->extra_headers = parseinfo->extra_headers;
parseinfo->extra_headers = NULL;
}
g_node_unlink(decinfo->node);
procmime_mimeinfo_free_all(&parseinfo);
@ -707,13 +720,68 @@ static PrivacySystem pgpmime_system = {
prefs_gpg_auto_check_signatures,
};
static MimeParser *protected_headers_parser = NULL;
static void pgpmime_add_header_no_content(void *header, void *data) {
Header *hdr = (Header *)header;
MimeInfo *mimeinfo = (MimeInfo *)data;
if (!procheader_headername_equal(hdr->name,"Content-Type")) {
if ( g_hash_table_lookup(mimeinfo->typeparameters,"protected-headers"))
g_message("Parser Found protected header: %s %s",hdr->name, hdr->body);
else
g_message("Parser Found rfc822-header: %s %s",hdr->name, hdr->body);
procmime_mimeinfo_add_extra_header(mimeinfo, hdr);
}
}
static gboolean protected_headers_parse (MimeParser *parser, MimeInfo *mimeinfo) {
FILE *fp;
g_message("Parsing rfc822-header mime part");
fp = claws_fopen(mimeinfo->data.filename, "rb");
if (!fp) {
FILE_OP_ERROR(mimeinfo->data.filename, "claws_fopen");
return FALSE;
}
if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0) {
FILE_OP_ERROR(mimeinfo->data.filename, "fseek");
claws_fclose(fp);
return FALSE;
}
GPtrArray *protected_headers = procheader_get_header_array(fp);
if (protected_headers != NULL) {
g_ptr_array_foreach(protected_headers,
pgpmime_add_header_no_content, mimeinfo);
g_ptr_array_free(protected_headers, TRUE);
/*TODO: We never return false??? */
}
claws_fclose(fp);
return TRUE;
}
void pgpmime_init()
{
protected_headers_parser = g_new0(MimeParser, 1);
protected_headers_parser->type = MIMETYPE_TEXT;
protected_headers_parser->sub_type = "rfc822-headers";
protected_headers_parser->parse = protected_headers_parse;
procmime_mimeparser_register(protected_headers_parser);
privacy_register_system(&pgpmime_system);
}
void pgpmime_done()
{
if (protected_headers_parser != NULL) {
procmime_mimeparser_unregister(protected_headers_parser);
g_free(protected_headers_parser);
protected_headers_parser = NULL;
} else
g_warning("%s:%d protected_headers_parser not initialized",__FUNCTION__,__LINE__);
privacy_unregister_system(&pgpmime_system);
}

View File

@ -25,6 +25,7 @@
#include "privacy.h"
#include "procmime.h"
#include "procmsg.h"
#include "procheader.h"
static GSList *systems = NULL;
static gchar *privacy_last_error = NULL;
@ -326,6 +327,19 @@ static gint decrypt(MimeInfo *mimeinfo, PrivacySystem *system)
procmime_mimeinfo_free_all(&mimeinfo);
if (decryptedinfo->extra_headers) {
if (parentinfo) {
g_message("Propagating extra headers up after decrpyt()");
parentinfo->extra_headers = decryptedinfo->extra_headers;
decryptedinfo->extra_headers = NULL;
for(int i = 0; i < parentinfo->extra_headers->len; i++) {
Header *hp = g_ptr_array_index(parentinfo->extra_headers, i);
g_message("Extra Header %d - %s %s", i, hp->name, hp->body);
}
} else
g_message("Identified extra headers up after decrpyt()");
}
g_node_insert(parentinfo->node, childnumber, decryptedinfo->node);
return 0;

View File

@ -58,7 +58,8 @@ static gint generic_get_one_field(gchar **bufptr, void *data,
HeaderEntry hentry[],
getlinefunc getline,
peekcharfunc peekchar,
gboolean unfold);
gboolean unfold,
gboolean allfields);
static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
gboolean full, gboolean decrypted);
@ -68,7 +69,15 @@ gint procheader_get_one_field(gchar **buf, FILE *fp,
{
return generic_get_one_field(buf, fp, hentry,
(getlinefunc)fgets_crlf, (peekcharfunc)file_peekchar,
TRUE);
TRUE, FALSE);
}
static gint procheader_get_one_field_extra(gchar **buf, FILE *fp,
HeaderEntry hentry[])
{
return generic_get_one_field(buf, fp, hentry,
(getlinefunc)fgets_crlf, (peekcharfunc)file_peekchar,
TRUE, TRUE);
}
static gint string_get_one_field(gchar **buf, char **str,
@ -77,7 +86,7 @@ static gint string_get_one_field(gchar **buf, char **str,
return generic_get_one_field(buf, str, hentry,
(getlinefunc)string_getline,
(peekcharfunc)string_peekchar,
TRUE);
TRUE, FALSE);
}
gboolean procheader_skip_headers(FILE *fp)
@ -137,12 +146,16 @@ static int file_peekchar(FILE *fp)
static gint generic_get_one_field(gchar **bufptr, void *data,
HeaderEntry *hentry,
getlinefunc getline, peekcharfunc peekchar,
gboolean unfold)
gboolean unfold, gboolean allfields)
{
/* returns -1 in case of failure of any kind, whatever it's a parsing error
or an allocation error. if returns -1, *bufptr is always NULL, and vice-versa,
and if returning 0 (OK), *bufptr is always non-NULL, so callers just have to
test the return value
and if returning >=0 (OK), *bufptr is always non-NULL, so callers just have to
test the return value.
returns -1, when end of headers reached (empty line) or any error
returns 0, when hentry == NULL
returns index of matching hentry, when hentry != NULL
returns index of last hentry (hentry[hnum].name == NULL) , if allfields == TRUE
*/
gint nexthead;
gint hnum = 0;
@ -175,12 +188,12 @@ static gint generic_get_one_field(gchar **bufptr, void *data,
} while (buf[0] == ' ' || buf[0] == '\t');
for (hp = hentry, hnum = 0; hp->name != NULL;
hp++, hnum++) {
hp++, hnum++) {
if (!g_ascii_strncasecmp(hp->name, buf,
strlen(hp->name)))
strlen(hp->name)))
break;
}
} while (hp->name == NULL);
} while (allfields == FALSE && hp->name == NULL);
} else {
/* read first line */
if (getline(buf, len, data) == NULL) {
@ -215,9 +228,13 @@ static gint generic_get_one_field(gchar **bufptr, void *data,
size_t tmplen;
gboolean skiptab = (nexthead == '\t');
/* trim previous trailing \n if requesting one header or
* unfolding was requested */
if ((!hentry && unfold) || (hp && hp->unfold))
/* trim previous trailing \n if
* unfolding was requested or
* the matching hentry required it
* was:
* (!hentry && unfold) || (hp && hp->unfold)) */
if (((hentry == NULL || (hp != NULL && hp->name == NULL)) && unfold) ||
(hp != NULL && hp->name != NULL && hp->unfold))
strretchomp(buf);
buflen = strlen(buf);
@ -262,7 +279,19 @@ gint procheader_get_one_field_asis(gchar **buf, FILE *fp)
return generic_get_one_field(buf, fp, NULL,
(getlinefunc)fgets_crlf,
(peekcharfunc)file_peekchar,
FALSE);
FALSE, TRUE);
}
inline
void procheader_header_free(gpointer ptr)
{
Header *header = (Header*) ptr;
if (!header) return;
g_free(header->name);
g_free(header->body);
g_free(header);
}
GPtrArray *procheader_get_header_array(FILE *fp)
@ -273,7 +302,7 @@ GPtrArray *procheader_get_header_array(FILE *fp)
cm_return_val_if_fail(fp != NULL, NULL);
headers = g_ptr_array_new();
headers = g_ptr_array_new_with_free_func(procheader_header_free);
while (procheader_get_one_field(&buf, fp, NULL) != -1) {
if ((header = procheader_parse_header(buf)) != NULL)
@ -285,30 +314,6 @@ GPtrArray *procheader_get_header_array(FILE *fp)
return headers;
}
void procheader_header_array_destroy(GPtrArray *harray)
{
gint i;
Header *header;
cm_return_if_fail(harray != NULL);
for (i = 0; i < harray->len; i++) {
header = g_ptr_array_index(harray, i);
procheader_header_free(header);
}
g_ptr_array_free(harray, TRUE);
}
void procheader_header_free(Header *header)
{
if (!header) return;
g_free(header->name);
g_free(header->body);
g_free(header);
}
/*
tests whether two headers' names are equal
remove the trailing ':' or ' ' before comparing
@ -388,31 +393,52 @@ Header * procheader_parse_header(gchar * buf)
}
void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
{
GPtrArray *headers = procheader_get_all_header_fields(fp, hentry);
if (headers)
g_ptr_array_unref(headers);
}
GPtrArray * procheader_get_all_header_fields(FILE *fp, HeaderEntry hentry[])
{
gchar *buf = NULL;
HeaderEntry *hp;
gint hnum;
gchar *p;
GPtrArray *extra_headers;
if (hentry == NULL) return;
if (hentry == NULL) return NULL;
while ((hnum = procheader_get_one_field(&buf, fp, hentry)) != -1) {
extra_headers = g_ptr_array_new_with_free_func(procheader_header_free);
if (extra_headers == NULL) return NULL;
while ((hnum = procheader_get_one_field_extra(&buf, fp, hentry)) != -1) {
hp = hentry + hnum;
p = buf + strlen(hp->name);
while (*p == ' ' || *p == '\t') p++;
if (hp->name != NULL)
{
p = buf + strlen(hp->name);
while (*p == ' ' || *p == '\t') p++;
if (hp->body == NULL)
hp->body = g_strdup(p);
else if (procheader_headername_equal(hp->name, "To") ||
procheader_headername_equal(hp->name, "Cc")) {
gchar *tp = hp->body;
hp->body = g_strconcat(tp, ", ", p, NULL);
g_free(tp);
if (hp->body == NULL)
hp->body = g_strdup(p);
else if (procheader_headername_equal(hp->name, "To") ||
procheader_headername_equal(hp->name, "Cc")) {
gchar *tp = hp->body;
hp->body = g_strconcat(tp, ", ", p, NULL);
g_free(tp);
}
} else if (extra_headers != NULL) {
g_ptr_array_add(extra_headers, procheader_parse_header(buf));
}
g_free(buf);
buf = NULL;
}
if ( extra_headers->len == 0) {
g_ptr_array_unref(extra_headers);
extra_headers = NULL;
}
return extra_headers;
}
MsgInfo *procheader_parse_file(const gchar *file, MsgFlags flags,

View File

@ -48,13 +48,14 @@ gint procheader_get_one_field_asis (gchar **buf,
FILE *fp);
GPtrArray *procheader_get_header_array (FILE *fp);
void procheader_header_array_destroy (GPtrArray *harray);
void procheader_header_free (Header *header);
void procheader_header_free (gpointer header);
gboolean procheader_skip_headers(FILE *fp);
void procheader_get_header_fields (FILE *fp,
HeaderEntry hentry[]);
GPtrArray *procheader_get_all_header_fields (FILE *fp,
HeaderEntry hentry[]);
MsgInfo *procheader_parse_file (const gchar *file,
MsgFlags flags,
gboolean full,
@ -83,7 +84,6 @@ void procheader_date_get_localtime (gchar *dest,
Header * procheader_parse_header (gchar * buf);
gboolean procheader_headername_equal (char * hdr1, char * hdr2);
void procheader_header_free (Header * header);
gint procheader_get_header_from_msginfo (MsgInfo *msginfo,
gchar **buf,

View File

@ -149,6 +149,11 @@ static gboolean free_func(GNode *node, gpointer data)
if (mimeinfo->sig_data)
privacy_free_signature_data(mimeinfo->sig_data);
if (mimeinfo->extra_headers) {
g_warning("Extra Header gets FREED!");
g_ptr_array_free(mimeinfo->extra_headers, TRUE);
}
g_free(mimeinfo);
return FALSE;
@ -1027,6 +1032,9 @@ FILE *procmime_get_first_encrypted_text_content(MsgInfo *msginfo)
privacy_get_error());
return NULL;
}
if ( encinfo->extra_headers ) {
g_message("get_first_encrypted_text: found extra headers during decryption");
}
}
partinfo = mimeinfo;
while (partinfo && partinfo->type != MIMETYPE_TEXT) {
@ -1463,6 +1471,32 @@ static int procmime_parse_mimepart(MimeInfo *parent,
guint length,
gboolean short_scan);
static inline void proc_mime_header(gpointer data, gpointer udata) {
gchar *value = data;
HeaderEntry *hp = NULL;
for(hp = (HeaderEntry *)udata; hp->name != NULL; hp++) {
if (!strncmp(hp->name, value, strlen(hp->name))) {
g_warning("Found standard MIME header in extra headers");
break;
}
}
}
static gchar *typenames[];
static void procmime_parse_content_type(const gchar *, MimeInfo *);
static inline MimeInfo *encrypted_parent(MimeInfo *mimeinfo)
{
MimeInfo *parent = procmime_mimeinfo_parent(mimeinfo);
if (parent != NULL) {
if (parent->type == MIMETYPE_MULTIPART &&
strncmp(parent->subtype, "encrypted", strlen("encrypted")) == 0 )
return parent;
else return encrypted_parent(parent);
}
return parent;
}
static void procmime_parse_message_rfc822(MimeInfo *mimeinfo, gboolean short_scan)
{
HeaderEntry hentry[] = {{"Content-Type:", NULL, TRUE},
@ -1487,9 +1521,12 @@ static void procmime_parse_message_rfc822(MimeInfo *mimeinfo, gboolean short_sca
FILE *fp;
gchar *tmp;
gint len = 0;
GPtrArray *headers = NULL;
procmime_decode_content(mimeinfo);
g_message("procmime_parse_message_rfc822 called for (%s/%s) file '%s'@%u",typenames[mimeinfo->type], mimeinfo->subtype, mimeinfo->data.filename, mimeinfo->offset);
fp = claws_fopen(mimeinfo->data.filename, "rb");
if (fp == NULL) {
FILE_OP_ERROR(mimeinfo->data.filename, "claws_fopen");
@ -1500,41 +1537,77 @@ static void procmime_parse_message_rfc822(MimeInfo *mimeinfo, gboolean short_sca
claws_fclose(fp);
return;
}
procheader_get_header_fields(fp, hentry);
headers = procheader_get_all_header_fields(fp, hentry);
if (hentry[0].body != NULL) {
tmp = conv_unmime_header(hentry[0].body, NULL, FALSE);
g_free(hentry[0].body);
hentry[0].body = tmp;
}
g_free(hentry[0].body);
hentry[0].body = tmp;
}
if (hentry[2].body != NULL) {
tmp = conv_unmime_header(hentry[2].body, NULL, FALSE);
g_free(hentry[2].body);
hentry[2].body = tmp;
}
g_free(hentry[2].body);
hentry[2].body = tmp;
}
if (hentry[4].body != NULL) {
tmp = conv_unmime_header(hentry[4].body, NULL, FALSE);
g_free(hentry[4].body);
hentry[4].body = tmp;
}
g_free(hentry[4].body);
hentry[4].body = tmp;
}
if (hentry[5].body != NULL) {
tmp = conv_unmime_header(hentry[5].body, NULL, FALSE);
g_free(hentry[5].body);
hentry[5].body = tmp;
}
g_free(hentry[5].body);
hentry[5].body = tmp;
}
if (hentry[7].body != NULL) {
tmp = conv_unmime_header(hentry[7].body, NULL, FALSE);
g_free(hentry[7].body);
hentry[7].body = tmp;
}
g_free(hentry[7].body);
hentry[7].body = tmp;
}
if (hentry[8].body != NULL) {
tmp = conv_unmime_header(hentry[8].body, NULL, FALSE);
g_free(hentry[8].body);
hentry[8].body = tmp;
}
g_free(hentry[8].body);
hentry[8].body = tmp;
}
MimeInfo *thispart = procmime_mimeinfo_new();
procmime_parse_content_type(hentry[0].body, thispart);
if ( g_hash_table_lookup(thispart->typeparameters, "protected-headers") != NULL ) {
HeaderEntry *hp;
g_message("Found protected headers attribute %s",(gchar *)g_hash_table_lookup(thispart->typeparameters, "protected-headers"));
/* TODO: g_ptr_array_steal_index() is costly.
* We can replace item witn NULL to state it should not be freed and we take ownership
* instead of stealing it which forces array to resize and move items around.
*/
while(headers->len) {
/* Take ownership because header is passed to mimeinfo struct without copy */
Header *header = (Header *)g_ptr_array_steal_index(headers, 0);
/* TODO: Sanity check, remove for prod!*/
// g_message("testing Header: %s", headbuf);
hp = &hentry[0];
while (hp->name != NULL) {
if (strcmp(hp->name, header->name) == 0) {
g_warning("Removing Header: %s", hp->name);
procheader_header_free(header);
break;
}
hp++;
}
/* TODO: End sanity check */
if (hp->name == NULL)
g_message("Preamble: Found extra (protected) Header: %s", header->name);
procmime_mimeinfo_add_extra_header(mimeinfo, header);
}
}
g_ptr_array_unref(headers);
content_start = ftell(fp);
claws_fclose(fp);
len = mimeinfo->length - (content_start - mimeinfo->offset);
if (len < 0)
len = 0;
@ -1585,9 +1658,9 @@ static void procmime_parse_disposition_notification(MimeInfo *mimeinfo,
procheader_get_header_fields(fp, hentry);
}
claws_fclose(fp);
claws_fclose(fp);
if (!hentry[0].body || !hentry[1].body) {
if (!hentry[0].body || !hentry[1].body) {
debug_print("MsgId %s, Disp %s\n",
hentry[0].body ? hentry[0].body:"(nil)",
hentry[1].body ? hentry[1].body:"(nil)");
@ -1702,6 +1775,47 @@ static void procmime_parse_multipart(MimeInfo *mimeinfo, gboolean short_scan)
return;
}
if ( g_hash_table_lookup(mimeinfo->typeparameters, "protected-headers") != NULL) {
g_message("Found multipart message with protected heders '%s'@%u",mimeinfo->data.filename,mimeinfo->offset);
g_message("Found protected headers attribute %s",(gchar *)g_hash_table_lookup(mimeinfo->typeparameters, "protected-headers"));
#if 0
if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0) {
FILE_OP_ERROR(mimeinfo->data.filename, "fseek");
claws_fclose(fp);
return;
}
GPtrArray *headers = procheader_get_all_header_fields(fp, hentry);
HeaderEntry *hp;
for (guint ii = 0; ii < headers->len; ii ++) {
gchar *headbuf = (gchar *)g_ptr_array_index(headers, ii);
/* TODO: Sanity check, remove for prod!*/
g_message("testing Header: %s", headbuf);
hp = &hentry[0];
while (hp->name != NULL) {
if (strncmp(hp->name, headbuf,strlen(hp->name)) == 0) {
g_warning("Removing Header: %s", hp->name);
g_ptr_array_remove_index(headers,ii);
break;
}
hp++;
}
if (hp->name == NULL)
/* TODO: End sanity check */
g_message("Found extra (protected) Header: %s",headbuf);
if ( mimeinfo->extra_headers == NULL ) {
mimeinfo->extra_headers = g_ptr_array_new();
}
Header *header = procheader_parse_header(headbuf);
if ( header != NULL )
g_ptr_array_add(mimeinfo->extra_headers, header);
else
g_warning("Found header line which cannot be parsed: %s",headbuf);
}
g_ptr_array_unref(headers);
#endif
}
if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0) {
FILE_OP_ERROR(mimeinfo->data.filename, "fseek");
claws_fclose(fp);
@ -2045,6 +2159,13 @@ static gboolean procmime_mimeparser_parse(MimeParser *parser, MimeInfo *mimeinfo
return parser->parse(parser, mimeinfo);
}
void procmime_mimeinfo_add_extra_header(MimeInfo *mimeinfo, Header *header) {
if ( mimeinfo->extra_headers == NULL )
mimeinfo->extra_headers = g_ptr_array_new();
if ( mimeinfo->extra_headers != NULL )
g_ptr_array_add(mimeinfo->extra_headers, header);
}
static int procmime_parse_mimepart(MimeInfo *parent,
gchar *content_type,
gchar *content_encoding,
@ -2063,7 +2184,7 @@ static int procmime_parse_mimepart(MimeInfo *parent,
MimeParser *parser = NULL;
gboolean parsed = FALSE;
int result = 0;
g_message("procmime_parse_mimepart (%s) called for file '%s'@%u",content_type,filename, offset);
/* Create MimeInfo */
mimeinfo = procmime_mimeinfo_new();
mimeinfo->content = MIMECONTENT_FILE;
@ -2164,6 +2285,18 @@ static int procmime_parse_mimepart(MimeInfo *parent,
break;
}
}
if ( mimeinfo->extra_headers != NULL ) {
g_message("Parsed a message with protected-headers, propagating upwards to %p",parent);
if (parent != NULL) {
parent->extra_headers = mimeinfo->extra_headers;
mimeinfo->extra_headers = NULL;
for(int i = 0; i < parent->extra_headers->len; i++) {
Header *hp = g_ptr_array_index(parent->extra_headers, i);
g_message("Extra Header %d - %s %s", i, hp->name, hp->body);
}
}
}
return result;
}
@ -2222,6 +2355,9 @@ static MimeInfo *procmime_scan_file_with_offset(const gchar *filename, int offse
mimeinfo->length = buf.st_size - offset;
procmime_parse_message_rfc822(mimeinfo, short_scan);
if ( mimeinfo->extra_headers ) {
g_message("Parsed a file which includes protected headers");
}
if (debug_get_mode())
output_mime_structure(mimeinfo, 0);

View File

@ -156,6 +156,9 @@ struct _MimeInfo
SignatureData *sig_data;
gboolean broken;
/* protected headers */
GPtrArray *extra_headers;
};
#define IS_BOUNDARY(s, bnd, len) \
@ -252,6 +255,7 @@ void *procmime_get_part_as_string(MimeInfo *mimeinfo,
GInputStream *procmime_get_part_as_inputstream(MimeInfo *mimeinfo);
GdkPixbuf *procmime_get_part_as_pixbuf(MimeInfo *mimeinfo, GError **error);
void procmime_mimeinfo_add_extra_header(MimeInfo *, Header *);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -818,6 +818,41 @@ void procmsg_msginfo_add_avatar(MsgInfo *msginfo, gint type, const gchar *data)
msginfo->extradata->avatars = g_slist_append(msginfo->extradata->avatars, av);
}
GHashTable *procmsg_msginfo_get_protected_headers(MsgInfo *msginfo)
{
if (!msginfo || !msginfo->extradata || !msginfo->extradata->protected_headers)
return NULL;
return msginfo->extradata->protected_headers;
}
GHashTable *procmsg_msginfo_add_protected_headers(MsgInfo *msginfo)
{
if (!msginfo->extradata)
msginfo->extradata = g_new0(MsgInfoExtraData, 1);
if (msginfo->extradata->protected_headers) {
g_message("Found another instance of RFC822 headers,reusing it");
g_hash_table_remove_all(msginfo->extradata->protected_headers);
} else {
msginfo->extradata->protected_headers =
g_hash_table_new(g_str_hash, g_str_equal);
}
return msginfo->extradata->protected_headers;
}
void msginfo_add_protected_header(MsgInfo *msginfo, Header *header)
{
GHashTable *msginfo_headers =
procmsg_msginfo_get_protected_headers(msginfo);
if (msginfo_headers == NULL)
msginfo_headers = procmsg_msginfo_add_protected_headers(msginfo);
g_hash_table_ref(msginfo_headers);
g_message("Adding Header %s:%s",header->name, header->body);
g_hash_table_insert(msginfo_headers,header->name, strdup(header->body));
g_hash_table_unref(msginfo_headers);
}
gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo)
{
gchar *folder_id;
@ -1453,6 +1488,10 @@ void procmsg_msginfo_free(MsgInfo **msginfo_ptr)
FREENULL(msginfo->extradata->account_server);
FREENULL(msginfo->extradata->account_login);
FREENULL(msginfo->extradata->resent_from);
if (msginfo->extradata->protected_headers) {
g_hash_table_unref(msginfo->extradata->protected_headers);
msginfo->extradata->protected_headers = NULL;
}
FREENULL(msginfo->extradata);
}
slist_free_strings_full(msginfo->references);
@ -1537,6 +1576,8 @@ guint procmsg_msginfo_memusage(MsgInfo *msginfo)
memusage += strlen(msginfo->extradata->list_archive);
if (msginfo->extradata->list_owner)
memusage += strlen(msginfo->extradata->list_owner);
if (msginfo->extradata->protected_headers)
memusage += 0; // TODO: determine correct size of extradata
}
return memusage;
}

View File

@ -255,6 +255,8 @@ struct _MsgInfoExtraData
gchar *list_help;
gchar *list_archive;
gchar *list_owner;
GHashTable *protected_headers;
};
struct _MsgInfoAvatar
@ -405,4 +407,7 @@ gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo);
gchar *procmsg_msginfo_get_avatar(MsgInfo *msginfo, gint type);
void procmsg_msginfo_add_avatar(MsgInfo *msginfo, gint type, const gchar *data);
GHashTable *procmsg_msginfo_get_protected_headers(MsgInfo *msginfo);
GHashTable *procmsg_msginfo_add_protected_headers(MsgInfo *msginfo);
void msginfo_add_protected_header(MsgInfo *, Header *);
#endif /* __PROCMSG_H__ */

View File

@ -168,6 +168,7 @@ static GPtrArray *textview_scan_header (TextView *textview,
FILE *fp);
static void textview_show_header (TextView *textview,
GPtrArray *headers);
static void textview_show_headers (TextView *textview);
static void textview_zoom(GtkWidget *widget, gboolean zoom_in);
static void textview_zoom_in(GtkWidget *widget, gpointer data);
@ -616,6 +617,7 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
textview->loading = TRUE;
textview->stop_loading = FALSE;
textview->headers_printed = FALSE;
textview_clear(textview);
@ -636,6 +638,18 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
END_TIMING();
}
static void textview_add_protected_header(TextView *textview, Header * header){
if ( textview != NULL &&
textview->messageview != NULL &&
textview->messageview->msginfo != NULL)
msginfo_add_protected_header(textview->messageview->msginfo, header);
else
g_warning("Could not obtain msginfo for textview %p -> messageview %p -> %p",
textview, textview == NULL ? NULL : textview->messageview,
textview == NULL || textview->messageview == NULL ? NULL :
textview->messageview->msginfo);
}
static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
{
GtkAllocation allocation;
@ -643,7 +657,7 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
GtkTextBuffer *buffer;
GtkTextIter iter, start_iter;
gchar buf[BUFFSIZE];
GPtrArray *headers = NULL;
// GPtrArray *headers = NULL;
const gchar *name;
gchar *content_type;
gint charcount;
@ -683,17 +697,21 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
END_TIMING();
return;
}
headers = textview_scan_header(textview, fp);
if (headers) {
if (textview->headers != NULL) {
g_warning("textview->headers not NULL, discarding");
g_ptr_array_unref(textview->headers);
textview->headers=NULL;
}
textview->headers = textview_scan_header(textview, fp);
if (textview->headers) {
g_message("Added headers: %p, %d", textview->headers, textview->headers->len);
if (charcount > 0)
gtk_text_buffer_insert(buffer, &iter, "\n", 1);
if (procmime_mimeinfo_parent(mimeinfo) == NULL &&
!prefs_common.display_header_pane)
if (procmime_mimeinfo_parent(mimeinfo) == NULL)
textview_show_tags(textview);
textview_show_header(textview, headers);
procheader_header_array_destroy(headers);
}
} else
g_message("NOT added headers");
claws_fclose(fp);
END_TIMING();
return;
@ -775,6 +793,8 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
END_TIMING();
GTK_EVENTS_FLUSH();
}
} else if (mimeinfo->type == MIMETYPE_TEXT &&
!g_ascii_strcasecmp(mimeinfo->subtype, "rfc822-headers")) {
} else if (mimeinfo->type == MIMETYPE_TEXT) {
if (prefs_common.display_header && (charcount > 0))
gtk_text_buffer_insert(buffer, &iter, "\n", 1);
@ -1018,6 +1038,9 @@ static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
gboolean continue_write = TRUE;
size_t wrote = 0, i = 0;
if (textview->headers_printed == FALSE) {
textview_show_headers(textview);
}
if (textview->messageview->forced_charset)
charset = textview->messageview->forced_charset;
else {
@ -1929,7 +1952,7 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
headers = procheader_get_header_array(fp);
sorted_headers = g_ptr_array_new();
for (i = 0; i < headers->len; i++) {
header = g_ptr_array_index(headers, i);
header = g_ptr_array_steal_index(headers, i);
if (!procheader_header_is_internal(header->name))
g_ptr_array_add(sorted_headers, header);
else
@ -1947,7 +1970,7 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
headers = procheader_get_header_array(fp);
sorted_headers = g_ptr_array_new();
sorted_headers = g_ptr_array_new_with_free_func(procheader_header_free);
for (disphdr_list = prefs_common.disphdr_list; disphdr_list != NULL;
disphdr_list = disphdr_list->next) {
@ -1958,12 +1981,12 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
header = g_ptr_array_index(headers, i);
if (procheader_headername_equal(header->name,
dp->name)) {
/* Take ownership of item */
g_ptr_array_steal_index(headers, i);
if (dp->hidden)
procheader_header_free(header);
else
g_ptr_array_add(sorted_headers, header);
g_ptr_array_remove_index(headers, i);
i--;
}
}
@ -1971,7 +1994,8 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
if (prefs_common.show_other_header) {
for (i = 0; i < headers->len; i++) {
header = g_ptr_array_index(headers, i);
/* Take ownership of item */
header = g_ptr_array_steal_index(headers, i);
unfold_line(header->body);
if (!procheader_header_is_internal(header->name)) {
g_ptr_array_add(sorted_headers, header);
@ -1981,7 +2005,7 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
}
g_ptr_array_free(headers, TRUE);
} else
procheader_header_array_destroy(headers);
g_ptr_array_free(headers, TRUE);
return sorted_headers;
@ -2266,7 +2290,10 @@ static void textview_show_header(TextView *textview, GPtrArray *headers)
gint i;
cm_return_if_fail(headers != NULL);
if (textview->headers_printed == TRUE) {
return;
}
textview->headers_printed = TRUE;
for (i = 0; i < headers->len; i++) {
header = g_ptr_array_index(headers, i);
cm_return_if_fail(header->name != NULL);
@ -2344,6 +2371,53 @@ static void textview_show_header(TextView *textview, GPtrArray *headers)
textview_show_contact_pic(textview);
}
static inline void textview_verify_protected_header(void *m_ptr, void *p_ptr)
{
Header *m_header = (Header *)m_ptr;
GHashTable *p_headers = (GHashTable *)p_ptr;
gchar *p_body = g_hash_table_lookup(p_headers,m_header->name);
if (p_body != NULL) {
g_message("Comparing '%s' and '%s'",m_header->body, p_body);
if (!g_ascii_strcasecmp(m_header->body, p_body)) {
size_t s = strlen(m_header->body) + strlen("(Verified) ")+1;
gchar* tmp = g_malloc(s);
snprintf(tmp, s, "(Verified) %s", m_header->body);
g_free(m_header->body);
m_header->body = tmp;
} else {
size_t s = strlen(m_header->body) + strlen(" (was: protected )")+strlen(p_body)+1;
gchar* tmp = g_malloc(s);
snprintf(tmp, s, "%s (was: protected %s)", m_header->body, p_body);
g_free(m_header->body);
m_header->body = tmp;
}
}
}
static void textview_show_headers(TextView *textview) {
if (textview->headers != NULL) {
g_message("Displaying headers");
GPtrArray *headers = g_ptr_array_sized_new(textview->headers->len);
g_ptr_array_set_free_func(headers, NULL);
for (unsigned int i = 0; i < textview->headers->len; i++) {
g_ptr_array_add(headers, g_ptr_array_index(textview->headers, i));
}
if ( textview->messageview != NULL &&
textview->messageview->msginfo != NULL &&
textview->messageview->msginfo->extradata != NULL &&
textview->messageview->msginfo->extradata->protected_headers != NULL) {
GHashTable *p_headers = textview->messageview->msginfo->extradata->protected_headers;
g_ptr_array_foreach(headers, textview_verify_protected_header, p_headers);
}
textview_show_header(textview, headers);
textview->headers_printed = TRUE;
g_ptr_array_unref(headers);
} else {
g_message("No headers in textview...");
}
return;
}
gboolean textview_search_string(TextView *textview, const gchar *str,
gboolean case_sens)
{

View File

@ -83,6 +83,8 @@ struct _TextView
gboolean loading;
gboolean stop_loading;
gint prev_quote_level;
gboolean headers_printed;
GPtrArray *headers;
};
TextView *textview_create (void);