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
archive_regex_version(struct archive_string * str)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
archive_xml_version(struct archive_string * str)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
archive_libb2_version(struct archive_string * str)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
archive_crypto_version(struct archive_string * str)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 // Just in case
162 (void)str; /* UNUSED */
163 }
164
165 const char *
archive_version_details(void)166 archive_version_details(void)
167 {
168 static struct archive_string str;
169 static int init = 0;
170 const char *zlib = archive_zlib_version();
171 const char *liblzma = archive_liblzma_version();
172 const char *bzlib = archive_bzlib_version();
173 const char *liblz4 = archive_liblz4_version();
174 const char *libzstd = archive_libzstd_version();
175 const char *liblzo = archive_liblzo2_version();
176 const char *libiconv = archive_libiconv_version();
177 const char *libacl = archive_libacl_version();
178 const char *librichacl = archive_librichacl_version();
179 const char *libattr = archive_libattr_version();
180
181 if (!init) {
182 archive_string_init(&str);
183
184 archive_strcat(&str, ARCHIVE_VERSION_STRING);
185 if (zlib) {
186 archive_strcat(&str, " zlib/");
187 archive_strcat(&str, zlib);
188 }
189 if (liblzma) {
190 archive_strcat(&str, " liblzma/");
191 archive_strcat(&str, liblzma);
192 }
193 if (bzlib) {
194 const char *p = bzlib;
195 const char *sep = strchr(p, ',');
196 if (sep == NULL)
197 sep = p + strlen(p);
198 archive_strcat(&str, " bz2lib/");
199 archive_strncat(&str, p, sep - p);
200 }
201 if (liblz4) {
202 archive_strcat(&str, " liblz4/");
203 archive_strcat(&str, liblz4);
204 }
205 if (libzstd) {
206 archive_strcat(&str, " libzstd/");
207 archive_strcat(&str, libzstd);
208 }
209 if (liblzo) {
210 archive_strcat(&str, " liblzo2/");
211 archive_strcat(&str, liblzo);
212 }
213 archive_xml_version(&str);
214 archive_regex_version(&str);
215 archive_crypto_version(&str);
216 archive_libb2_version(&str);
217 if (librichacl) {
218 archive_strcat(&str, " librichacl/");
219 archive_strcat(&str, librichacl);
220 }
221 if (libacl) {
222 archive_strcat(&str, " libacl/");
223 archive_strcat(&str, libacl);
224 }
225 if (libattr) {
226 archive_strcat(&str, " libattr/");
227 archive_strcat(&str, libattr);
228 }
229 if (libiconv) {
230 archive_strcat(&str, " libiconv/");
231 archive_strcat(&str, libiconv);
232 }
233 init = 1;
234 }
235 return str.s;
236 }
237
238 const char *
archive_zlib_version(void)239 archive_zlib_version(void)
240 {
241 #if HAVE_ZLIB_H && HAVE_LIBZ
242 return zlibVersion();
243 #else
244 return NULL;
245 #endif
246 }
247
248 const char *
archive_liblzma_version(void)249 archive_liblzma_version(void)
250 {
251 #if HAVE_LZMA_H && HAVE_LIBLZMA
252 return lzma_version_string();
253 #else
254 return NULL;
255 #endif
256 }
257
258 const char *
archive_bzlib_version(void)259 archive_bzlib_version(void)
260 {
261 #if HAVE_BZLIB_H && HAVE_LIBBZ2
262 return BZ2_bzlibVersion();
263 #else
264 return NULL;
265 #endif
266 }
267
268 const char *
archive_liblz4_version(void)269 archive_liblz4_version(void)
270 {
271 #if HAVE_LZ4_H && HAVE_LIBLZ4
272 #if LZ4_VERSION_NUMBER > 10705
273 return LZ4_versionString();
274 #elif LZ4_VERSION_NUMBER > 10300
275 div_t major = div(LZ4_versionNumber(), 10000);
276 div_t minor = div(major.rem, 100);
277 static char lz4_version[9];
278 snprintf(lz4_version, 9, "%d.%d.%d", major.quot, minor.quot, minor.rem);
279 return lz4_version;
280 #else
281 #define str(s) #s
282 #define NUMBER(x) str(x)
283 return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
284 #undef NUMBER
285 #undef str
286 #endif
287 #else
288 return NULL;
289 #endif
290 }
291
292 const char *
archive_libzstd_version(void)293 archive_libzstd_version(void)
294 {
295 #if HAVE_ZSTD_H && HAVE_LIBZSTD
296 #if ZSTD_VERSION_NUMBER > 10300
297 return ZSTD_versionString();
298 #else
299 div_t major = div(ZSTD_versionNumber(), 10000);
300 div_t minor = div(major.rem, 100);
301 static char zstd_version[9];
302 snprintf(zstd_version, 9, "%d.%d.%d", major.quot, minor.quot, minor.rem);
303 return zstd_version;
304 #endif
305 #else
306 return NULL;
307 #endif
308 }
309
310 const char *
archive_liblzo2_version(void)311 archive_liblzo2_version(void)
312 {
313 #if HAVE_LZO_LZOCONF_H && HAVE_LIBLZO2
314 return LZO_VERSION_STRING;
315 #else
316 return NULL;
317 #endif
318 }
319
320 const char *
archive_libbsdxml_version(void)321 archive_libbsdxml_version(void)
322 {
323 #if HAVE_BSDXML_H && HAVE_LIBBSDXML
324 return XML_ExpatVersion();
325 #else
326 return NULL;
327 #endif
328 }
329
330 const char *
archive_libxml2_version(void)331 archive_libxml2_version(void)
332 {
333 #if HAVE_LIBXML_XMLVERSION_H && HAVE_LIBXML2
334 return LIBXML_DOTTED_VERSION;
335 #else
336 return NULL;
337 #endif
338 }
339
340 const char *
archive_libexpat_version(void)341 archive_libexpat_version(void)
342 {
343 #if HAVE_EXPAT_H && HAVE_LIBEXPAT
344 return XML_ExpatVersion();
345 #else
346 return NULL;
347 #endif
348 }
349
350 const char *
archive_mbedtls_version(void)351 archive_mbedtls_version(void)
352 {
353 #if defined(ARCHIVE_CRYPTOR_USE_MBED) || defined(ARCHIVE_CRYPTO_MBED)
354 static char mbed_version[9];
355 mbedtls_version_get_string(mbed_version);
356 return mbed_version;
357 #else
358 return NULL;
359 #endif
360 }
361
362 const char *
archive_nettle_version(void)363 archive_nettle_version(void)
364 {
365 #if defined(ARCHIVE_CRYPTOR_USE_NETTLE) || defined(ARCHIVE_CRYPTO_NETTLE)
366 static char nettle_version[6];
367 snprintf(nettle_version, 6, "%d.%d", nettle_version_major(), nettle_version_minor());
368 return nettle_version;
369 #else
370 return NULL;
371 #endif
372 }
373
374 const char *
archive_openssl_version(void)375 archive_openssl_version(void)
376 {
377 #if defined(ARCHIVE_CRYPTOR_USE_OPENSSL) || defined(ARCHIVE_CRYPTO_OPENSSL)
378 #ifdef OPENSSL_VERSION_STR
379 return OPENSSL_VERSION_STR;
380 #else
381 #define OPENSSL_MAJOR (OPENSSL_VERSION_NUMBER >> 28)
382 #define OPENSSL_MINOR ((OPENSSL_VERSION_NUMBER >> 20) & 0xFF)
383 static char openssl_version[6];
384 snprintf(openssl_version, 6, "%ld.%ld", OPENSSL_MAJOR, OPENSSL_MINOR);
385 return openssl_version;
386 #undef OPENSSL_MAJOR
387 #undef OPENSSL_MINOR
388 #endif
389 #else
390 return NULL;
391 #endif
392 }
393
394 const char *
archive_libmd_version(void)395 archive_libmd_version(void)
396 {
397 #if defined(ARCHIVE_CRYPTOR_USE_LIBMD) || defined(ARCHIVE_CRYPTO_LIBMD)
398 return "system";
399 #else
400 return NULL;
401 #endif
402 }
403
404 const char *
archive_commoncrypto_version(void)405 archive_commoncrypto_version(void)
406 {
407 #if defined(ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto) || defined(ARCHIVE_CRYPTO_CommonCrypto)
408 return "system";
409 #else
410 return NULL;
411 #endif
412 }
413
414 const char *
archive_cng_version(void)415 archive_cng_version(void)
416 {
417 #if defined(ARCHIVE_CRYPTOR_USE_CNG) || defined(ARCHIVE_CRYPTO_CNG)
418 #ifdef BCRYPT_HASH_INTERFACE_MAJORVERSION_2
419 return "2.0";
420 #else
421 return "1.0";
422 #endif
423 #else
424 return NULL;
425 #endif
426 }
427
428 const char *
archive_wincrypt_version(void)429 archive_wincrypt_version(void)
430 {
431 return NULL;
432 }
433
434 const char *
archive_librichacl_version(void)435 archive_librichacl_version(void)
436 {
437 #if HAVE_LIBRICHACL
438 #if defined(LIBRICHACL_PKGCONFIG_VERSION)
439 return LIBRICHACL_PKGCONFIG_VERSION;
440 #else
441 return "system";
442 #endif
443 #else
444 return NULL;
445 #endif
446 }
447
448 const char *
archive_libacl_version(void)449 archive_libacl_version(void)
450 {
451 #if HAVE_LIBACL
452 #if defined(LIBACL_PKGCONFIG_VERSION)
453 return LIBACL_PKGCONFIG_VERSION;
454 #else
455 return "system";
456 #endif
457 #else
458 return NULL;
459 #endif
460 }
461
462 const char *
archive_libattr_version(void)463 archive_libattr_version(void)
464 {
465 #if HAVE_LIBATTR
466 #if defined(LIBATTR_PKGCONFIG_VERSION)
467 return LIBATTR_PKGCONFIG_VERSION;
468 #else
469 return "system";
470 #endif
471 #else
472 return NULL;
473 #endif
474 }
475
476 const char *
archive_libiconv_version(void)477 archive_libiconv_version(void)
478 {
479 #if HAVE_LIBCHARSET && HAVE_ICONV_H
480 char major = _libiconv_version >> 8;
481 char minor = _libiconv_version & 0xFF;
482 static char charset_version[6];
483 snprintf(charset_version, 6, "%hhd.%hhd", major, minor);
484 return charset_version;
485 #else
486 return NULL;
487 #endif
488 }
489
490 const char *
archive_libpcre_version(void)491 archive_libpcre_version(void)
492 {
493 #if HAVE_LIBPCREPOSIX && HAVE_PCRE_H
494 #define str(s) #s
495 #define NUMBER(x) str(x)
496 return NUMBER(PCRE_MAJOR) "." NUMBER(PCRE_MINOR);
497 #undef NUMBER
498 #undef str
499 #else
500 return NULL;
501 #endif
502 }
503
504 const char *
archive_libpcre2_version(void)505 archive_libpcre2_version(void)
506 {
507 #if HAVE_LIBPCRE2POSIX && HAVE_PCRE2_H
508 #define str(s) #s
509 #define NUMBER(x) str(x)
510 return NUMBER(PCRE2_MAJOR) "." NUMBER(PCRE2_MINOR);
511 #undef NUMBER
512 #undef str
513 #else
514 return NULL;
515 #endif
516 }
517