Home | History | Annotate | Line # | Download | only in libarchive
      1 /*-
      2  * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
      3  * Copyright (c) 2003-2007 Tim Kientzle
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "archive_platform.h"
     28 
     29 #ifdef HAVE_STDLIB_H
     30 #include <stdlib.h>
     31 #endif
     32 #ifdef HAVE_STRING_H
     33 #include <string.h>
     34 #endif
     35 #ifdef HAVE_ZLIB_H
     36 #include <zlib.h>
     37 #endif
     38 #ifdef HAVE_LZMA_H
     39 #include <lzma.h>
     40 #endif
     41 #ifdef HAVE_BZLIB_H
     42 #include <bzlib.h>
     43 #endif
     44 #ifdef HAVE_LZ4_H
     45 #include <lz4.h>
     46 #endif
     47 #ifdef HAVE_ZSTD_H
     48 #include <zstd.h>
     49 #include <stdio.h>
     50 #endif
     51 #ifdef HAVE_LZO_LZOCONF_H
     52 #include <lzo/lzoconf.h>
     53 #endif
     54 #if HAVE_LIBXML_XMLVERSION_H
     55 #include <libxml/xmlversion.h>
     56 #elif HAVE_BSDXML_H
     57 #include <bsdxml.h>
     58 #elif HAVE_EXPAT_H
     59 #include <expat.h>
     60 #endif
     61 #if HAVE_MBEDTLS_VERSION_H
     62 #include <mbedtls/version.h>
     63 #endif
     64 #if HAVE_NETTLE_VERSION_H
     65 #include <nettle/version.h>
     66 #include <stdio.h>
     67 #endif
     68 #if HAVE_OPENSSL_OPENSSLV_H
     69 #include <openssl/opensslv.h>
     70 #include <stdio.h>
     71 #endif
     72 #if HAVE_ICONV_H
     73 #include <iconv.h>
     74 #endif
     75 #if HAVE_PCRE_H
     76 #include <pcre.h>
     77 #endif
     78 #if HAVE_PCRE2_H
     79 #include <pcre2.h>
     80 #endif
     81 
     82 #include "archive.h"
     83 #include "archive_private.h"
     84 #include "archive_string.h"
     85 #include "archive_cryptor_private.h"
     86 #include "archive_digest_private.h"
     87 
     88 static void
     89 archive_regex_version(struct archive_string* str)
     90 {
     91 #if HAVE_LIBPCREPOSIX && HAVE_PCRE_H
     92 	archive_strcat(str, " libpcre/");
     93 	archive_strcat(str, archive_libpcre_version());
     94 #elif HAVE_LIBPCRE2POSIX && HAVE_PCRE2_H
     95 	archive_strcat(str, " libpcre2/");
     96 	archive_strcat(str, archive_libpcre2_version());
     97 #else
     98 	(void)str; /* UNUSED */
     99 #endif
    100 }
    101 
    102 static void
    103 archive_xml_version(struct archive_string* str)
    104 {
    105 #if HAVE_LIBXML_XMLVERSION_H && HAVE_LIBXML2
    106 	archive_strcat(str, " libxml2/");
    107 	archive_strcat(str, archive_libxml2_version());
    108 #elif HAVE_BSDXML_H && HAVE_LIBBSDXML
    109 	archive_strcat(str, " bsdxml/");
    110 	archive_strcat(str, archive_libbsdxml_version());
    111 #elif HAVE_EXPAT_H && HAVE_LIBEXPAT
    112 	archive_strcat(str, " expat/");
    113 	archive_strcat(str, archive_libexpat_version());
    114 #else
    115 	(void)str; /* UNUSED */
    116 #endif
    117 }
    118 
    119 static void
    120 archive_libb2_version(struct archive_string* str)
    121 {
    122 	archive_strcat(str, " libb2/");
    123 #if HAVE_BLAKE2_H && HAVE_LIBB2
    124 #if defined(LIBB2_PKGCONFIG_VERSION)
    125 	archive_strcat(str, LIBB2_PKGCONFIG_VERSION);
    126 #else
    127 	archive_strcat(str, "system");
    128 #endif
    129 #else
    130 	archive_strcat(str, "bundled");
    131 #endif
    132 }
    133 
    134 static void
    135 archive_crypto_version(struct archive_string* str)
    136 {
    137 #if defined(ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto)
    138 	archive_strcat(str, " CommonCrypto/");
    139 	archive_strcat(str, archive_commoncrypto_version());
    140 #endif
    141 #if defined(ARCHIVE_CRYPTOR_USE_CNG)
    142 	archive_strcat(str, " cng/");
    143 	archive_strcat(str, archive_cng_version());
    144 #endif
    145 #if defined(ARCHIVE_CRYPTOR_USE_MBED)
    146 	archive_strcat(str, " mbedtls/");
    147 	archive_strcat(str, archive_mbedtls_version());
    148 #endif
    149 #if defined(ARCHIVE_CRYPTOR_USE_NETTLE)
    150 	archive_strcat(str, " nettle/");
    151 	archive_strcat(str, archive_nettle_version());
    152 #endif
    153 #if defined(ARCHIVE_CRYPTOR_USE_OPENSSL)
    154 	archive_strcat(str, " openssl/");
    155 	archive_strcat(str, archive_openssl_version());
    156 #endif
    157 #if defined(ARCHIVE_CRYPTOR_USE_LIBMD)
    158 	archive_strcat(str, " libmd/");
    159 	archive_strcat(str, archive_libmd_version());
    160 #endif
    161 #if defined(ARCHIVE_CRYPTOR_USE_WINCRYPT)
    162 	archive_strcat(str, " WinCrypt/");
    163 	archive_strcat(str, archive_wincrypt_version());
    164 #endif
    165 	// Just in case
    166 	(void)str; /* UNUSED */
    167 }
    168 
    169 const char *
    170 archive_version_details(void)
    171 {
    172 	static struct archive_string str;
    173 	static int init = 0;
    174 	const char *zlib = archive_zlib_version();
    175 	const char *liblzma = archive_liblzma_version();
    176 	const char *bzlib = archive_bzlib_version();
    177 	const char *liblz4 = archive_liblz4_version();
    178 	const char *libzstd = archive_libzstd_version();
    179 	const char *liblzo = archive_liblzo2_version();
    180 	const char *libiconv = archive_libiconv_version();
    181 	const char *libacl = archive_libacl_version();
    182 	const char *librichacl = archive_librichacl_version();
    183 	const char *libattr = archive_libacl_version();
    184 
    185 	if (!init) {
    186 		archive_string_init(&str);
    187 
    188 		archive_strcat(&str, ARCHIVE_VERSION_STRING);
    189 		if (zlib) {
    190 			archive_strcat(&str, " zlib/");
    191 			archive_strcat(&str, zlib);
    192 		}
    193 		if (liblzma) {
    194 			archive_strcat(&str, " liblzma/");
    195 			archive_strcat(&str, liblzma);
    196 		}
    197 		if (bzlib) {
    198 			const char *p = bzlib;
    199 			const char *sep = strchr(p, ',');
    200 			if (sep == NULL)
    201 				sep = p + strlen(p);
    202 			archive_strcat(&str, " bz2lib/");
    203 			archive_strncat(&str, p, sep - p);
    204 		}
    205 		if (liblz4) {
    206 			archive_strcat(&str, " liblz4/");
    207 			archive_strcat(&str, liblz4);
    208 		}
    209 		if (libzstd) {
    210 			archive_strcat(&str, " libzstd/");
    211 			archive_strcat(&str, libzstd);
    212 		}
    213 		if (liblzo) {
    214 			archive_strcat(&str, " liblzo2/");
    215 			archive_strcat(&str, liblzo);
    216 		}
    217 		archive_xml_version(&str);
    218 		archive_regex_version(&str);
    219 		archive_crypto_version(&str);
    220 		archive_libb2_version(&str);
    221 		if (librichacl) {
    222 			archive_strcat(&str, " librichacl/");
    223 			archive_strcat(&str, librichacl);
    224 		}
    225 		if (libacl) {
    226 			archive_strcat(&str, " libacl/");
    227 			archive_strcat(&str, libacl);
    228 		}
    229 		if (libattr) {
    230 			archive_strcat(&str, " libattr/");
    231 			archive_strcat(&str, libattr);
    232 		}
    233 		if (libiconv) {
    234 			archive_strcat(&str, " libiconv/");
    235 			archive_strcat(&str, libiconv);
    236 		}
    237 	}
    238 	return str.s;
    239 }
    240 
    241 const char *
    242 archive_zlib_version(void)
    243 {
    244 #if HAVE_ZLIB_H && HAVE_LIBZ
    245 	return zlibVersion();
    246 #else
    247 	return NULL;
    248 #endif
    249 }
    250 
    251 const char *
    252 archive_liblzma_version(void)
    253 {
    254 #if HAVE_LZMA_H && HAVE_LIBLZMA
    255 	return lzma_version_string();
    256 #else
    257 	return NULL;
    258 #endif
    259 }
    260 
    261 const char *
    262 archive_bzlib_version(void)
    263 {
    264 #if HAVE_BZLIB_H && HAVE_LIBBZ2
    265 	return BZ2_bzlibVersion();
    266 #else
    267 	return NULL;
    268 #endif
    269 }
    270 
    271 const char *
    272 archive_liblz4_version(void)
    273 {
    274 #if HAVE_LZ4_H && HAVE_LIBLZ4
    275 #if LZ4_VERSION_NUMBER > 10705
    276 	return LZ4_versionString();
    277 #elif LZ4_VERSION_NUMBER > 10300
    278 	div_t major = div(LZ4_versionNumber(), 10000);
    279 	div_t minor = div(major.rem, 100);
    280 	static char lz4_version[9];
    281 	snprintf(lz4_version, 9, "%d.%d.%d", major.quot, minor.quot, minor.rem);
    282 	return lz4_version;
    283 #else
    284 #define str(s) #s
    285 #define NUMBER(x) str(x)
    286 	return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
    287 #undef NUMBER
    288 #undef str
    289 #endif
    290 #else
    291 	return NULL;
    292 #endif
    293 }
    294 
    295 const char *
    296 archive_libzstd_version(void)
    297 {
    298 #if HAVE_ZSTD_H && HAVE_LIBZSTD
    299 #if ZSTD_VERSION_NUMBER > 10300
    300 	return ZSTD_versionString();
    301 #else
    302 	div_t major = div(ZSTD_versionNumber(), 10000);
    303 	div_t minor = div(major.rem, 100);
    304 	static char zstd_version[9];
    305 	snprintf(zstd_version, 9, "%d.%d.%d", major.quot, minor.quot, minor.rem);
    306 	return zstd_version;
    307 #endif
    308 #else
    309 	return NULL;
    310 #endif
    311 }
    312 
    313 const char *
    314 archive_liblzo2_version(void)
    315 {
    316 #if HAVE_LZO_LZOCONF_H && HAVE_LIBLZO2
    317 	return LZO_VERSION_STRING;
    318 #else
    319 	return NULL;
    320 #endif
    321 }
    322 
    323 const char *
    324 archive_libbsdxml_version(void)
    325 {
    326 #if HAVE_BSDXML_H && HAVE_LIBBSDXML
    327 	return XML_ExpatVersion();
    328 #else
    329 	return NULL;
    330 #endif
    331 }
    332 
    333 const char *
    334 archive_libxml2_version(void)
    335 {
    336 #if HAVE_LIBXML_XMLVERSION_H && HAVE_LIBXML2
    337 	return LIBXML_DOTTED_VERSION;
    338 #else
    339 	return NULL;
    340 #endif
    341 }
    342 
    343 const char *
    344 archive_libexpat_version(void)
    345 {
    346 #if HAVE_EXPAT_H && HAVE_LIBEXPAT
    347 	return XML_ExpatVersion();
    348 #else
    349 	return NULL;
    350 #endif
    351 }
    352 
    353 const char *
    354 archive_mbedtls_version(void)
    355 {
    356 #if defined(ARCHIVE_CRYPTOR_USE_MBED) || defined(ARCHIVE_CRYPTO_MBED)
    357 	static char mbed_version[9];
    358 	mbedtls_version_get_string(mbed_version);
    359 	return mbed_version;
    360 #else
    361 	return NULL;
    362 #endif
    363 }
    364 
    365 const char *
    366 archive_nettle_version(void)
    367 {
    368 #if defined(ARCHIVE_CRYPTOR_USE_NETTLE) || defined(ARCHIVE_CRYPTO_NETTLE)
    369 	static char nettle_version[6];
    370 	snprintf(nettle_version, 6, "%d.%d", nettle_version_major(), nettle_version_minor());
    371 	return nettle_version;
    372 #else
    373 	return NULL;
    374 #endif
    375 }
    376 
    377 const char *
    378 archive_openssl_version(void)
    379 {
    380 #if defined(ARCHIVE_CRYPTOR_USE_OPENSSL) || defined(ARCHIVE_CRYPTO_OPENSSL)
    381 #ifdef OPENSSL_VERSION_STR
    382 	return OPENSSL_VERSION_STR;
    383 #else
    384 #define OPENSSL_MAJOR (OPENSSL_VERSION_NUMBER >> 28)
    385 #define OPENSSL_MINOR ((OPENSSL_VERSION_NUMBER >> 20) & 0xFF)
    386 	static char openssl_version[6];
    387 	snprintf(openssl_version, 6, "%ld.%ld", OPENSSL_MAJOR, OPENSSL_MINOR);
    388 	return openssl_version;
    389 #undef OPENSSL_MAJOR
    390 #undef OPENSSL_MINOR
    391 #endif
    392 #else
    393 	return NULL;
    394 #endif
    395 }
    396 
    397 const char *
    398 archive_libmd_version(void)
    399 {
    400 #if defined(ARCHIVE_CRYPTOR_USE_LIBMD) || defined(ARCHIVE_CRYPTO_LIBMD)
    401 	return "system";
    402 #else
    403 	return NULL;
    404 #endif
    405 }
    406 
    407 const char *
    408 archive_commoncrypto_version(void)
    409 {
    410 #if defined(ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto) || defined(ARCHIVE_CRYPTO_CommonCrypto)
    411 	return "system";
    412 #else
    413 	return NULL;
    414 #endif
    415 }
    416 
    417 const char *
    418 archive_cng_version(void)
    419 {
    420 #if defined(ARCHIVE_CRYPTOR_USE_CNG) || defined(ARCHIVE_CRYPTO_CNG)
    421 #ifdef BCRYPT_HASH_INTERFACE_MAJORVERSION_2
    422 	return "2.0";
    423 #else
    424 	return "1.0";
    425 #endif
    426 #else
    427 	return NULL;
    428 #endif
    429 }
    430 
    431 const char *
    432 archive_wincrypt_version(void)
    433 {
    434 #if defined(ARCHIVE_CRYPTOR_USE_WINCRYPT) || defined(ARCHIVE_CRYPTO_WINCRYPT)
    435 	HCRYPTPROV prov;
    436 	if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
    437 		if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
    438 			return NULL;
    439 		if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
    440 			return NULL;
    441 	}
    442 	DWORD version, length = sizeof(version);
    443 	if (!CryptGetProvParam(prov, PP_VERSION, (BYTE *)&version, &length, 0)) {
    444 		return NULL;
    445 	} else {
    446 		char major = (version >> 8) & 0xFF;
    447 		char minor = version & 0xFF;
    448 		static char wincrypt_version[6];
    449 		snprintf(wincrypt_version, 6, "%hhd.%hhd", major, minor);
    450 		return wincrypt_version;
    451 	}
    452 #else
    453 	return NULL;
    454 #endif
    455 }
    456 
    457 const char *
    458 archive_librichacl_version(void)
    459 {
    460 #if HAVE_LIBRICHACL
    461 #if defined(LIBRICHACL_PKGCONFIG_VERSION)
    462 	return LIBRICHACL_PKGCONFIG_VERSION;
    463 #else
    464 	return "system";
    465 #endif
    466 #else
    467 	return NULL;
    468 #endif
    469 }
    470 
    471 const char *
    472 archive_libacl_version(void)
    473 {
    474 #if HAVE_LIBACL
    475 #if defined(LIBACL_PKGCONFIG_VERSION)
    476 	return LIBACL_PKGCONFIG_VERSION;
    477 #else
    478 	return "system";
    479 #endif
    480 #else
    481 	return NULL;
    482 #endif
    483 }
    484 
    485 const char *
    486 archive_libattr_version(void)
    487 {
    488 #if HAVE_LIBATTR
    489 #if defined(LIBATTR_PKGCONFIG_VERSION)
    490 	return LIBATTR_PKGCONFIG_VERSION;
    491 #else
    492 	return "system";
    493 #endif
    494 #else
    495 	return NULL;
    496 #endif
    497 }
    498 
    499 const char *
    500 archive_libiconv_version(void)
    501 {
    502 #if HAVE_LIBCHARSET && HAVE_ICONV_H
    503 	char major = _libiconv_version >> 8;
    504 	char minor = _libiconv_version & 0xFF;
    505 	static char charset_version[6];
    506 	snprintf(charset_version, 6, "%hhd.%hhd", major, minor);
    507 	return charset_version;
    508 #else
    509 	return NULL;
    510 #endif
    511 }
    512 
    513 const char *
    514 archive_libpcre_version(void)
    515 {
    516 #if HAVE_LIBPCREPOSIX && HAVE_PCRE_H
    517 #define str(s) #s
    518 #define NUMBER(x) str(x)
    519 	return NUMBER(PCRE_MAJOR) "." NUMBER(PCRE_MINOR);
    520 #undef NUMBER
    521 #undef str
    522 #else
    523 	return NULL;
    524 #endif
    525 }
    526 
    527 const char *
    528 archive_libpcre2_version(void)
    529 {
    530 #if HAVE_LIBPCRE2POSIX && HAVE_PCRE2_H
    531 #define str(s) #s
    532 #define NUMBER(x) str(x)
    533 	return NUMBER(PCRE2_MAJOR) "." NUMBER(PCRE2_MINOR);
    534 #undef NUMBER
    535 #undef str
    536 #else
    537 	return NULL;
    538 #endif
    539 }
    540