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