libarchive-static 1.0.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/extconf.rb +2 -9
- data/ext/libarchive-0.1.1/ext/archive_read_support_compression.c +6 -6
- data/ext/libarchive-0.1.1/ext/archive_read_support_compression.o +0 -0
- data/ext/libarchive-0.1.1/ext/archive_read_support_format.o +0 -0
- data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.c +1 -1
- data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.o +0 -0
- data/ext/libarchive-0.1.1/ext/archive_write_set_compression.c +5 -5
- data/ext/libarchive-0.1.1/ext/archive_write_set_compression.o +0 -0
- data/ext/libarchive-0.1.1/ext/config.h +23 -0
- data/ext/libarchive-0.1.1/ext/config.log +230 -0
- data/ext/libarchive-0.1.1/ext/config.status +671 -0
- data/ext/libarchive-0.1.1/ext/libarchive.c +1 -1
- data/ext/libarchive-0.1.1/ext/libarchive.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_archive.c +7 -7
- data/ext/libarchive-0.1.1/ext/libarchive_archive.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_entry.c +6 -0
- data/ext/libarchive-0.1.1/ext/libarchive_entry.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_reader.c +6 -4
- data/ext/libarchive-0.1.1/ext/libarchive_reader.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_ruby.so +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_win32.h +1 -1
- data/ext/libarchive-0.1.1/ext/libarchive_writer.c +2 -2
- data/ext/libarchive-0.1.1/ext/libarchive_writer.o +0 -0
- data/ext/libarchive-3.6.2/Makefile.in +16892 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_append_compile_flags.m4 +67 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_append_flag.m4 +71 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_check_compile_flag.m4 +74 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_require_defined.m4 +37 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/check_stdcall_func.m4 +0 -0
- data/ext/libarchive-3.6.2/build/autoconf/compile +348 -0
- data/ext/libarchive-3.6.2/build/autoconf/config.guess +1754 -0
- data/ext/libarchive-3.6.2/build/autoconf/config.rpath +696 -0
- data/ext/libarchive-3.6.2/build/autoconf/config.sub +1890 -0
- data/ext/libarchive-3.6.2/build/autoconf/depcomp +791 -0
- data/ext/libarchive-3.6.2/build/autoconf/iconv.m4 +271 -0
- data/ext/libarchive-3.6.2/build/autoconf/install-sh +541 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/la_uid_t.m4 +0 -0
- data/ext/libarchive-3.6.2/build/autoconf/lib-ld.m4 +109 -0
- data/ext/libarchive-3.6.2/build/autoconf/lib-link.m4 +777 -0
- data/ext/libarchive-3.6.2/build/autoconf/lib-prefix.m4 +224 -0
- data/ext/libarchive-3.6.2/build/autoconf/ltmain.sh +11251 -0
- data/ext/libarchive-3.6.2/build/autoconf/m4_ax_compile_check_sizeof.m4 +115 -0
- data/ext/libarchive-3.6.2/build/autoconf/missing +215 -0
- data/ext/libarchive-3.6.2/build/autoconf/test-driver +153 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/pkgconfig/libarchive.pc.in +4 -1
- data/ext/libarchive-3.6.2/config.h.in +1504 -0
- data/ext/libarchive-3.6.2/configure +25558 -0
- data/ext/libarchive-3.6.2/libarchive/archive.h +1212 -0
- data/ext/libarchive-3.6.2/libarchive/archive_acl.c +2097 -0
- data/ext/libarchive-3.6.2/libarchive/archive_acl_private.h +83 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2.h +197 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2_impl.h +161 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2s_ref.c +369 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2sp_ref.c +361 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_check_magic.c +63 -22
- data/ext/libarchive-3.6.2/libarchive/archive_cmdline.c +227 -0
- data/ext/libarchive-3.6.2/libarchive/archive_cmdline_private.h +47 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_crc32.h +17 -0
- data/ext/libarchive-3.6.2/libarchive/archive_cryptor.c +534 -0
- data/ext/libarchive-3.6.2/libarchive/archive_cryptor_private.h +188 -0
- data/ext/libarchive-3.6.2/libarchive/archive_digest.c +1505 -0
- data/ext/libarchive-3.6.2/libarchive/archive_digest_private.h +416 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_darwin.c +559 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_freebsd.c +712 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_linux.c +760 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_sunos.c +824 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_endian.h +48 -15
- data/ext/libarchive-3.6.2/libarchive/archive_entry.c +2149 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry.h +305 -106
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_bhfi.c +5 -4
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_stat.c +9 -3
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_link_resolver.c +104 -62
- data/ext/libarchive-3.6.2/libarchive/archive_entry_locale.h +92 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_private.h +65 -49
- data/ext/libarchive-3.6.2/libarchive/archive_entry_sparse.c +156 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_stat.c +6 -6
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_strmode.c +1 -1
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_xattr.c +4 -6
- data/ext/libarchive-3.6.2/libarchive/archive_getdate.c +1165 -0
- data/ext/libarchive-3.6.2/libarchive/archive_getdate.h +39 -0
- data/ext/libarchive-3.6.2/libarchive/archive_hmac.c +334 -0
- data/ext/libarchive-3.6.2/libarchive/archive_hmac_private.h +117 -0
- data/ext/libarchive-3.6.2/libarchive/archive_match.c +1875 -0
- data/ext/libarchive-3.6.2/libarchive/archive_openssl_evp_private.h +53 -0
- data/ext/libarchive-3.6.2/libarchive/archive_openssl_hmac_private.h +54 -0
- data/ext/libarchive-3.6.2/libarchive/archive_options.c +218 -0
- data/ext/libarchive-3.6.2/libarchive/archive_options_private.h +51 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.c +337 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.h +49 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.c +463 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.h +52 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_platform.h +77 -9
- data/ext/libarchive-3.6.2/libarchive/archive_platform_acl.h +55 -0
- data/ext/libarchive-3.6.2/libarchive/archive_platform_xattr.h +47 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd7.c +1168 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd7_private.h +119 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd8.c +1287 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd8_private.h +148 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd_private.h +151 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_private.h +74 -18
- data/ext/libarchive-3.6.2/libarchive/archive_random.c +272 -0
- data/ext/libarchive-3.6.2/libarchive/archive_random_private.h +36 -0
- data/ext/libarchive-3.6.2/libarchive/archive_rb.c +709 -0
- data/ext/libarchive-3.6.2/libarchive/archive_rb.h +113 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read.c +1756 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_add_passphrase.c +190 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_append_filter.c +204 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_data_into_fd.c +64 -18
- data/ext/libarchive-3.6.2/libarchive/archive_read_disk_entry_from_file.c +1086 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_disk_posix.c +2732 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_private.h +40 -4
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_set_standard_lookup.c +21 -11
- data/ext/libarchive-3.6.2/libarchive/archive_read_disk_windows.c +2479 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_extract.c +60 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_extract.c → libarchive-3.6.2/libarchive/archive_read_extract2.c} +34 -61
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_fd.c +70 -49
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_file.c +38 -23
- data/ext/libarchive-3.6.2/libarchive/archive_read_open_filename.c +586 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_memory.c +58 -28
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_private.h +127 -59
- data/ext/libarchive-3.6.2/libarchive/archive_read_set_format.c +117 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_set_options.c +133 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_all.c → libarchive-3.6.2/libarchive/archive_read_support_filter_all.c} +35 -10
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_by_code.c +83 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_bzip2.c → libarchive-3.6.2/libarchive/archive_read_support_filter_bzip2.c} +38 -26
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_compress.c → libarchive-3.6.2/libarchive/archive_read_support_filter_compress.c} +52 -44
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_grzip.c +112 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_gzip.c → libarchive-3.6.2/libarchive/archive_read_support_filter_gzip.c} +108 -37
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lrzip.c +122 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lz4.c +742 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lzop.c +499 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_none.c → libarchive-3.6.2/libarchive/archive_read_support_filter_none.c} +15 -3
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_program.c → libarchive-3.6.2/libarchive/archive_read_support_filter_program.c} +114 -77
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_rpm.c → libarchive-3.6.2/libarchive/archive_read_support_filter_rpm.c} +31 -31
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_uu.c → libarchive-3.6.2/libarchive/archive_read_support_filter_uu.c} +141 -85
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_xz.c → libarchive-3.6.2/libarchive/archive_read_support_filter_xz.c} +369 -284
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_zstd.c +297 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_7zip.c +3900 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_all.c +89 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_ar.c +126 -72
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_by_code.c +92 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cab.c +3228 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cpio.c +1104 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_empty.c +14 -11
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_iso9660.c +990 -541
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_lha.c +2916 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_mtree.c +2150 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar.c +3797 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar5.c +4251 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_raw.c +38 -31
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_tar.c +1157 -629
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_warc.c +848 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_xar.c +439 -258
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_zip.c +4270 -0
- data/ext/libarchive-3.6.2/libarchive/archive_string.c +4240 -0
- data/ext/libarchive-3.6.2/libarchive/archive_string.h +243 -0
- data/ext/libarchive-3.6.2/libarchive/archive_string_composition.h +2292 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_string_sprintf.c +44 -16
- data/ext/libarchive-3.6.2/libarchive/archive_util.c +655 -0
- data/ext/libarchive-3.6.2/libarchive/archive_version_details.c +151 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_virtual.c +85 -16
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.c +214 -541
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.h +74 -106
- data/ext/libarchive-3.6.2/libarchive/archive_write.c +828 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter.c +72 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_b64encode.c +304 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_by_name.c +77 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_bzip2.c +401 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_write_set_compression_compress.c → libarchive-3.6.2/libarchive/archive_write_add_filter_compress.c} +86 -131
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_grzip.c +135 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_gzip.c +442 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lrzip.c +197 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lz4.c +700 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lzop.c +478 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_format_all.c → libarchive-3.6.2/libarchive/archive_write_add_filter_none.c} +11 -11
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_program.c +391 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_uuencode.c +295 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_xz.c +545 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_zstd.c +418 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_disk_posix.c +4711 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_private.h +9 -2
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_set_standard_lookup.c +30 -29
- data/ext/libarchive-3.6.2/libarchive/archive_write_disk_windows.c +2842 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_fd.c +15 -10
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_file.c +15 -9
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_filename.c +128 -20
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_memory.c +7 -18
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_private.h +72 -29
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format.c +56 -3
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_7zip.c +2322 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ar.c +54 -34
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_by_name.c +20 -2
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio.c +11 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_binary.c +610 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_newc.c +457 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_odc.c +500 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_filter_by_ext.c +142 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_gnutar.c +755 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_iso9660.c +8165 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_mtree.c +2217 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_pax.c +1049 -387
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_private.h +42 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_raw.c +125 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_shar.c +62 -47
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ustar.c +279 -108
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_v7tar.c +638 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_warc.c +453 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_xar.c +3259 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_zip.c +1704 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_options.c +130 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_passphrase.c +95 -0
- data/ext/libarchive-3.6.2/libarchive/archive_xxhash.h +48 -0
- data/ext/libarchive-3.6.2/libarchive/config_freebsd.h +271 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/filter_fork.h +10 -5
- data/ext/{libarchive-2.8.4/libarchive/filter_fork.c → libarchive-3.6.2/libarchive/filter_fork_posix.c} +98 -19
- data/ext/libarchive-3.6.2/libarchive/filter_fork_windows.c +236 -0
- data/ext/libarchive-3.6.2/libarchive/xxhash.c +525 -0
- data/ext/libarchive-static-makefile +144 -80
- data/ext/libarchive-static-wrapper-makefile +1 -1
- data/ext/zlib-1.2.13/Makefile.in +404 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/adler32.c +51 -34
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/compress.c +27 -21
- data/ext/zlib-1.2.13/configure +922 -0
- data/ext/zlib-1.2.13/crc32.c +1125 -0
- data/ext/zlib-1.2.13/crc32.h +9446 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.c +842 -459
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.h +37 -33
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzclose.c +0 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzguts.h +103 -16
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzlib.c +155 -53
- data/ext/zlib-1.2.13/gzread.c +650 -0
- data/ext/zlib-1.2.13/gzwrite.c +677 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/infback.c +24 -12
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.c +49 -66
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.h +0 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffixed.h +3 -3
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.c +209 -94
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.h +9 -5
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.c +24 -50
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.h +1 -1
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.c +135 -198
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.h +0 -0
- data/ext/zlib-1.2.13/uncompr.c +93 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zconf.h +182 -63
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zlib.h +617 -295
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.c +50 -41
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.h +83 -82
- metadata +241 -133
- data/ext/libarchive-0.1.1/libarchive.c +0 -1762
- data/ext/libarchive-2.8.4/Makefile.in +0 -7076
- data/ext/libarchive-2.8.4/build/autoconf/compile +0 -143
- data/ext/libarchive-2.8.4/build/autoconf/config.guess +0 -1502
- data/ext/libarchive-2.8.4/build/autoconf/config.sub +0 -1708
- data/ext/libarchive-2.8.4/build/autoconf/depcomp +0 -630
- data/ext/libarchive-2.8.4/build/autoconf/install-sh +0 -291
- data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +0 -8406
- data/ext/libarchive-2.8.4/build/autoconf/missing +0 -376
- data/ext/libarchive-2.8.4/config.h.in +0 -772
- data/ext/libarchive-2.8.4/configure +0 -17916
- data/ext/libarchive-2.8.4/libarchive/archive.h +0 -741
- data/ext/libarchive-2.8.4/libarchive/archive_entry.c +0 -2202
- data/ext/libarchive-2.8.4/libarchive/archive_hash.h +0 -281
- data/ext/libarchive-2.8.4/libarchive/archive_read.c +0 -1249
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +0 -198
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +0 -570
- data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +0 -272
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +0 -777
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +0 -1304
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +0 -903
- data/ext/libarchive-2.8.4/libarchive/archive_string.c +0 -453
- data/ext/libarchive-2.8.4/libarchive/archive_string.h +0 -148
- data/ext/libarchive-2.8.4/libarchive/archive_util.c +0 -391
- data/ext/libarchive-2.8.4/libarchive/archive_write.c +0 -466
- data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +0 -2628
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +0 -408
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +0 -477
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +0 -257
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +0 -347
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +0 -438
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +0 -344
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +0 -295
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +0 -1050
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +0 -667
- data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +0 -154
- data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +0 -113
- data/ext/zlib-1.2.5/Makefile.in +0 -257
- data/ext/zlib-1.2.5/configure +0 -596
- data/ext/zlib-1.2.5/crc32.c +0 -442
- data/ext/zlib-1.2.5/crc32.h +0 -441
- data/ext/zlib-1.2.5/example.c +0 -565
- data/ext/zlib-1.2.5/gzread.c +0 -653
- data/ext/zlib-1.2.5/gzwrite.c +0 -531
- data/ext/zlib-1.2.5/minigzip.c +0 -440
- data/ext/zlib-1.2.5/uncompr.c +0 -59
|
@@ -0,0 +1,1704 @@
|
|
|
1
|
+
/*-
|
|
2
|
+
* Copyright (c) 2008 Anselm Strauss
|
|
3
|
+
* Copyright (c) 2009 Joerg Sonnenberger
|
|
4
|
+
* Copyright (c) 2011-2012,2014 Michihiro NAKAJIMA
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
*
|
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
|
8
|
+
* modification, are permitted provided that the following conditions
|
|
9
|
+
* are met:
|
|
10
|
+
* 1. Redistributions of source code must retain the above copyright
|
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
|
12
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
|
13
|
+
* notice, this list of conditions and the following disclaimer in the
|
|
14
|
+
* documentation and/or other materials provided with the distribution.
|
|
15
|
+
*
|
|
16
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
|
17
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
18
|
+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
19
|
+
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
20
|
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
21
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
22
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
23
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
24
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
25
|
+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* Development supported by Google Summer of Code 2008.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
#include "archive_platform.h"
|
|
33
|
+
__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 2009-12-29 06:15:32Z kientzle $");
|
|
34
|
+
|
|
35
|
+
#ifdef HAVE_ERRNO_H
|
|
36
|
+
#include <errno.h>
|
|
37
|
+
#endif
|
|
38
|
+
#ifdef HAVE_LANGINFO_H
|
|
39
|
+
#include <langinfo.h>
|
|
40
|
+
#endif
|
|
41
|
+
#ifdef HAVE_STDLIB_H
|
|
42
|
+
#include <stdlib.h>
|
|
43
|
+
#endif
|
|
44
|
+
#ifdef HAVE_STRING_H
|
|
45
|
+
#include <string.h>
|
|
46
|
+
#endif
|
|
47
|
+
#ifdef HAVE_ZLIB_H
|
|
48
|
+
#include <zlib.h>
|
|
49
|
+
#endif
|
|
50
|
+
|
|
51
|
+
#include "archive.h"
|
|
52
|
+
#include "archive_cryptor_private.h"
|
|
53
|
+
#include "archive_endian.h"
|
|
54
|
+
#include "archive_entry.h"
|
|
55
|
+
#include "archive_entry_locale.h"
|
|
56
|
+
#include "archive_hmac_private.h"
|
|
57
|
+
#include "archive_private.h"
|
|
58
|
+
#include "archive_random_private.h"
|
|
59
|
+
#include "archive_write_private.h"
|
|
60
|
+
#include "archive_write_set_format_private.h"
|
|
61
|
+
|
|
62
|
+
#ifndef HAVE_ZLIB_H
|
|
63
|
+
#include "archive_crc32.h"
|
|
64
|
+
#endif
|
|
65
|
+
|
|
66
|
+
#define ZIP_ENTRY_FLAG_ENCRYPTED (1<<0)
|
|
67
|
+
#define ZIP_ENTRY_FLAG_LENGTH_AT_END (1<<3)
|
|
68
|
+
#define ZIP_ENTRY_FLAG_UTF8_NAME (1 << 11)
|
|
69
|
+
|
|
70
|
+
#define ZIP_4GB_MAX ARCHIVE_LITERAL_LL(0xffffffff)
|
|
71
|
+
#define ZIP_4GB_MAX_UNCOMPRESSED ARCHIVE_LITERAL_LL(0xff000000)
|
|
72
|
+
|
|
73
|
+
enum compression {
|
|
74
|
+
COMPRESSION_UNSPECIFIED = -1,
|
|
75
|
+
COMPRESSION_STORE = 0,
|
|
76
|
+
COMPRESSION_DEFLATE = 8
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
#ifdef HAVE_ZLIB_H
|
|
80
|
+
#define COMPRESSION_DEFAULT COMPRESSION_DEFLATE
|
|
81
|
+
#else
|
|
82
|
+
#define COMPRESSION_DEFAULT COMPRESSION_STORE
|
|
83
|
+
#endif
|
|
84
|
+
|
|
85
|
+
enum encryption {
|
|
86
|
+
ENCRYPTION_NONE = 0,
|
|
87
|
+
ENCRYPTION_TRADITIONAL, /* Traditional PKWARE encryption. */
|
|
88
|
+
ENCRYPTION_WINZIP_AES128, /* WinZIP AES-128 encryption. */
|
|
89
|
+
ENCRYPTION_WINZIP_AES256, /* WinZIP AES-256 encryption. */
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
#define TRAD_HEADER_SIZE 12
|
|
93
|
+
/*
|
|
94
|
+
* See "WinZip - AES Encryption Information"
|
|
95
|
+
* http://www.winzip.com/aes_info.htm
|
|
96
|
+
*/
|
|
97
|
+
/* Value used in compression method. */
|
|
98
|
+
#define WINZIP_AES_ENCRYPTION 99
|
|
99
|
+
/* A WinZip AES header size which is stored at the beginning of
|
|
100
|
+
* file contents. */
|
|
101
|
+
#define WINZIP_AES128_HEADER_SIZE (8 + 2)
|
|
102
|
+
#define WINZIP_AES256_HEADER_SIZE (16 + 2)
|
|
103
|
+
/* AES vendor version. */
|
|
104
|
+
#define AES_VENDOR_AE_1 0x0001
|
|
105
|
+
#define AES_VENDOR_AE_2 0x0002
|
|
106
|
+
/* Authentication code size. */
|
|
107
|
+
#define AUTH_CODE_SIZE 10
|
|
108
|
+
/**/
|
|
109
|
+
#define MAX_DERIVED_KEY_BUF_SIZE (AES_MAX_KEY_SIZE * 2 + 2)
|
|
110
|
+
|
|
111
|
+
struct cd_segment {
|
|
112
|
+
struct cd_segment *next;
|
|
113
|
+
size_t buff_size;
|
|
114
|
+
unsigned char *buff;
|
|
115
|
+
unsigned char *p;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
struct trad_enc_ctx {
|
|
119
|
+
uint32_t keys[3];
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
struct zip {
|
|
123
|
+
|
|
124
|
+
int64_t entry_offset;
|
|
125
|
+
int64_t entry_compressed_size;
|
|
126
|
+
int64_t entry_uncompressed_size;
|
|
127
|
+
int64_t entry_compressed_written;
|
|
128
|
+
int64_t entry_uncompressed_written;
|
|
129
|
+
int64_t entry_uncompressed_limit;
|
|
130
|
+
struct archive_entry *entry;
|
|
131
|
+
uint32_t entry_crc32;
|
|
132
|
+
enum compression entry_compression;
|
|
133
|
+
enum encryption entry_encryption;
|
|
134
|
+
int entry_flags;
|
|
135
|
+
int entry_uses_zip64;
|
|
136
|
+
int experiments;
|
|
137
|
+
struct trad_enc_ctx tctx;
|
|
138
|
+
char tctx_valid;
|
|
139
|
+
unsigned char trad_chkdat;
|
|
140
|
+
unsigned aes_vendor;
|
|
141
|
+
archive_crypto_ctx cctx;
|
|
142
|
+
char cctx_valid;
|
|
143
|
+
archive_hmac_sha1_ctx hctx;
|
|
144
|
+
char hctx_valid;
|
|
145
|
+
|
|
146
|
+
unsigned char *file_header;
|
|
147
|
+
size_t file_header_extra_offset;
|
|
148
|
+
unsigned long (*crc32func)(unsigned long crc, const void *buff, size_t len);
|
|
149
|
+
|
|
150
|
+
struct cd_segment *central_directory;
|
|
151
|
+
struct cd_segment *central_directory_last;
|
|
152
|
+
size_t central_directory_bytes;
|
|
153
|
+
size_t central_directory_entries;
|
|
154
|
+
|
|
155
|
+
int64_t written_bytes; /* Overall position in file. */
|
|
156
|
+
|
|
157
|
+
struct archive_string_conv *opt_sconv;
|
|
158
|
+
struct archive_string_conv *sconv_default;
|
|
159
|
+
enum compression requested_compression;
|
|
160
|
+
int deflate_compression_level;
|
|
161
|
+
int init_default_conversion;
|
|
162
|
+
enum encryption encryption_type;
|
|
163
|
+
|
|
164
|
+
#define ZIP_FLAG_AVOID_ZIP64 1
|
|
165
|
+
#define ZIP_FLAG_FORCE_ZIP64 2
|
|
166
|
+
#define ZIP_FLAG_EXPERIMENT_xl 4
|
|
167
|
+
int flags;
|
|
168
|
+
|
|
169
|
+
#ifdef HAVE_ZLIB_H
|
|
170
|
+
z_stream stream;
|
|
171
|
+
#endif
|
|
172
|
+
size_t len_buf;
|
|
173
|
+
unsigned char *buf;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/* Don't call this min or MIN, since those are already defined
|
|
177
|
+
on lots of platforms (but not all). */
|
|
178
|
+
#define zipmin(a, b) ((a) > (b) ? (b) : (a))
|
|
179
|
+
|
|
180
|
+
static ssize_t archive_write_zip_data(struct archive_write *,
|
|
181
|
+
const void *buff, size_t s);
|
|
182
|
+
static int archive_write_zip_close(struct archive_write *);
|
|
183
|
+
static int archive_write_zip_free(struct archive_write *);
|
|
184
|
+
static int archive_write_zip_finish_entry(struct archive_write *);
|
|
185
|
+
static int archive_write_zip_header(struct archive_write *,
|
|
186
|
+
struct archive_entry *);
|
|
187
|
+
static int archive_write_zip_options(struct archive_write *,
|
|
188
|
+
const char *, const char *);
|
|
189
|
+
static unsigned int dos_time(const time_t);
|
|
190
|
+
static size_t path_length(struct archive_entry *);
|
|
191
|
+
static int write_path(struct archive_entry *, struct archive_write *);
|
|
192
|
+
static void copy_path(struct archive_entry *, unsigned char *);
|
|
193
|
+
static struct archive_string_conv *get_sconv(struct archive_write *, struct zip *);
|
|
194
|
+
static int trad_enc_init(struct trad_enc_ctx *, const char *, size_t);
|
|
195
|
+
static unsigned trad_enc_encrypt_update(struct trad_enc_ctx *, const uint8_t *,
|
|
196
|
+
size_t, uint8_t *, size_t);
|
|
197
|
+
static int init_traditional_pkware_encryption(struct archive_write *);
|
|
198
|
+
static int is_traditional_pkware_encryption_supported(void);
|
|
199
|
+
static int init_winzip_aes_encryption(struct archive_write *);
|
|
200
|
+
static int is_winzip_aes_encryption_supported(int encryption);
|
|
201
|
+
|
|
202
|
+
static unsigned char *
|
|
203
|
+
cd_alloc(struct zip *zip, size_t length)
|
|
204
|
+
{
|
|
205
|
+
unsigned char *p;
|
|
206
|
+
|
|
207
|
+
if (zip->central_directory == NULL
|
|
208
|
+
|| (zip->central_directory_last->p + length
|
|
209
|
+
> zip->central_directory_last->buff + zip->central_directory_last->buff_size)) {
|
|
210
|
+
struct cd_segment *segment = calloc(1, sizeof(*segment));
|
|
211
|
+
if (segment == NULL)
|
|
212
|
+
return NULL;
|
|
213
|
+
segment->buff_size = 64 * 1024;
|
|
214
|
+
segment->buff = malloc(segment->buff_size);
|
|
215
|
+
if (segment->buff == NULL) {
|
|
216
|
+
free(segment);
|
|
217
|
+
return NULL;
|
|
218
|
+
}
|
|
219
|
+
segment->p = segment->buff;
|
|
220
|
+
|
|
221
|
+
if (zip->central_directory == NULL) {
|
|
222
|
+
zip->central_directory
|
|
223
|
+
= zip->central_directory_last
|
|
224
|
+
= segment;
|
|
225
|
+
} else {
|
|
226
|
+
zip->central_directory_last->next = segment;
|
|
227
|
+
zip->central_directory_last = segment;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
p = zip->central_directory_last->p;
|
|
232
|
+
zip->central_directory_last->p += length;
|
|
233
|
+
zip->central_directory_bytes += length;
|
|
234
|
+
return (p);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
static unsigned long
|
|
238
|
+
real_crc32(unsigned long crc, const void *buff, size_t len)
|
|
239
|
+
{
|
|
240
|
+
return crc32(crc, buff, (unsigned int)len);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
static unsigned long
|
|
244
|
+
fake_crc32(unsigned long crc, const void *buff, size_t len)
|
|
245
|
+
{
|
|
246
|
+
(void)crc; /* UNUSED */
|
|
247
|
+
(void)buff; /* UNUSED */
|
|
248
|
+
(void)len; /* UNUSED */
|
|
249
|
+
return 0;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
static int
|
|
253
|
+
archive_write_zip_options(struct archive_write *a, const char *key,
|
|
254
|
+
const char *val)
|
|
255
|
+
{
|
|
256
|
+
struct zip *zip = a->format_data;
|
|
257
|
+
int ret = ARCHIVE_FAILED;
|
|
258
|
+
|
|
259
|
+
if (strcmp(key, "compression") == 0) {
|
|
260
|
+
/*
|
|
261
|
+
* Set compression to use on all future entries.
|
|
262
|
+
* This only affects regular files.
|
|
263
|
+
*/
|
|
264
|
+
if (val == NULL || val[0] == 0) {
|
|
265
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
266
|
+
"%s: compression option needs a compression name",
|
|
267
|
+
a->format_name);
|
|
268
|
+
} else if (strcmp(val, "deflate") == 0) {
|
|
269
|
+
#ifdef HAVE_ZLIB_H
|
|
270
|
+
zip->requested_compression = COMPRESSION_DEFLATE;
|
|
271
|
+
ret = ARCHIVE_OK;
|
|
272
|
+
#else
|
|
273
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
274
|
+
"deflate compression not supported");
|
|
275
|
+
#endif
|
|
276
|
+
} else if (strcmp(val, "store") == 0) {
|
|
277
|
+
zip->requested_compression = COMPRESSION_STORE;
|
|
278
|
+
ret = ARCHIVE_OK;
|
|
279
|
+
}
|
|
280
|
+
return (ret);
|
|
281
|
+
} else if (strcmp(key, "compression-level") == 0) {
|
|
282
|
+
if (val == NULL || !(val[0] >= '0' && val[0] <= '9') || val[1] != '\0') {
|
|
283
|
+
return ARCHIVE_WARN;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (val[0] == '0') {
|
|
287
|
+
zip->requested_compression = COMPRESSION_STORE;
|
|
288
|
+
return ARCHIVE_OK;
|
|
289
|
+
} else {
|
|
290
|
+
#ifdef HAVE_ZLIB_H
|
|
291
|
+
zip->requested_compression = COMPRESSION_DEFLATE;
|
|
292
|
+
zip->deflate_compression_level = val[0] - '0';
|
|
293
|
+
return ARCHIVE_OK;
|
|
294
|
+
#else
|
|
295
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
296
|
+
"deflate compression not supported");
|
|
297
|
+
#endif
|
|
298
|
+
}
|
|
299
|
+
} else if (strcmp(key, "encryption") == 0) {
|
|
300
|
+
if (val == NULL) {
|
|
301
|
+
zip->encryption_type = ENCRYPTION_NONE;
|
|
302
|
+
ret = ARCHIVE_OK;
|
|
303
|
+
} else if (val[0] == '1' || strcmp(val, "traditional") == 0
|
|
304
|
+
|| strcmp(val, "zipcrypt") == 0
|
|
305
|
+
|| strcmp(val, "ZipCrypt") == 0) {
|
|
306
|
+
if (is_traditional_pkware_encryption_supported()) {
|
|
307
|
+
zip->encryption_type = ENCRYPTION_TRADITIONAL;
|
|
308
|
+
ret = ARCHIVE_OK;
|
|
309
|
+
} else {
|
|
310
|
+
archive_set_error(&a->archive,
|
|
311
|
+
ARCHIVE_ERRNO_MISC,
|
|
312
|
+
"encryption not supported");
|
|
313
|
+
}
|
|
314
|
+
} else if (strcmp(val, "aes128") == 0) {
|
|
315
|
+
if (is_winzip_aes_encryption_supported(
|
|
316
|
+
ENCRYPTION_WINZIP_AES128)) {
|
|
317
|
+
zip->encryption_type = ENCRYPTION_WINZIP_AES128;
|
|
318
|
+
ret = ARCHIVE_OK;
|
|
319
|
+
} else {
|
|
320
|
+
archive_set_error(&a->archive,
|
|
321
|
+
ARCHIVE_ERRNO_MISC,
|
|
322
|
+
"encryption not supported");
|
|
323
|
+
}
|
|
324
|
+
} else if (strcmp(val, "aes256") == 0) {
|
|
325
|
+
if (is_winzip_aes_encryption_supported(
|
|
326
|
+
ENCRYPTION_WINZIP_AES256)) {
|
|
327
|
+
zip->encryption_type = ENCRYPTION_WINZIP_AES256;
|
|
328
|
+
ret = ARCHIVE_OK;
|
|
329
|
+
} else {
|
|
330
|
+
archive_set_error(&a->archive,
|
|
331
|
+
ARCHIVE_ERRNO_MISC,
|
|
332
|
+
"encryption not supported");
|
|
333
|
+
}
|
|
334
|
+
} else {
|
|
335
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
336
|
+
"%s: unknown encryption '%s'",
|
|
337
|
+
a->format_name, val);
|
|
338
|
+
}
|
|
339
|
+
return (ret);
|
|
340
|
+
} else if (strcmp(key, "experimental") == 0) {
|
|
341
|
+
if (val == NULL || val[0] == 0) {
|
|
342
|
+
zip->flags &= ~ ZIP_FLAG_EXPERIMENT_xl;
|
|
343
|
+
} else {
|
|
344
|
+
zip->flags |= ZIP_FLAG_EXPERIMENT_xl;
|
|
345
|
+
}
|
|
346
|
+
return (ARCHIVE_OK);
|
|
347
|
+
} else if (strcmp(key, "fakecrc32") == 0) {
|
|
348
|
+
/*
|
|
349
|
+
* FOR TESTING ONLY: disable CRC calculation to speed up
|
|
350
|
+
* certain complex tests.
|
|
351
|
+
*/
|
|
352
|
+
if (val == NULL || val[0] == 0) {
|
|
353
|
+
zip->crc32func = real_crc32;
|
|
354
|
+
} else {
|
|
355
|
+
zip->crc32func = fake_crc32;
|
|
356
|
+
}
|
|
357
|
+
return (ARCHIVE_OK);
|
|
358
|
+
} else if (strcmp(key, "hdrcharset") == 0) {
|
|
359
|
+
/*
|
|
360
|
+
* Set the character set used in translating filenames.
|
|
361
|
+
*/
|
|
362
|
+
if (val == NULL || val[0] == 0) {
|
|
363
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
364
|
+
"%s: hdrcharset option needs a character-set name",
|
|
365
|
+
a->format_name);
|
|
366
|
+
} else {
|
|
367
|
+
zip->opt_sconv = archive_string_conversion_to_charset(
|
|
368
|
+
&a->archive, val, 0);
|
|
369
|
+
if (zip->opt_sconv != NULL)
|
|
370
|
+
ret = ARCHIVE_OK;
|
|
371
|
+
else
|
|
372
|
+
ret = ARCHIVE_FATAL;
|
|
373
|
+
}
|
|
374
|
+
return (ret);
|
|
375
|
+
} else if (strcmp(key, "zip64") == 0) {
|
|
376
|
+
/*
|
|
377
|
+
* Bias decisions about Zip64: force them to be
|
|
378
|
+
* generated in certain cases where they are not
|
|
379
|
+
* forbidden or avoid them in certain cases where they
|
|
380
|
+
* are not strictly required.
|
|
381
|
+
*/
|
|
382
|
+
if (val != NULL && *val != '\0') {
|
|
383
|
+
zip->flags |= ZIP_FLAG_FORCE_ZIP64;
|
|
384
|
+
zip->flags &= ~ZIP_FLAG_AVOID_ZIP64;
|
|
385
|
+
} else {
|
|
386
|
+
zip->flags &= ~ZIP_FLAG_FORCE_ZIP64;
|
|
387
|
+
zip->flags |= ZIP_FLAG_AVOID_ZIP64;
|
|
388
|
+
}
|
|
389
|
+
return (ARCHIVE_OK);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* Note: The "warn" return is just to inform the options
|
|
393
|
+
* supervisor that we didn't handle it. It will generate
|
|
394
|
+
* a suitable error if no one used this option. */
|
|
395
|
+
return (ARCHIVE_WARN);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
int
|
|
399
|
+
archive_write_zip_set_compression_deflate(struct archive *_a)
|
|
400
|
+
{
|
|
401
|
+
struct archive_write *a = (struct archive_write *)_a;
|
|
402
|
+
int ret = ARCHIVE_FAILED;
|
|
403
|
+
|
|
404
|
+
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
|
|
405
|
+
ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
|
|
406
|
+
"archive_write_zip_set_compression_deflate");
|
|
407
|
+
if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) {
|
|
408
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
409
|
+
"Can only use archive_write_zip_set_compression_deflate"
|
|
410
|
+
" with zip format");
|
|
411
|
+
ret = ARCHIVE_FATAL;
|
|
412
|
+
} else {
|
|
413
|
+
#ifdef HAVE_ZLIB_H
|
|
414
|
+
struct zip *zip = a->format_data;
|
|
415
|
+
zip->requested_compression = COMPRESSION_DEFLATE;
|
|
416
|
+
ret = ARCHIVE_OK;
|
|
417
|
+
#else
|
|
418
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
419
|
+
"deflate compression not supported");
|
|
420
|
+
ret = ARCHIVE_FAILED;
|
|
421
|
+
#endif
|
|
422
|
+
}
|
|
423
|
+
return (ret);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
int
|
|
427
|
+
archive_write_zip_set_compression_store(struct archive *_a)
|
|
428
|
+
{
|
|
429
|
+
struct archive_write *a = (struct archive_write *)_a;
|
|
430
|
+
struct zip *zip = a->format_data;
|
|
431
|
+
int ret = ARCHIVE_FAILED;
|
|
432
|
+
|
|
433
|
+
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
|
|
434
|
+
ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
|
|
435
|
+
"archive_write_zip_set_compression_deflate");
|
|
436
|
+
if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) {
|
|
437
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
438
|
+
"Can only use archive_write_zip_set_compression_store"
|
|
439
|
+
" with zip format");
|
|
440
|
+
ret = ARCHIVE_FATAL;
|
|
441
|
+
} else {
|
|
442
|
+
zip->requested_compression = COMPRESSION_STORE;
|
|
443
|
+
ret = ARCHIVE_OK;
|
|
444
|
+
}
|
|
445
|
+
return (ret);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
int
|
|
449
|
+
archive_write_set_format_zip(struct archive *_a)
|
|
450
|
+
{
|
|
451
|
+
struct archive_write *a = (struct archive_write *)_a;
|
|
452
|
+
struct zip *zip;
|
|
453
|
+
|
|
454
|
+
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
|
|
455
|
+
ARCHIVE_STATE_NEW, "archive_write_set_format_zip");
|
|
456
|
+
|
|
457
|
+
/* If another format was already registered, unregister it. */
|
|
458
|
+
if (a->format_free != NULL)
|
|
459
|
+
(a->format_free)(a);
|
|
460
|
+
|
|
461
|
+
zip = (struct zip *) calloc(1, sizeof(*zip));
|
|
462
|
+
if (zip == NULL) {
|
|
463
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
464
|
+
"Can't allocate zip data");
|
|
465
|
+
return (ARCHIVE_FATAL);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/* "Unspecified" lets us choose the appropriate compression. */
|
|
469
|
+
zip->requested_compression = COMPRESSION_UNSPECIFIED;
|
|
470
|
+
#ifdef HAVE_ZLIB_H
|
|
471
|
+
zip->deflate_compression_level = Z_DEFAULT_COMPRESSION;
|
|
472
|
+
#endif
|
|
473
|
+
zip->crc32func = real_crc32;
|
|
474
|
+
|
|
475
|
+
/* A buffer used for both compression and encryption. */
|
|
476
|
+
zip->len_buf = 65536;
|
|
477
|
+
zip->buf = malloc(zip->len_buf);
|
|
478
|
+
if (zip->buf == NULL) {
|
|
479
|
+
free(zip);
|
|
480
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
481
|
+
"Can't allocate compression buffer");
|
|
482
|
+
return (ARCHIVE_FATAL);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
a->format_data = zip;
|
|
486
|
+
a->format_name = "zip";
|
|
487
|
+
a->format_options = archive_write_zip_options;
|
|
488
|
+
a->format_write_header = archive_write_zip_header;
|
|
489
|
+
a->format_write_data = archive_write_zip_data;
|
|
490
|
+
a->format_finish_entry = archive_write_zip_finish_entry;
|
|
491
|
+
a->format_close = archive_write_zip_close;
|
|
492
|
+
a->format_free = archive_write_zip_free;
|
|
493
|
+
a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
|
|
494
|
+
a->archive.archive_format_name = "ZIP";
|
|
495
|
+
|
|
496
|
+
return (ARCHIVE_OK);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
static int
|
|
500
|
+
is_all_ascii(const char *p)
|
|
501
|
+
{
|
|
502
|
+
const unsigned char *pp = (const unsigned char *)p;
|
|
503
|
+
|
|
504
|
+
while (*pp) {
|
|
505
|
+
if (*pp++ > 127)
|
|
506
|
+
return (0);
|
|
507
|
+
}
|
|
508
|
+
return (1);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
static int
|
|
512
|
+
archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
|
513
|
+
{
|
|
514
|
+
unsigned char local_header[32];
|
|
515
|
+
unsigned char local_extra[144];
|
|
516
|
+
struct zip *zip = a->format_data;
|
|
517
|
+
unsigned char *e;
|
|
518
|
+
unsigned char *cd_extra;
|
|
519
|
+
size_t filename_length;
|
|
520
|
+
const char *slink = NULL;
|
|
521
|
+
size_t slink_size = 0;
|
|
522
|
+
struct archive_string_conv *sconv = get_sconv(a, zip);
|
|
523
|
+
int ret, ret2 = ARCHIVE_OK;
|
|
524
|
+
mode_t type;
|
|
525
|
+
int version_needed = 10;
|
|
526
|
+
|
|
527
|
+
/* Ignore types of entries that we don't support. */
|
|
528
|
+
type = archive_entry_filetype(entry);
|
|
529
|
+
if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
|
|
530
|
+
__archive_write_entry_filetype_unsupported(
|
|
531
|
+
&a->archive, entry, "zip");
|
|
532
|
+
return ARCHIVE_FAILED;
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
/* If we're not using Zip64, reject large files. */
|
|
536
|
+
if (zip->flags & ZIP_FLAG_AVOID_ZIP64) {
|
|
537
|
+
/* Reject entries over 4GB. */
|
|
538
|
+
if (archive_entry_size_is_set(entry)
|
|
539
|
+
&& (archive_entry_size(entry) > ZIP_4GB_MAX)) {
|
|
540
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
541
|
+
"Files > 4GB require Zip64 extensions");
|
|
542
|
+
return ARCHIVE_FAILED;
|
|
543
|
+
}
|
|
544
|
+
/* Reject entries if archive is > 4GB. */
|
|
545
|
+
if (zip->written_bytes > ZIP_4GB_MAX) {
|
|
546
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
547
|
+
"Archives > 4GB require Zip64 extensions");
|
|
548
|
+
return ARCHIVE_FAILED;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/* Only regular files can have size > 0. */
|
|
553
|
+
if (type != AE_IFREG)
|
|
554
|
+
archive_entry_set_size(entry, 0);
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
/* Reset information from last entry. */
|
|
558
|
+
zip->entry_offset = zip->written_bytes;
|
|
559
|
+
zip->entry_uncompressed_limit = INT64_MAX;
|
|
560
|
+
zip->entry_compressed_size = 0;
|
|
561
|
+
zip->entry_uncompressed_size = 0;
|
|
562
|
+
zip->entry_compressed_written = 0;
|
|
563
|
+
zip->entry_uncompressed_written = 0;
|
|
564
|
+
zip->entry_flags = 0;
|
|
565
|
+
zip->entry_uses_zip64 = 0;
|
|
566
|
+
zip->entry_crc32 = zip->crc32func(0, NULL, 0);
|
|
567
|
+
zip->entry_encryption = 0;
|
|
568
|
+
archive_entry_free(zip->entry);
|
|
569
|
+
zip->entry = NULL;
|
|
570
|
+
|
|
571
|
+
if (zip->cctx_valid)
|
|
572
|
+
archive_encrypto_aes_ctr_release(&zip->cctx);
|
|
573
|
+
if (zip->hctx_valid)
|
|
574
|
+
archive_hmac_sha1_cleanup(&zip->hctx);
|
|
575
|
+
zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
|
|
576
|
+
|
|
577
|
+
if (type == AE_IFREG
|
|
578
|
+
&&(!archive_entry_size_is_set(entry)
|
|
579
|
+
|| archive_entry_size(entry) > 0)) {
|
|
580
|
+
switch (zip->encryption_type) {
|
|
581
|
+
case ENCRYPTION_TRADITIONAL:
|
|
582
|
+
case ENCRYPTION_WINZIP_AES128:
|
|
583
|
+
case ENCRYPTION_WINZIP_AES256:
|
|
584
|
+
zip->entry_flags |= ZIP_ENTRY_FLAG_ENCRYPTED;
|
|
585
|
+
zip->entry_encryption = zip->encryption_type;
|
|
586
|
+
break;
|
|
587
|
+
case ENCRYPTION_NONE:
|
|
588
|
+
default:
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
595
|
+
/* Make sure the path separators in pathname, hardlink and symlink
|
|
596
|
+
* are all slash '/', not the Windows path separator '\'. */
|
|
597
|
+
zip->entry = __la_win_entry_in_posix_pathseparator(entry);
|
|
598
|
+
if (zip->entry == entry)
|
|
599
|
+
zip->entry = archive_entry_clone(entry);
|
|
600
|
+
#else
|
|
601
|
+
zip->entry = archive_entry_clone(entry);
|
|
602
|
+
#endif
|
|
603
|
+
if (zip->entry == NULL) {
|
|
604
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
605
|
+
"Can't allocate zip header data");
|
|
606
|
+
return (ARCHIVE_FATAL);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
if (sconv != NULL) {
|
|
610
|
+
const char *p;
|
|
611
|
+
size_t len;
|
|
612
|
+
|
|
613
|
+
if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) {
|
|
614
|
+
if (errno == ENOMEM) {
|
|
615
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
616
|
+
"Can't allocate memory for Pathname");
|
|
617
|
+
return (ARCHIVE_FATAL);
|
|
618
|
+
}
|
|
619
|
+
archive_set_error(&a->archive,
|
|
620
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
621
|
+
"Can't translate Pathname '%s' to %s",
|
|
622
|
+
archive_entry_pathname(entry),
|
|
623
|
+
archive_string_conversion_charset_name(sconv));
|
|
624
|
+
ret2 = ARCHIVE_WARN;
|
|
625
|
+
}
|
|
626
|
+
if (len > 0)
|
|
627
|
+
archive_entry_set_pathname(zip->entry, p);
|
|
628
|
+
|
|
629
|
+
/*
|
|
630
|
+
* There is no standard for symlink handling; we convert
|
|
631
|
+
* it using the same character-set translation that we use
|
|
632
|
+
* for filename.
|
|
633
|
+
*/
|
|
634
|
+
if (type == AE_IFLNK) {
|
|
635
|
+
if (archive_entry_symlink_l(entry, &p, &len, sconv)) {
|
|
636
|
+
if (errno == ENOMEM) {
|
|
637
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
638
|
+
"Can't allocate memory "
|
|
639
|
+
" for Symlink");
|
|
640
|
+
return (ARCHIVE_FATAL);
|
|
641
|
+
}
|
|
642
|
+
/* No error if we can't convert. */
|
|
643
|
+
} else if (len > 0)
|
|
644
|
+
archive_entry_set_symlink(zip->entry, p);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/* If filename isn't ASCII and we can use UTF-8, set the UTF-8 flag. */
|
|
649
|
+
if (!is_all_ascii(archive_entry_pathname(zip->entry))) {
|
|
650
|
+
if (zip->opt_sconv != NULL) {
|
|
651
|
+
if (strcmp(archive_string_conversion_charset_name(
|
|
652
|
+
zip->opt_sconv), "UTF-8") == 0)
|
|
653
|
+
zip->entry_flags |= ZIP_ENTRY_FLAG_UTF8_NAME;
|
|
654
|
+
#if HAVE_NL_LANGINFO
|
|
655
|
+
} else if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
|
|
656
|
+
zip->entry_flags |= ZIP_ENTRY_FLAG_UTF8_NAME;
|
|
657
|
+
#endif
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
filename_length = path_length(zip->entry);
|
|
661
|
+
|
|
662
|
+
/* Determine appropriate compression and size for this entry. */
|
|
663
|
+
if (type == AE_IFLNK) {
|
|
664
|
+
slink = archive_entry_symlink(zip->entry);
|
|
665
|
+
if (slink != NULL)
|
|
666
|
+
slink_size = strlen(slink);
|
|
667
|
+
else
|
|
668
|
+
slink_size = 0;
|
|
669
|
+
zip->entry_uncompressed_limit = slink_size;
|
|
670
|
+
zip->entry_compressed_size = slink_size;
|
|
671
|
+
zip->entry_uncompressed_size = slink_size;
|
|
672
|
+
zip->entry_crc32 = zip->crc32func(zip->entry_crc32,
|
|
673
|
+
(const unsigned char *)slink, slink_size);
|
|
674
|
+
zip->entry_compression = COMPRESSION_STORE;
|
|
675
|
+
version_needed = 20;
|
|
676
|
+
} else if (type != AE_IFREG) {
|
|
677
|
+
zip->entry_compression = COMPRESSION_STORE;
|
|
678
|
+
zip->entry_uncompressed_limit = 0;
|
|
679
|
+
version_needed = 20;
|
|
680
|
+
} else if (archive_entry_size_is_set(zip->entry)) {
|
|
681
|
+
int64_t size = archive_entry_size(zip->entry);
|
|
682
|
+
int64_t additional_size = 0;
|
|
683
|
+
|
|
684
|
+
zip->entry_uncompressed_limit = size;
|
|
685
|
+
zip->entry_compression = zip->requested_compression;
|
|
686
|
+
if (zip->entry_compression == COMPRESSION_UNSPECIFIED) {
|
|
687
|
+
zip->entry_compression = COMPRESSION_DEFAULT;
|
|
688
|
+
}
|
|
689
|
+
if (zip->entry_compression == COMPRESSION_STORE) {
|
|
690
|
+
zip->entry_compressed_size = size;
|
|
691
|
+
zip->entry_uncompressed_size = size;
|
|
692
|
+
version_needed = 10;
|
|
693
|
+
} else {
|
|
694
|
+
zip->entry_uncompressed_size = size;
|
|
695
|
+
version_needed = 20;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
|
|
699
|
+
switch (zip->entry_encryption) {
|
|
700
|
+
case ENCRYPTION_TRADITIONAL:
|
|
701
|
+
additional_size = TRAD_HEADER_SIZE;
|
|
702
|
+
version_needed = 20;
|
|
703
|
+
break;
|
|
704
|
+
case ENCRYPTION_WINZIP_AES128:
|
|
705
|
+
additional_size = WINZIP_AES128_HEADER_SIZE
|
|
706
|
+
+ AUTH_CODE_SIZE;
|
|
707
|
+
version_needed = 20;
|
|
708
|
+
break;
|
|
709
|
+
case ENCRYPTION_WINZIP_AES256:
|
|
710
|
+
additional_size = WINZIP_AES256_HEADER_SIZE
|
|
711
|
+
+ AUTH_CODE_SIZE;
|
|
712
|
+
version_needed = 20;
|
|
713
|
+
break;
|
|
714
|
+
case ENCRYPTION_NONE:
|
|
715
|
+
default:
|
|
716
|
+
break;
|
|
717
|
+
}
|
|
718
|
+
if (zip->entry_compression == COMPRESSION_STORE)
|
|
719
|
+
zip->entry_compressed_size += additional_size;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/*
|
|
723
|
+
* Set Zip64 extension in any of the following cases
|
|
724
|
+
* (this was suggested by discussion on info-zip-dev
|
|
725
|
+
* mailing list):
|
|
726
|
+
* = Zip64 is being forced by user
|
|
727
|
+
* = File is over 4GiB uncompressed
|
|
728
|
+
* (including encryption header, if any)
|
|
729
|
+
* = File is close to 4GiB and is being compressed
|
|
730
|
+
* (compression might make file larger)
|
|
731
|
+
*/
|
|
732
|
+
if ((zip->flags & ZIP_FLAG_FORCE_ZIP64)
|
|
733
|
+
|| (zip->entry_uncompressed_size + additional_size > ZIP_4GB_MAX)
|
|
734
|
+
|| (zip->entry_uncompressed_size > ZIP_4GB_MAX_UNCOMPRESSED
|
|
735
|
+
&& zip->entry_compression != COMPRESSION_STORE)) {
|
|
736
|
+
zip->entry_uses_zip64 = 1;
|
|
737
|
+
version_needed = 45;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/* We may know the size, but never the CRC. */
|
|
741
|
+
zip->entry_flags |= ZIP_ENTRY_FLAG_LENGTH_AT_END;
|
|
742
|
+
} else {
|
|
743
|
+
/* We don't know the size. Use the default
|
|
744
|
+
* compression unless specified otherwise.
|
|
745
|
+
* We enable Zip64 extensions unless we're told not to.
|
|
746
|
+
*/
|
|
747
|
+
|
|
748
|
+
zip->entry_compression = zip->requested_compression;
|
|
749
|
+
if(zip->entry_compression == COMPRESSION_UNSPECIFIED){
|
|
750
|
+
zip->entry_compression = COMPRESSION_DEFAULT;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
zip->entry_flags |= ZIP_ENTRY_FLAG_LENGTH_AT_END;
|
|
754
|
+
if ((zip->flags & ZIP_FLAG_AVOID_ZIP64) == 0) {
|
|
755
|
+
zip->entry_uses_zip64 = 1;
|
|
756
|
+
version_needed = 45;
|
|
757
|
+
} else if (zip->entry_compression == COMPRESSION_STORE) {
|
|
758
|
+
version_needed = 10;
|
|
759
|
+
} else {
|
|
760
|
+
version_needed = 20;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
|
|
764
|
+
switch (zip->entry_encryption) {
|
|
765
|
+
case ENCRYPTION_TRADITIONAL:
|
|
766
|
+
case ENCRYPTION_WINZIP_AES128:
|
|
767
|
+
case ENCRYPTION_WINZIP_AES256:
|
|
768
|
+
if (version_needed < 20)
|
|
769
|
+
version_needed = 20;
|
|
770
|
+
break;
|
|
771
|
+
case ENCRYPTION_NONE:
|
|
772
|
+
default:
|
|
773
|
+
break;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/* Format the local header. */
|
|
779
|
+
memset(local_header, 0, sizeof(local_header));
|
|
780
|
+
memcpy(local_header, "PK\003\004", 4);
|
|
781
|
+
archive_le16enc(local_header + 4, version_needed);
|
|
782
|
+
archive_le16enc(local_header + 6, zip->entry_flags);
|
|
783
|
+
if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
|
|
784
|
+
|| zip->entry_encryption == ENCRYPTION_WINZIP_AES256)
|
|
785
|
+
archive_le16enc(local_header + 8, WINZIP_AES_ENCRYPTION);
|
|
786
|
+
else
|
|
787
|
+
archive_le16enc(local_header + 8, zip->entry_compression);
|
|
788
|
+
archive_le32enc(local_header + 10,
|
|
789
|
+
dos_time(archive_entry_mtime(zip->entry)));
|
|
790
|
+
archive_le32enc(local_header + 14, zip->entry_crc32);
|
|
791
|
+
if (zip->entry_uses_zip64) {
|
|
792
|
+
/* Zip64 data in the local header "must" include both
|
|
793
|
+
* compressed and uncompressed sizes AND those fields
|
|
794
|
+
* are included only if these are 0xffffffff;
|
|
795
|
+
* THEREFORE these must be set this way, even if we
|
|
796
|
+
* know one of them is smaller. */
|
|
797
|
+
archive_le32enc(local_header + 18, ZIP_4GB_MAX);
|
|
798
|
+
archive_le32enc(local_header + 22, ZIP_4GB_MAX);
|
|
799
|
+
} else {
|
|
800
|
+
archive_le32enc(local_header + 18, (uint32_t)zip->entry_compressed_size);
|
|
801
|
+
archive_le32enc(local_header + 22, (uint32_t)zip->entry_uncompressed_size);
|
|
802
|
+
}
|
|
803
|
+
archive_le16enc(local_header + 26, (uint16_t)filename_length);
|
|
804
|
+
|
|
805
|
+
if (zip->entry_encryption == ENCRYPTION_TRADITIONAL) {
|
|
806
|
+
if (zip->entry_flags & ZIP_ENTRY_FLAG_LENGTH_AT_END)
|
|
807
|
+
zip->trad_chkdat = local_header[11];
|
|
808
|
+
else
|
|
809
|
+
zip->trad_chkdat = local_header[17];
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
/* Format as much of central directory file header as we can: */
|
|
813
|
+
zip->file_header = cd_alloc(zip, 46);
|
|
814
|
+
/* If (zip->file_header == NULL) XXXX */
|
|
815
|
+
++zip->central_directory_entries;
|
|
816
|
+
memset(zip->file_header, 0, 46);
|
|
817
|
+
memcpy(zip->file_header, "PK\001\002", 4);
|
|
818
|
+
/* "Made by PKZip 2.0 on Unix." */
|
|
819
|
+
archive_le16enc(zip->file_header + 4, 3 * 256 + version_needed);
|
|
820
|
+
archive_le16enc(zip->file_header + 6, version_needed);
|
|
821
|
+
archive_le16enc(zip->file_header + 8, zip->entry_flags);
|
|
822
|
+
if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
|
|
823
|
+
|| zip->entry_encryption == ENCRYPTION_WINZIP_AES256)
|
|
824
|
+
archive_le16enc(zip->file_header + 10, WINZIP_AES_ENCRYPTION);
|
|
825
|
+
else
|
|
826
|
+
archive_le16enc(zip->file_header + 10, zip->entry_compression);
|
|
827
|
+
archive_le32enc(zip->file_header + 12,
|
|
828
|
+
dos_time(archive_entry_mtime(zip->entry)));
|
|
829
|
+
archive_le16enc(zip->file_header + 28, (uint16_t)filename_length);
|
|
830
|
+
/* Following Info-Zip, store mode in the "external attributes" field. */
|
|
831
|
+
archive_le32enc(zip->file_header + 38,
|
|
832
|
+
((uint32_t)archive_entry_mode(zip->entry)) << 16);
|
|
833
|
+
e = cd_alloc(zip, filename_length);
|
|
834
|
+
/* If (e == NULL) XXXX */
|
|
835
|
+
copy_path(zip->entry, e);
|
|
836
|
+
|
|
837
|
+
/* Format extra data. */
|
|
838
|
+
memset(local_extra, 0, sizeof(local_extra));
|
|
839
|
+
e = local_extra;
|
|
840
|
+
|
|
841
|
+
/* First, extra blocks that are the same between
|
|
842
|
+
* the local file header and the central directory.
|
|
843
|
+
* We format them once and then duplicate them. */
|
|
844
|
+
|
|
845
|
+
/* UT timestamp, length depends on what timestamps are set. */
|
|
846
|
+
memcpy(e, "UT", 2);
|
|
847
|
+
archive_le16enc(e + 2,
|
|
848
|
+
1
|
|
849
|
+
+ (archive_entry_mtime_is_set(entry) ? 4 : 0)
|
|
850
|
+
+ (archive_entry_atime_is_set(entry) ? 4 : 0)
|
|
851
|
+
+ (archive_entry_ctime_is_set(entry) ? 4 : 0));
|
|
852
|
+
e += 4;
|
|
853
|
+
*e++ =
|
|
854
|
+
(archive_entry_mtime_is_set(entry) ? 1 : 0)
|
|
855
|
+
| (archive_entry_atime_is_set(entry) ? 2 : 0)
|
|
856
|
+
| (archive_entry_ctime_is_set(entry) ? 4 : 0);
|
|
857
|
+
if (archive_entry_mtime_is_set(entry)) {
|
|
858
|
+
archive_le32enc(e, (uint32_t)archive_entry_mtime(entry));
|
|
859
|
+
e += 4;
|
|
860
|
+
}
|
|
861
|
+
if (archive_entry_atime_is_set(entry)) {
|
|
862
|
+
archive_le32enc(e, (uint32_t)archive_entry_atime(entry));
|
|
863
|
+
e += 4;
|
|
864
|
+
}
|
|
865
|
+
if (archive_entry_ctime_is_set(entry)) {
|
|
866
|
+
archive_le32enc(e, (uint32_t)archive_entry_ctime(entry));
|
|
867
|
+
e += 4;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/* ux Unix extra data, length 11, version 1 */
|
|
871
|
+
/* TODO: If uid < 64k, use 2 bytes, ditto for gid. */
|
|
872
|
+
memcpy(e, "ux\013\000\001", 5);
|
|
873
|
+
e += 5;
|
|
874
|
+
*e++ = 4; /* Length of following UID */
|
|
875
|
+
archive_le32enc(e, (uint32_t)archive_entry_uid(entry));
|
|
876
|
+
e += 4;
|
|
877
|
+
*e++ = 4; /* Length of following GID */
|
|
878
|
+
archive_le32enc(e, (uint32_t)archive_entry_gid(entry));
|
|
879
|
+
e += 4;
|
|
880
|
+
|
|
881
|
+
/* AES extra data field: WinZIP AES information, ID=0x9901 */
|
|
882
|
+
if ((zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED)
|
|
883
|
+
&& (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
|
|
884
|
+
|| zip->entry_encryption == ENCRYPTION_WINZIP_AES256)) {
|
|
885
|
+
|
|
886
|
+
memcpy(e, "\001\231\007\000\001\000AE", 8);
|
|
887
|
+
/* AES vendor version AE-2 does not store a CRC.
|
|
888
|
+
* WinZip 11 uses AE-1, which does store the CRC,
|
|
889
|
+
* but it does not store the CRC when the file size
|
|
890
|
+
* is less than 20 bytes. So we simulate what
|
|
891
|
+
* WinZip 11 does.
|
|
892
|
+
* NOTE: WinZip 9.0 and 10.0 uses AE-2 by default. */
|
|
893
|
+
if (archive_entry_size_is_set(zip->entry)
|
|
894
|
+
&& archive_entry_size(zip->entry) < 20) {
|
|
895
|
+
archive_le16enc(e+4, AES_VENDOR_AE_2);
|
|
896
|
+
zip->aes_vendor = AES_VENDOR_AE_2;/* no CRC. */
|
|
897
|
+
} else
|
|
898
|
+
zip->aes_vendor = AES_VENDOR_AE_1;
|
|
899
|
+
e += 8;
|
|
900
|
+
/* AES encryption strength. */
|
|
901
|
+
*e++ = (zip->entry_encryption == ENCRYPTION_WINZIP_AES128)?1:3;
|
|
902
|
+
/* Actual compression method. */
|
|
903
|
+
archive_le16enc(e, zip->entry_compression);
|
|
904
|
+
e += 2;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/* Copy UT ,ux, and AES-extra into central directory as well. */
|
|
908
|
+
zip->file_header_extra_offset = zip->central_directory_bytes;
|
|
909
|
+
cd_extra = cd_alloc(zip, e - local_extra);
|
|
910
|
+
memcpy(cd_extra, local_extra, e - local_extra);
|
|
911
|
+
|
|
912
|
+
/*
|
|
913
|
+
* Following extra blocks vary between local header and
|
|
914
|
+
* central directory. These are the local header versions.
|
|
915
|
+
* Central directory versions get formatted in
|
|
916
|
+
* archive_write_zip_finish_entry() below.
|
|
917
|
+
*/
|
|
918
|
+
|
|
919
|
+
/* "[Zip64 entry] in the local header MUST include BOTH
|
|
920
|
+
* original [uncompressed] and compressed size fields." */
|
|
921
|
+
if (zip->entry_uses_zip64) {
|
|
922
|
+
unsigned char *zip64_start = e;
|
|
923
|
+
memcpy(e, "\001\000\020\000", 4);
|
|
924
|
+
e += 4;
|
|
925
|
+
archive_le64enc(e, zip->entry_uncompressed_size);
|
|
926
|
+
e += 8;
|
|
927
|
+
archive_le64enc(e, zip->entry_compressed_size);
|
|
928
|
+
e += 8;
|
|
929
|
+
archive_le16enc(zip64_start + 2, (uint16_t)(e - (zip64_start + 4)));
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
if (zip->flags & ZIP_FLAG_EXPERIMENT_xl) {
|
|
933
|
+
/* Experimental 'xl' extension to improve streaming. */
|
|
934
|
+
unsigned char *external_info = e;
|
|
935
|
+
int included = 7;
|
|
936
|
+
memcpy(e, "xl\000\000", 4); // 0x6c65 + 2-byte length
|
|
937
|
+
e += 4;
|
|
938
|
+
e[0] = included; /* bitmap of included fields */
|
|
939
|
+
e += 1;
|
|
940
|
+
if (included & 1) {
|
|
941
|
+
archive_le16enc(e, /* "Version created by" */
|
|
942
|
+
3 * 256 + version_needed);
|
|
943
|
+
e += 2;
|
|
944
|
+
}
|
|
945
|
+
if (included & 2) {
|
|
946
|
+
archive_le16enc(e, 0); /* internal file attributes */
|
|
947
|
+
e += 2;
|
|
948
|
+
}
|
|
949
|
+
if (included & 4) {
|
|
950
|
+
archive_le32enc(e, /* external file attributes */
|
|
951
|
+
((uint32_t)archive_entry_mode(zip->entry)) << 16);
|
|
952
|
+
e += 4;
|
|
953
|
+
}
|
|
954
|
+
if (included & 8) {
|
|
955
|
+
// Libarchive does not currently support file comments.
|
|
956
|
+
}
|
|
957
|
+
archive_le16enc(external_info + 2, (uint16_t)(e - (external_info + 4)));
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
/* Update local header with size of extra data and write it all out: */
|
|
961
|
+
archive_le16enc(local_header + 28, (uint16_t)(e - local_extra));
|
|
962
|
+
|
|
963
|
+
ret = __archive_write_output(a, local_header, 30);
|
|
964
|
+
if (ret != ARCHIVE_OK)
|
|
965
|
+
return (ARCHIVE_FATAL);
|
|
966
|
+
zip->written_bytes += 30;
|
|
967
|
+
|
|
968
|
+
ret = write_path(zip->entry, a);
|
|
969
|
+
if (ret <= ARCHIVE_OK)
|
|
970
|
+
return (ARCHIVE_FATAL);
|
|
971
|
+
zip->written_bytes += ret;
|
|
972
|
+
|
|
973
|
+
ret = __archive_write_output(a, local_extra, e - local_extra);
|
|
974
|
+
if (ret != ARCHIVE_OK)
|
|
975
|
+
return (ARCHIVE_FATAL);
|
|
976
|
+
zip->written_bytes += e - local_extra;
|
|
977
|
+
|
|
978
|
+
/* For symlinks, write the body now. */
|
|
979
|
+
if (slink != NULL) {
|
|
980
|
+
ret = __archive_write_output(a, slink, slink_size);
|
|
981
|
+
if (ret != ARCHIVE_OK)
|
|
982
|
+
return (ARCHIVE_FATAL);
|
|
983
|
+
zip->entry_compressed_written += slink_size;
|
|
984
|
+
zip->entry_uncompressed_written += slink_size;
|
|
985
|
+
zip->written_bytes += slink_size;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
#ifdef HAVE_ZLIB_H
|
|
989
|
+
if (zip->entry_compression == COMPRESSION_DEFLATE) {
|
|
990
|
+
zip->stream.zalloc = Z_NULL;
|
|
991
|
+
zip->stream.zfree = Z_NULL;
|
|
992
|
+
zip->stream.opaque = Z_NULL;
|
|
993
|
+
zip->stream.next_out = zip->buf;
|
|
994
|
+
zip->stream.avail_out = (uInt)zip->len_buf;
|
|
995
|
+
if (deflateInit2(&zip->stream, zip->deflate_compression_level,
|
|
996
|
+
Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
|
|
997
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
998
|
+
"Can't init deflate compressor");
|
|
999
|
+
return (ARCHIVE_FATAL);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
#endif
|
|
1003
|
+
|
|
1004
|
+
return (ret2);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
static ssize_t
|
|
1008
|
+
archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
|
|
1009
|
+
{
|
|
1010
|
+
int ret;
|
|
1011
|
+
struct zip *zip = a->format_data;
|
|
1012
|
+
|
|
1013
|
+
if ((int64_t)s > zip->entry_uncompressed_limit)
|
|
1014
|
+
s = (size_t)zip->entry_uncompressed_limit;
|
|
1015
|
+
zip->entry_uncompressed_written += s;
|
|
1016
|
+
|
|
1017
|
+
if (s == 0) return 0;
|
|
1018
|
+
|
|
1019
|
+
if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
|
|
1020
|
+
switch (zip->entry_encryption) {
|
|
1021
|
+
case ENCRYPTION_TRADITIONAL:
|
|
1022
|
+
/* Initialize traditional PKWARE encryption context. */
|
|
1023
|
+
if (!zip->tctx_valid) {
|
|
1024
|
+
ret = init_traditional_pkware_encryption(a);
|
|
1025
|
+
if (ret != ARCHIVE_OK)
|
|
1026
|
+
return (ret);
|
|
1027
|
+
zip->tctx_valid = 1;
|
|
1028
|
+
}
|
|
1029
|
+
break;
|
|
1030
|
+
case ENCRYPTION_WINZIP_AES128:
|
|
1031
|
+
case ENCRYPTION_WINZIP_AES256:
|
|
1032
|
+
if (!zip->cctx_valid) {
|
|
1033
|
+
ret = init_winzip_aes_encryption(a);
|
|
1034
|
+
if (ret != ARCHIVE_OK)
|
|
1035
|
+
return (ret);
|
|
1036
|
+
zip->cctx_valid = zip->hctx_valid = 1;
|
|
1037
|
+
}
|
|
1038
|
+
break;
|
|
1039
|
+
case ENCRYPTION_NONE:
|
|
1040
|
+
default:
|
|
1041
|
+
break;
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
switch (zip->entry_compression) {
|
|
1046
|
+
case COMPRESSION_STORE:
|
|
1047
|
+
if (zip->tctx_valid || zip->cctx_valid) {
|
|
1048
|
+
const uint8_t *rb = (const uint8_t *)buff;
|
|
1049
|
+
const uint8_t * const re = rb + s;
|
|
1050
|
+
|
|
1051
|
+
while (rb < re) {
|
|
1052
|
+
size_t l;
|
|
1053
|
+
|
|
1054
|
+
if (zip->tctx_valid) {
|
|
1055
|
+
l = trad_enc_encrypt_update(&zip->tctx,
|
|
1056
|
+
rb, re - rb,
|
|
1057
|
+
zip->buf, zip->len_buf);
|
|
1058
|
+
} else {
|
|
1059
|
+
l = zip->len_buf;
|
|
1060
|
+
ret = archive_encrypto_aes_ctr_update(
|
|
1061
|
+
&zip->cctx,
|
|
1062
|
+
rb, re - rb, zip->buf, &l);
|
|
1063
|
+
if (ret < 0) {
|
|
1064
|
+
archive_set_error(&a->archive,
|
|
1065
|
+
ARCHIVE_ERRNO_MISC,
|
|
1066
|
+
"Failed to encrypt file");
|
|
1067
|
+
return (ARCHIVE_FAILED);
|
|
1068
|
+
}
|
|
1069
|
+
archive_hmac_sha1_update(&zip->hctx,
|
|
1070
|
+
zip->buf, l);
|
|
1071
|
+
}
|
|
1072
|
+
ret = __archive_write_output(a, zip->buf, l);
|
|
1073
|
+
if (ret != ARCHIVE_OK)
|
|
1074
|
+
return (ret);
|
|
1075
|
+
zip->entry_compressed_written += l;
|
|
1076
|
+
zip->written_bytes += l;
|
|
1077
|
+
rb += l;
|
|
1078
|
+
}
|
|
1079
|
+
} else {
|
|
1080
|
+
ret = __archive_write_output(a, buff, s);
|
|
1081
|
+
if (ret != ARCHIVE_OK)
|
|
1082
|
+
return (ret);
|
|
1083
|
+
zip->written_bytes += s;
|
|
1084
|
+
zip->entry_compressed_written += s;
|
|
1085
|
+
}
|
|
1086
|
+
break;
|
|
1087
|
+
#if HAVE_ZLIB_H
|
|
1088
|
+
case COMPRESSION_DEFLATE:
|
|
1089
|
+
zip->stream.next_in = (unsigned char*)(uintptr_t)buff;
|
|
1090
|
+
zip->stream.avail_in = (uInt)s;
|
|
1091
|
+
do {
|
|
1092
|
+
ret = deflate(&zip->stream, Z_NO_FLUSH);
|
|
1093
|
+
if (ret == Z_STREAM_ERROR)
|
|
1094
|
+
return (ARCHIVE_FATAL);
|
|
1095
|
+
if (zip->stream.avail_out == 0) {
|
|
1096
|
+
if (zip->tctx_valid) {
|
|
1097
|
+
trad_enc_encrypt_update(&zip->tctx,
|
|
1098
|
+
zip->buf, zip->len_buf,
|
|
1099
|
+
zip->buf, zip->len_buf);
|
|
1100
|
+
} else if (zip->cctx_valid) {
|
|
1101
|
+
size_t outl = zip->len_buf;
|
|
1102
|
+
ret = archive_encrypto_aes_ctr_update(
|
|
1103
|
+
&zip->cctx,
|
|
1104
|
+
zip->buf, zip->len_buf,
|
|
1105
|
+
zip->buf, &outl);
|
|
1106
|
+
if (ret < 0) {
|
|
1107
|
+
archive_set_error(&a->archive,
|
|
1108
|
+
ARCHIVE_ERRNO_MISC,
|
|
1109
|
+
"Failed to encrypt file");
|
|
1110
|
+
return (ARCHIVE_FAILED);
|
|
1111
|
+
}
|
|
1112
|
+
archive_hmac_sha1_update(&zip->hctx,
|
|
1113
|
+
zip->buf, zip->len_buf);
|
|
1114
|
+
}
|
|
1115
|
+
ret = __archive_write_output(a, zip->buf,
|
|
1116
|
+
zip->len_buf);
|
|
1117
|
+
if (ret != ARCHIVE_OK)
|
|
1118
|
+
return (ret);
|
|
1119
|
+
zip->entry_compressed_written += zip->len_buf;
|
|
1120
|
+
zip->written_bytes += zip->len_buf;
|
|
1121
|
+
zip->stream.next_out = zip->buf;
|
|
1122
|
+
zip->stream.avail_out = (uInt)zip->len_buf;
|
|
1123
|
+
}
|
|
1124
|
+
} while (zip->stream.avail_in != 0);
|
|
1125
|
+
break;
|
|
1126
|
+
#endif
|
|
1127
|
+
|
|
1128
|
+
case COMPRESSION_UNSPECIFIED:
|
|
1129
|
+
default:
|
|
1130
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1131
|
+
"Invalid ZIP compression type");
|
|
1132
|
+
return ARCHIVE_FATAL;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
zip->entry_uncompressed_limit -= s;
|
|
1136
|
+
if (!zip->cctx_valid || zip->aes_vendor != AES_VENDOR_AE_2)
|
|
1137
|
+
zip->entry_crc32 =
|
|
1138
|
+
zip->crc32func(zip->entry_crc32, buff, (unsigned)s);
|
|
1139
|
+
return (s);
|
|
1140
|
+
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
static int
|
|
1144
|
+
archive_write_zip_finish_entry(struct archive_write *a)
|
|
1145
|
+
{
|
|
1146
|
+
struct zip *zip = a->format_data;
|
|
1147
|
+
int ret;
|
|
1148
|
+
|
|
1149
|
+
#if HAVE_ZLIB_H
|
|
1150
|
+
if (zip->entry_compression == COMPRESSION_DEFLATE) {
|
|
1151
|
+
for (;;) {
|
|
1152
|
+
size_t remainder;
|
|
1153
|
+
|
|
1154
|
+
ret = deflate(&zip->stream, Z_FINISH);
|
|
1155
|
+
if (ret == Z_STREAM_ERROR)
|
|
1156
|
+
return (ARCHIVE_FATAL);
|
|
1157
|
+
remainder = zip->len_buf - zip->stream.avail_out;
|
|
1158
|
+
if (zip->tctx_valid) {
|
|
1159
|
+
trad_enc_encrypt_update(&zip->tctx,
|
|
1160
|
+
zip->buf, remainder, zip->buf, remainder);
|
|
1161
|
+
} else if (zip->cctx_valid) {
|
|
1162
|
+
size_t outl = remainder;
|
|
1163
|
+
ret = archive_encrypto_aes_ctr_update(
|
|
1164
|
+
&zip->cctx, zip->buf, remainder,
|
|
1165
|
+
zip->buf, &outl);
|
|
1166
|
+
if (ret < 0) {
|
|
1167
|
+
archive_set_error(&a->archive,
|
|
1168
|
+
ARCHIVE_ERRNO_MISC,
|
|
1169
|
+
"Failed to encrypt file");
|
|
1170
|
+
return (ARCHIVE_FAILED);
|
|
1171
|
+
}
|
|
1172
|
+
archive_hmac_sha1_update(&zip->hctx,
|
|
1173
|
+
zip->buf, remainder);
|
|
1174
|
+
}
|
|
1175
|
+
ret = __archive_write_output(a, zip->buf, remainder);
|
|
1176
|
+
if (ret != ARCHIVE_OK)
|
|
1177
|
+
return (ret);
|
|
1178
|
+
zip->entry_compressed_written += remainder;
|
|
1179
|
+
zip->written_bytes += remainder;
|
|
1180
|
+
zip->stream.next_out = zip->buf;
|
|
1181
|
+
if (zip->stream.avail_out != 0)
|
|
1182
|
+
break;
|
|
1183
|
+
zip->stream.avail_out = (uInt)zip->len_buf;
|
|
1184
|
+
}
|
|
1185
|
+
deflateEnd(&zip->stream);
|
|
1186
|
+
}
|
|
1187
|
+
#endif
|
|
1188
|
+
if (zip->hctx_valid) {
|
|
1189
|
+
uint8_t hmac[20];
|
|
1190
|
+
size_t hmac_len = 20;
|
|
1191
|
+
|
|
1192
|
+
archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len);
|
|
1193
|
+
ret = __archive_write_output(a, hmac, AUTH_CODE_SIZE);
|
|
1194
|
+
if (ret != ARCHIVE_OK)
|
|
1195
|
+
return (ret);
|
|
1196
|
+
zip->entry_compressed_written += AUTH_CODE_SIZE;
|
|
1197
|
+
zip->written_bytes += AUTH_CODE_SIZE;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
/* Write trailing data descriptor. */
|
|
1201
|
+
if ((zip->entry_flags & ZIP_ENTRY_FLAG_LENGTH_AT_END) != 0) {
|
|
1202
|
+
char d[24];
|
|
1203
|
+
memcpy(d, "PK\007\010", 4);
|
|
1204
|
+
if (zip->cctx_valid && zip->aes_vendor == AES_VENDOR_AE_2)
|
|
1205
|
+
archive_le32enc(d + 4, 0);/* no CRC.*/
|
|
1206
|
+
else
|
|
1207
|
+
archive_le32enc(d + 4, zip->entry_crc32);
|
|
1208
|
+
if (zip->entry_uses_zip64) {
|
|
1209
|
+
archive_le64enc(d + 8,
|
|
1210
|
+
(uint64_t)zip->entry_compressed_written);
|
|
1211
|
+
archive_le64enc(d + 16,
|
|
1212
|
+
(uint64_t)zip->entry_uncompressed_written);
|
|
1213
|
+
ret = __archive_write_output(a, d, 24);
|
|
1214
|
+
zip->written_bytes += 24;
|
|
1215
|
+
} else {
|
|
1216
|
+
archive_le32enc(d + 8,
|
|
1217
|
+
(uint32_t)zip->entry_compressed_written);
|
|
1218
|
+
archive_le32enc(d + 12,
|
|
1219
|
+
(uint32_t)zip->entry_uncompressed_written);
|
|
1220
|
+
ret = __archive_write_output(a, d, 16);
|
|
1221
|
+
zip->written_bytes += 16;
|
|
1222
|
+
}
|
|
1223
|
+
if (ret != ARCHIVE_OK)
|
|
1224
|
+
return (ARCHIVE_FATAL);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
/* Append Zip64 extra data to central directory information. */
|
|
1228
|
+
if (zip->entry_compressed_written > ZIP_4GB_MAX
|
|
1229
|
+
|| zip->entry_uncompressed_written > ZIP_4GB_MAX
|
|
1230
|
+
|| zip->entry_offset > ZIP_4GB_MAX) {
|
|
1231
|
+
unsigned char zip64[32];
|
|
1232
|
+
unsigned char *z = zip64, *zd;
|
|
1233
|
+
memcpy(z, "\001\000\000\000", 4);
|
|
1234
|
+
z += 4;
|
|
1235
|
+
if (zip->entry_uncompressed_written >= ZIP_4GB_MAX) {
|
|
1236
|
+
archive_le64enc(z, zip->entry_uncompressed_written);
|
|
1237
|
+
z += 8;
|
|
1238
|
+
}
|
|
1239
|
+
if (zip->entry_compressed_written >= ZIP_4GB_MAX) {
|
|
1240
|
+
archive_le64enc(z, zip->entry_compressed_written);
|
|
1241
|
+
z += 8;
|
|
1242
|
+
}
|
|
1243
|
+
if (zip->entry_offset >= ZIP_4GB_MAX) {
|
|
1244
|
+
archive_le64enc(z, zip->entry_offset);
|
|
1245
|
+
z += 8;
|
|
1246
|
+
}
|
|
1247
|
+
archive_le16enc(zip64 + 2, (uint16_t)(z - (zip64 + 4)));
|
|
1248
|
+
zd = cd_alloc(zip, z - zip64);
|
|
1249
|
+
if (zd == NULL) {
|
|
1250
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1251
|
+
"Can't allocate zip data");
|
|
1252
|
+
return (ARCHIVE_FATAL);
|
|
1253
|
+
}
|
|
1254
|
+
memcpy(zd, zip64, z - zip64);
|
|
1255
|
+
/* Zip64 means version needs to be set to at least 4.5 */
|
|
1256
|
+
if (archive_le16dec(zip->file_header + 6) < 45)
|
|
1257
|
+
archive_le16enc(zip->file_header + 6, 45);
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
/* Fix up central directory file header. */
|
|
1261
|
+
if (zip->cctx_valid && zip->aes_vendor == AES_VENDOR_AE_2)
|
|
1262
|
+
archive_le32enc(zip->file_header + 16, 0);/* no CRC.*/
|
|
1263
|
+
else
|
|
1264
|
+
archive_le32enc(zip->file_header + 16, zip->entry_crc32);
|
|
1265
|
+
archive_le32enc(zip->file_header + 20,
|
|
1266
|
+
(uint32_t)zipmin(zip->entry_compressed_written,
|
|
1267
|
+
ZIP_4GB_MAX));
|
|
1268
|
+
archive_le32enc(zip->file_header + 24,
|
|
1269
|
+
(uint32_t)zipmin(zip->entry_uncompressed_written,
|
|
1270
|
+
ZIP_4GB_MAX));
|
|
1271
|
+
archive_le16enc(zip->file_header + 30,
|
|
1272
|
+
(uint16_t)(zip->central_directory_bytes - zip->file_header_extra_offset));
|
|
1273
|
+
archive_le32enc(zip->file_header + 42,
|
|
1274
|
+
(uint32_t)zipmin(zip->entry_offset,
|
|
1275
|
+
ZIP_4GB_MAX));
|
|
1276
|
+
|
|
1277
|
+
return (ARCHIVE_OK);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
static int
|
|
1281
|
+
archive_write_zip_close(struct archive_write *a)
|
|
1282
|
+
{
|
|
1283
|
+
uint8_t buff[64];
|
|
1284
|
+
int64_t offset_start, offset_end;
|
|
1285
|
+
struct zip *zip = a->format_data;
|
|
1286
|
+
struct cd_segment *segment;
|
|
1287
|
+
int ret;
|
|
1288
|
+
|
|
1289
|
+
offset_start = zip->written_bytes;
|
|
1290
|
+
segment = zip->central_directory;
|
|
1291
|
+
while (segment != NULL) {
|
|
1292
|
+
ret = __archive_write_output(a,
|
|
1293
|
+
segment->buff, segment->p - segment->buff);
|
|
1294
|
+
if (ret != ARCHIVE_OK)
|
|
1295
|
+
return (ARCHIVE_FATAL);
|
|
1296
|
+
zip->written_bytes += segment->p - segment->buff;
|
|
1297
|
+
segment = segment->next;
|
|
1298
|
+
}
|
|
1299
|
+
offset_end = zip->written_bytes;
|
|
1300
|
+
|
|
1301
|
+
/* If central dir info is too large, write Zip64 end-of-cd */
|
|
1302
|
+
if (offset_end - offset_start > ZIP_4GB_MAX
|
|
1303
|
+
|| offset_start > ZIP_4GB_MAX
|
|
1304
|
+
|| zip->central_directory_entries > 0xffffUL
|
|
1305
|
+
|| (zip->flags & ZIP_FLAG_FORCE_ZIP64)) {
|
|
1306
|
+
/* Zip64 end-of-cd record */
|
|
1307
|
+
memset(buff, 0, 56);
|
|
1308
|
+
memcpy(buff, "PK\006\006", 4);
|
|
1309
|
+
archive_le64enc(buff + 4, 44);
|
|
1310
|
+
archive_le16enc(buff + 12, 45);
|
|
1311
|
+
archive_le16enc(buff + 14, 45);
|
|
1312
|
+
/* This is disk 0 of 0. */
|
|
1313
|
+
archive_le64enc(buff + 24, zip->central_directory_entries);
|
|
1314
|
+
archive_le64enc(buff + 32, zip->central_directory_entries);
|
|
1315
|
+
archive_le64enc(buff + 40, offset_end - offset_start);
|
|
1316
|
+
archive_le64enc(buff + 48, offset_start);
|
|
1317
|
+
ret = __archive_write_output(a, buff, 56);
|
|
1318
|
+
if (ret != ARCHIVE_OK)
|
|
1319
|
+
return (ARCHIVE_FATAL);
|
|
1320
|
+
zip->written_bytes += 56;
|
|
1321
|
+
|
|
1322
|
+
/* Zip64 end-of-cd locator record. */
|
|
1323
|
+
memset(buff, 0, 20);
|
|
1324
|
+
memcpy(buff, "PK\006\007", 4);
|
|
1325
|
+
archive_le32enc(buff + 4, 0);
|
|
1326
|
+
archive_le64enc(buff + 8, offset_end);
|
|
1327
|
+
archive_le32enc(buff + 16, 1);
|
|
1328
|
+
ret = __archive_write_output(a, buff, 20);
|
|
1329
|
+
if (ret != ARCHIVE_OK)
|
|
1330
|
+
return (ARCHIVE_FATAL);
|
|
1331
|
+
zip->written_bytes += 20;
|
|
1332
|
+
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
/* Format and write end of central directory. */
|
|
1336
|
+
memset(buff, 0, sizeof(buff));
|
|
1337
|
+
memcpy(buff, "PK\005\006", 4);
|
|
1338
|
+
archive_le16enc(buff + 8, (uint16_t)zipmin(0xffffU,
|
|
1339
|
+
zip->central_directory_entries));
|
|
1340
|
+
archive_le16enc(buff + 10, (uint16_t)zipmin(0xffffU,
|
|
1341
|
+
zip->central_directory_entries));
|
|
1342
|
+
archive_le32enc(buff + 12,
|
|
1343
|
+
(uint32_t)zipmin(ZIP_4GB_MAX, (offset_end - offset_start)));
|
|
1344
|
+
archive_le32enc(buff + 16,
|
|
1345
|
+
(uint32_t)zipmin(ZIP_4GB_MAX, offset_start));
|
|
1346
|
+
ret = __archive_write_output(a, buff, 22);
|
|
1347
|
+
if (ret != ARCHIVE_OK)
|
|
1348
|
+
return (ARCHIVE_FATAL);
|
|
1349
|
+
zip->written_bytes += 22;
|
|
1350
|
+
return (ARCHIVE_OK);
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
static int
|
|
1354
|
+
archive_write_zip_free(struct archive_write *a)
|
|
1355
|
+
{
|
|
1356
|
+
struct zip *zip;
|
|
1357
|
+
struct cd_segment *segment;
|
|
1358
|
+
|
|
1359
|
+
zip = a->format_data;
|
|
1360
|
+
while (zip->central_directory != NULL) {
|
|
1361
|
+
segment = zip->central_directory;
|
|
1362
|
+
zip->central_directory = segment->next;
|
|
1363
|
+
free(segment->buff);
|
|
1364
|
+
free(segment);
|
|
1365
|
+
}
|
|
1366
|
+
free(zip->buf);
|
|
1367
|
+
archive_entry_free(zip->entry);
|
|
1368
|
+
if (zip->cctx_valid)
|
|
1369
|
+
archive_encrypto_aes_ctr_release(&zip->cctx);
|
|
1370
|
+
if (zip->hctx_valid)
|
|
1371
|
+
archive_hmac_sha1_cleanup(&zip->hctx);
|
|
1372
|
+
/* TODO: Free opt_sconv, sconv_default */
|
|
1373
|
+
|
|
1374
|
+
free(zip);
|
|
1375
|
+
a->format_data = NULL;
|
|
1376
|
+
return (ARCHIVE_OK);
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
/* Convert into MSDOS-style date/time. */
|
|
1380
|
+
static unsigned int
|
|
1381
|
+
dos_time(const time_t unix_time)
|
|
1382
|
+
{
|
|
1383
|
+
struct tm *t;
|
|
1384
|
+
unsigned int dt;
|
|
1385
|
+
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
|
|
1386
|
+
struct tm tmbuf;
|
|
1387
|
+
#endif
|
|
1388
|
+
#if defined(HAVE__LOCALTIME64_S)
|
|
1389
|
+
errno_t terr;
|
|
1390
|
+
__time64_t tmptime;
|
|
1391
|
+
#endif
|
|
1392
|
+
|
|
1393
|
+
/* This will not preserve time when creating/extracting the archive
|
|
1394
|
+
* on two systems with different time zones. */
|
|
1395
|
+
#if defined(HAVE_LOCALTIME_R)
|
|
1396
|
+
t = localtime_r(&unix_time, &tmbuf);
|
|
1397
|
+
#elif defined(HAVE__LOCALTIME64_S)
|
|
1398
|
+
tmptime = unix_time;
|
|
1399
|
+
terr = _localtime64_s(&tmbuf, &tmptime);
|
|
1400
|
+
if (terr)
|
|
1401
|
+
t = NULL;
|
|
1402
|
+
else
|
|
1403
|
+
t = &tmbuf;
|
|
1404
|
+
#else
|
|
1405
|
+
t = localtime(&unix_time);
|
|
1406
|
+
#endif
|
|
1407
|
+
|
|
1408
|
+
/* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */
|
|
1409
|
+
if (t->tm_year < 1980 - 1900)
|
|
1410
|
+
/* Set minimum date/time '1980-01-01 00:00:00'. */
|
|
1411
|
+
dt = 0x00210000U;
|
|
1412
|
+
else if (t->tm_year > 2107 - 1900)
|
|
1413
|
+
/* Set maximum date/time '2107-12-31 23:59:58'. */
|
|
1414
|
+
dt = 0xff9fbf7dU;
|
|
1415
|
+
else {
|
|
1416
|
+
dt = 0;
|
|
1417
|
+
dt += ((t->tm_year - 80) & 0x7f) << 9;
|
|
1418
|
+
dt += ((t->tm_mon + 1) & 0x0f) << 5;
|
|
1419
|
+
dt += (t->tm_mday & 0x1f);
|
|
1420
|
+
dt <<= 16;
|
|
1421
|
+
dt += (t->tm_hour & 0x1f) << 11;
|
|
1422
|
+
dt += (t->tm_min & 0x3f) << 5;
|
|
1423
|
+
dt += (t->tm_sec & 0x3e) >> 1; /* Only counting every 2 seconds. */
|
|
1424
|
+
}
|
|
1425
|
+
return dt;
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
static size_t
|
|
1429
|
+
path_length(struct archive_entry *entry)
|
|
1430
|
+
{
|
|
1431
|
+
mode_t type;
|
|
1432
|
+
const char *path;
|
|
1433
|
+
size_t len;
|
|
1434
|
+
|
|
1435
|
+
type = archive_entry_filetype(entry);
|
|
1436
|
+
path = archive_entry_pathname(entry);
|
|
1437
|
+
|
|
1438
|
+
if (path == NULL)
|
|
1439
|
+
return (0);
|
|
1440
|
+
len = strlen(path);
|
|
1441
|
+
if (type == AE_IFDIR && (path[0] == '\0' || path[len - 1] != '/'))
|
|
1442
|
+
++len; /* Space for the trailing / */
|
|
1443
|
+
return len;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
static int
|
|
1447
|
+
write_path(struct archive_entry *entry, struct archive_write *archive)
|
|
1448
|
+
{
|
|
1449
|
+
int ret;
|
|
1450
|
+
const char *path;
|
|
1451
|
+
mode_t type;
|
|
1452
|
+
size_t written_bytes;
|
|
1453
|
+
|
|
1454
|
+
path = archive_entry_pathname(entry);
|
|
1455
|
+
type = archive_entry_filetype(entry);
|
|
1456
|
+
written_bytes = 0;
|
|
1457
|
+
|
|
1458
|
+
if (path == NULL)
|
|
1459
|
+
return (ARCHIVE_FATAL);
|
|
1460
|
+
|
|
1461
|
+
ret = __archive_write_output(archive, path, strlen(path));
|
|
1462
|
+
if (ret != ARCHIVE_OK)
|
|
1463
|
+
return (ARCHIVE_FATAL);
|
|
1464
|
+
written_bytes += strlen(path);
|
|
1465
|
+
|
|
1466
|
+
/* Folders are recognized by a trailing slash. */
|
|
1467
|
+
if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
|
|
1468
|
+
ret = __archive_write_output(archive, "/", 1);
|
|
1469
|
+
if (ret != ARCHIVE_OK)
|
|
1470
|
+
return (ARCHIVE_FATAL);
|
|
1471
|
+
written_bytes += 1;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
return ((int)written_bytes);
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
static void
|
|
1478
|
+
copy_path(struct archive_entry *entry, unsigned char *p)
|
|
1479
|
+
{
|
|
1480
|
+
const char *path;
|
|
1481
|
+
size_t pathlen;
|
|
1482
|
+
mode_t type;
|
|
1483
|
+
|
|
1484
|
+
path = archive_entry_pathname(entry);
|
|
1485
|
+
pathlen = strlen(path);
|
|
1486
|
+
type = archive_entry_filetype(entry);
|
|
1487
|
+
|
|
1488
|
+
memcpy(p, path, pathlen);
|
|
1489
|
+
|
|
1490
|
+
/* Folders are recognized by a trailing slash. */
|
|
1491
|
+
if ((type == AE_IFDIR) && (path[pathlen - 1] != '/'))
|
|
1492
|
+
p[pathlen] = '/';
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
static struct archive_string_conv *
|
|
1497
|
+
get_sconv(struct archive_write *a, struct zip *zip)
|
|
1498
|
+
{
|
|
1499
|
+
if (zip->opt_sconv != NULL)
|
|
1500
|
+
return (zip->opt_sconv);
|
|
1501
|
+
|
|
1502
|
+
if (!zip->init_default_conversion) {
|
|
1503
|
+
zip->sconv_default =
|
|
1504
|
+
archive_string_default_conversion_for_write(&(a->archive));
|
|
1505
|
+
zip->init_default_conversion = 1;
|
|
1506
|
+
}
|
|
1507
|
+
return (zip->sconv_default);
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
/*
|
|
1511
|
+
Traditional PKWARE Decryption functions.
|
|
1512
|
+
*/
|
|
1513
|
+
|
|
1514
|
+
static void
|
|
1515
|
+
trad_enc_update_keys(struct trad_enc_ctx *ctx, uint8_t c)
|
|
1516
|
+
{
|
|
1517
|
+
uint8_t t;
|
|
1518
|
+
#define CRC32(c, b) (crc32(c ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL)
|
|
1519
|
+
|
|
1520
|
+
ctx->keys[0] = CRC32(ctx->keys[0], c);
|
|
1521
|
+
ctx->keys[1] = (ctx->keys[1] + (ctx->keys[0] & 0xff)) * 134775813L + 1;
|
|
1522
|
+
t = (ctx->keys[1] >> 24) & 0xff;
|
|
1523
|
+
ctx->keys[2] = CRC32(ctx->keys[2], t);
|
|
1524
|
+
#undef CRC32
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
static uint8_t
|
|
1528
|
+
trad_enc_decrypt_byte(struct trad_enc_ctx *ctx)
|
|
1529
|
+
{
|
|
1530
|
+
unsigned temp = ctx->keys[2] | 2;
|
|
1531
|
+
return (uint8_t)((temp * (temp ^ 1)) >> 8) & 0xff;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
static unsigned
|
|
1535
|
+
trad_enc_encrypt_update(struct trad_enc_ctx *ctx, const uint8_t *in,
|
|
1536
|
+
size_t in_len, uint8_t *out, size_t out_len)
|
|
1537
|
+
{
|
|
1538
|
+
unsigned i, max;
|
|
1539
|
+
|
|
1540
|
+
max = (unsigned)((in_len < out_len)? in_len: out_len);
|
|
1541
|
+
|
|
1542
|
+
for (i = 0; i < max; i++) {
|
|
1543
|
+
uint8_t t = in[i];
|
|
1544
|
+
out[i] = t ^ trad_enc_decrypt_byte(ctx);
|
|
1545
|
+
trad_enc_update_keys(ctx, t);
|
|
1546
|
+
}
|
|
1547
|
+
return i;
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
static int
|
|
1551
|
+
trad_enc_init(struct trad_enc_ctx *ctx, const char *pw, size_t pw_len)
|
|
1552
|
+
{
|
|
1553
|
+
|
|
1554
|
+
ctx->keys[0] = 305419896L;
|
|
1555
|
+
ctx->keys[1] = 591751049L;
|
|
1556
|
+
ctx->keys[2] = 878082192L;
|
|
1557
|
+
|
|
1558
|
+
for (;pw_len; --pw_len)
|
|
1559
|
+
trad_enc_update_keys(ctx, *pw++);
|
|
1560
|
+
return 0;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
static int
|
|
1564
|
+
is_traditional_pkware_encryption_supported(void)
|
|
1565
|
+
{
|
|
1566
|
+
uint8_t key[TRAD_HEADER_SIZE];
|
|
1567
|
+
|
|
1568
|
+
if (archive_random(key, sizeof(key)-1) != ARCHIVE_OK)
|
|
1569
|
+
return (0);
|
|
1570
|
+
return (1);
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
static int
|
|
1574
|
+
init_traditional_pkware_encryption(struct archive_write *a)
|
|
1575
|
+
{
|
|
1576
|
+
struct zip *zip = a->format_data;
|
|
1577
|
+
const char *passphrase;
|
|
1578
|
+
uint8_t key[TRAD_HEADER_SIZE];
|
|
1579
|
+
uint8_t key_encrypted[TRAD_HEADER_SIZE];
|
|
1580
|
+
int ret;
|
|
1581
|
+
|
|
1582
|
+
passphrase = __archive_write_get_passphrase(a);
|
|
1583
|
+
if (passphrase == NULL) {
|
|
1584
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1585
|
+
"Encryption needs passphrase");
|
|
1586
|
+
return ARCHIVE_FAILED;
|
|
1587
|
+
}
|
|
1588
|
+
if (archive_random(key, sizeof(key)-1) != ARCHIVE_OK) {
|
|
1589
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1590
|
+
"Can't generate random number for encryption");
|
|
1591
|
+
return ARCHIVE_FATAL;
|
|
1592
|
+
}
|
|
1593
|
+
trad_enc_init(&zip->tctx, passphrase, strlen(passphrase));
|
|
1594
|
+
/* Set the last key code which will be used as a check code
|
|
1595
|
+
* for verifying passphrase in decryption. */
|
|
1596
|
+
key[TRAD_HEADER_SIZE-1] = zip->trad_chkdat;
|
|
1597
|
+
trad_enc_encrypt_update(&zip->tctx, key, TRAD_HEADER_SIZE,
|
|
1598
|
+
key_encrypted, TRAD_HEADER_SIZE);
|
|
1599
|
+
/* Write encrypted keys in the top of the file content. */
|
|
1600
|
+
ret = __archive_write_output(a, key_encrypted, TRAD_HEADER_SIZE);
|
|
1601
|
+
if (ret != ARCHIVE_OK)
|
|
1602
|
+
return (ret);
|
|
1603
|
+
zip->written_bytes += TRAD_HEADER_SIZE;
|
|
1604
|
+
zip->entry_compressed_written += TRAD_HEADER_SIZE;
|
|
1605
|
+
return (ret);
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
static int
|
|
1609
|
+
init_winzip_aes_encryption(struct archive_write *a)
|
|
1610
|
+
{
|
|
1611
|
+
struct zip *zip = a->format_data;
|
|
1612
|
+
const char *passphrase;
|
|
1613
|
+
size_t key_len, salt_len;
|
|
1614
|
+
uint8_t salt[16 + 2];
|
|
1615
|
+
uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
|
|
1616
|
+
int ret;
|
|
1617
|
+
|
|
1618
|
+
passphrase = __archive_write_get_passphrase(a);
|
|
1619
|
+
if (passphrase == NULL) {
|
|
1620
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1621
|
+
"Encryption needs passphrase");
|
|
1622
|
+
return (ARCHIVE_FAILED);
|
|
1623
|
+
}
|
|
1624
|
+
if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128) {
|
|
1625
|
+
salt_len = 8;
|
|
1626
|
+
key_len = 16;
|
|
1627
|
+
} else {
|
|
1628
|
+
/* AES 256 */
|
|
1629
|
+
salt_len = 16;
|
|
1630
|
+
key_len = 32;
|
|
1631
|
+
}
|
|
1632
|
+
if (archive_random(salt, salt_len) != ARCHIVE_OK) {
|
|
1633
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1634
|
+
"Can't generate random number for encryption");
|
|
1635
|
+
return (ARCHIVE_FATAL);
|
|
1636
|
+
}
|
|
1637
|
+
archive_pbkdf2_sha1(passphrase, strlen(passphrase),
|
|
1638
|
+
salt, salt_len, 1000, derived_key, key_len * 2 + 2);
|
|
1639
|
+
|
|
1640
|
+
ret = archive_encrypto_aes_ctr_init(&zip->cctx, derived_key, key_len);
|
|
1641
|
+
if (ret != 0) {
|
|
1642
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1643
|
+
"Decryption is unsupported due to lack of crypto library");
|
|
1644
|
+
return (ARCHIVE_FAILED);
|
|
1645
|
+
}
|
|
1646
|
+
ret = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len,
|
|
1647
|
+
key_len);
|
|
1648
|
+
if (ret != 0) {
|
|
1649
|
+
archive_encrypto_aes_ctr_release(&zip->cctx);
|
|
1650
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1651
|
+
"Failed to initialize HMAC-SHA1");
|
|
1652
|
+
return (ARCHIVE_FAILED);
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
/* Set a password verification value after the 'salt'. */
|
|
1656
|
+
salt[salt_len] = derived_key[key_len * 2];
|
|
1657
|
+
salt[salt_len + 1] = derived_key[key_len * 2 + 1];
|
|
1658
|
+
|
|
1659
|
+
/* Write encrypted keys in the top of the file content. */
|
|
1660
|
+
ret = __archive_write_output(a, salt, salt_len + 2);
|
|
1661
|
+
if (ret != ARCHIVE_OK)
|
|
1662
|
+
return (ret);
|
|
1663
|
+
zip->written_bytes += salt_len + 2;
|
|
1664
|
+
zip->entry_compressed_written += salt_len + 2;
|
|
1665
|
+
|
|
1666
|
+
return (ARCHIVE_OK);
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
static int
|
|
1670
|
+
is_winzip_aes_encryption_supported(int encryption)
|
|
1671
|
+
{
|
|
1672
|
+
size_t key_len, salt_len;
|
|
1673
|
+
uint8_t salt[16 + 2];
|
|
1674
|
+
uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
|
|
1675
|
+
archive_crypto_ctx cctx;
|
|
1676
|
+
archive_hmac_sha1_ctx hctx;
|
|
1677
|
+
int ret;
|
|
1678
|
+
|
|
1679
|
+
if (encryption == ENCRYPTION_WINZIP_AES128) {
|
|
1680
|
+
salt_len = 8;
|
|
1681
|
+
key_len = 16;
|
|
1682
|
+
} else {
|
|
1683
|
+
/* AES 256 */
|
|
1684
|
+
salt_len = 16;
|
|
1685
|
+
key_len = 32;
|
|
1686
|
+
}
|
|
1687
|
+
if (archive_random(salt, salt_len) != ARCHIVE_OK)
|
|
1688
|
+
return (0);
|
|
1689
|
+
ret = archive_pbkdf2_sha1("p", 1, salt, salt_len, 1000,
|
|
1690
|
+
derived_key, key_len * 2 + 2);
|
|
1691
|
+
if (ret != 0)
|
|
1692
|
+
return (0);
|
|
1693
|
+
|
|
1694
|
+
ret = archive_encrypto_aes_ctr_init(&cctx, derived_key, key_len);
|
|
1695
|
+
if (ret != 0)
|
|
1696
|
+
return (0);
|
|
1697
|
+
ret = archive_hmac_sha1_init(&hctx, derived_key + key_len,
|
|
1698
|
+
key_len);
|
|
1699
|
+
archive_encrypto_aes_ctr_release(&cctx);
|
|
1700
|
+
if (ret != 0)
|
|
1701
|
+
return (0);
|
|
1702
|
+
archive_hmac_sha1_cleanup(&hctx);
|
|
1703
|
+
return (1);
|
|
1704
|
+
}
|