]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Properly detect encrypted files in zip archives
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 13 Apr 2019 10:25:16 +0000 (11:25 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 13 Apr 2019 10:25:16 +0000 (11:25 +0100)
src/libmime/archives.c
src/libmime/archives.h

index 21bd51ecd4508875816e97e9462e93b8da6af715..ed49db4b388a1c123dd74d39af57ba574be19559 100644 (file)
@@ -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;
        }
 
index 9ea1b28e1b88bf7c8b4bcc0e92add588db7a3e36..e4e7b8b031bca080a3a53a61aaedf14c33af10cd 100644 (file)
@@ -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 {