diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-04-13 11:25:16 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-04-13 11:25:16 +0100 |
commit | 6861c93af2e50b118e3c4a3609f72a90c790c184 (patch) | |
tree | 0f0c11c11a536f69e4d54eb7a3ed90c6f34c368f | |
parent | f0d671bca423e302fe82a76cac3fde9ddbdb5d81 (diff) | |
download | rspamd-6861c93af2e50b118e3c4a3609f72a90c790c184.tar.gz rspamd-6861c93af2e50b118e3c4a3609f72a90c790c184.zip |
[Fix] Properly detect encrypted files in zip archives
-rw-r--r-- | src/libmime/archives.c | 27 | ||||
-rw-r--r-- | src/libmime/archives.h | 4 |
2 files changed, 29 insertions, 2 deletions
diff --git a/src/libmime/archives.c b/src/libmime/archives.c index 21bd51ecd..ed49db4b3 100644 --- a/src/libmime/archives.c +++ b/src/libmime/archives.c @@ -208,6 +208,8 @@ rspamd_archive_process_zip (struct rspamd_task *task, arch); while (cd < eocd) { + guint16 flags; + /* Read central directory record */ if (eocd - cd < cd_basic_len || memcmp (cd, cd_magic, sizeof (cd_magic)) != 0) { @@ -216,6 +218,8 @@ rspamd_archive_process_zip (struct rspamd_task *task, return; } + memcpy (&flags, cd + 8, sizeof (guint16)); + flags = GUINT16_FROM_LE (flags); memcpy (&comp_size, cd + 20, sizeof (guint32)); comp_size = GUINT32_FROM_LE (comp_size); memcpy (&uncomp_size, cd + 24, sizeof (guint32)); @@ -239,6 +243,10 @@ rspamd_archive_process_zip (struct rspamd_task *task, f->compressed_size = comp_size; f->uncompressed_size = uncomp_size; + if (flags & 0x41u) { + f->flags |= RSPAMD_ARCHIVE_FILE_ENCRYPTED; + } + if (f->fname) { g_ptr_array_add (arch->files, f); msg_debug_archive ("found file in zip archive: %v", f->fname); @@ -247,6 +255,25 @@ rspamd_archive_process_zip (struct rspamd_task *task, g_free (f); } + /* Process extra fields */ + const guchar *extra = cd + fname_len + cd_basic_len; + p = extra; + + while (p + sizeof (guint16) * 2 < extra + extra_len) { + guint16 hid, hlen; + + memcpy (&hid, p, sizeof (guint16)); + hid = GUINT16_FROM_LE (hid); + memcpy (&hlen, p + sizeof (guint16), sizeof (guint16)); + hlen = GUINT16_FROM_LE (hlen); + + if (hid == 0x0017) { + f->flags |= RSPAMD_ARCHIVE_FILE_ENCRYPTED; + } + + p += hlen + sizeof (guint16) * 2; + } + cd += fname_len + comment_len + extra_len + cd_basic_len; } diff --git a/src/libmime/archives.h b/src/libmime/archives.h index 9ea1b28e1..e4e7b8b03 100644 --- a/src/libmime/archives.h +++ b/src/libmime/archives.h @@ -26,11 +26,11 @@ enum rspamd_archive_type { }; enum rspamd_archive_flags { - RSPAMD_ARCHIVE_ENCRYPTED = (1 << 0), + RSPAMD_ARCHIVE_ENCRYPTED = (1u << 0u), }; enum rspamd_archive_file_flags { - RSPAMD_ARCHIVE_FILE_ENCRYPTED = (1 << 0), + RSPAMD_ARCHIVE_FILE_ENCRYPTED = (1u << 0u), }; struct rspamd_archive_file { |