1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel (at) haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 23 #include "curl_setup.h" 24 25 #include <curl/curl.h> 26 #include "urldata.h" 27 #include "vtls/vtls.h" 28 #include "http2.h" 29 #include "curl_printf.h" 30 31 #ifdef USE_ARES 32 # if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ 33 (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) 34 # define CARES_STATICLIB 35 # endif 36 # include <ares.h> 37 #endif 38 39 #ifdef USE_LIBIDN2 40 #include <idn2.h> 41 #endif 42 43 #ifdef USE_LIBPSL 44 #include <libpsl.h> 45 #endif 46 47 #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) 48 #include <iconv.h> 49 #endif 50 51 #ifdef USE_LIBRTMP 52 #include <librtmp/rtmp.h> 53 #endif 54 55 #ifdef USE_LIBSSH2 56 #include <libssh2.h> 57 #endif 58 59 #ifdef HAVE_LIBSSH2_VERSION 60 /* get it run-time if possible */ 61 #define CURL_LIBSSH2_VERSION libssh2_version(0) 62 #else 63 /* use build-time if run-time not possible */ 64 #define CURL_LIBSSH2_VERSION LIBSSH2_VERSION 65 #endif 66 67 void Curl_version_init(void); 68 69 /* For thread safety purposes this function is called by global_init so that 70 the static data in both version functions is initialized. */ 71 void Curl_version_init(void) 72 { 73 curl_version(); 74 curl_version_info(CURLVERSION_NOW); 75 } 76 77 char *curl_version(void) 78 { 79 static bool initialized; 80 static char version[200]; 81 char *ptr = version; 82 size_t len; 83 size_t left = sizeof(version); 84 85 if(initialized) 86 return version; 87 88 strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION); 89 len = strlen(ptr); 90 left -= len; 91 ptr += len; 92 93 if(left > 1) { 94 len = Curl_ssl_version(ptr + 1, left - 1); 95 96 if(len > 0) { 97 *ptr = ' '; 98 left -= ++len; 99 ptr += len; 100 } 101 } 102 103 #ifdef HAVE_LIBZ 104 len = snprintf(ptr, left, " zlib/%s", zlibVersion()); 105 left -= len; 106 ptr += len; 107 #endif 108 #ifdef USE_ARES 109 /* this function is only present in c-ares, not in the original ares */ 110 len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL)); 111 left -= len; 112 ptr += len; 113 #endif 114 #ifdef USE_LIBIDN2 115 if(idn2_check_version(IDN2_VERSION)) { 116 len = snprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL)); 117 left -= len; 118 ptr += len; 119 } 120 #endif 121 #ifdef USE_LIBPSL 122 len = snprintf(ptr, left, " libpsl/%s", psl_get_version()); 123 left -= len; 124 ptr += len; 125 #endif 126 #ifdef USE_WIN32_IDN 127 len = snprintf(ptr, left, " WinIDN"); 128 left -= len; 129 ptr += len; 130 #endif 131 #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) 132 #ifdef _LIBICONV_VERSION 133 len = snprintf(ptr, left, " iconv/%d.%d", 134 _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255); 135 #else 136 /* version unknown */ 137 len = snprintf(ptr, left, " iconv"); 138 #endif /* _LIBICONV_VERSION */ 139 left -= len; 140 ptr += len; 141 #endif 142 #ifdef USE_LIBSSH2 143 len = snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION); 144 left -= len; 145 ptr += len; 146 #endif 147 #ifdef USE_NGHTTP2 148 len = Curl_http2_ver(ptr, left); 149 left -= len; 150 ptr += len; 151 #endif 152 #ifdef USE_LIBRTMP 153 { 154 char suff[2]; 155 if(RTMP_LIB_VERSION & 0xff) { 156 suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1; 157 suff[1] = '\0'; 158 } 159 else 160 suff[0] = '\0'; 161 162 snprintf(ptr, left, " librtmp/%d.%d%s", 163 RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff, 164 suff); 165 /* 166 If another lib version is added below this one, this code would 167 also have to do: 168 169 len = what snprintf() returned 170 171 left -= len; 172 ptr += len; 173 */ 174 } 175 #endif 176 177 initialized = true; 178 return version; 179 } 180 181 /* data for curl_version_info 182 183 Keep the list sorted alphabetically. It is also written so that each 184 protocol line has its own #if line to make things easier on the eye. 185 */ 186 187 static const char * const protocols[] = { 188 #ifndef CURL_DISABLE_DICT 189 "dict", 190 #endif 191 #ifndef CURL_DISABLE_FILE 192 "file", 193 #endif 194 #ifndef CURL_DISABLE_FTP 195 "ftp", 196 #endif 197 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) 198 "ftps", 199 #endif 200 #ifndef CURL_DISABLE_GOPHER 201 "gopher", 202 #endif 203 #ifndef CURL_DISABLE_HTTP 204 "http", 205 #endif 206 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) 207 "https", 208 #endif 209 #ifndef CURL_DISABLE_IMAP 210 "imap", 211 #endif 212 #if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP) 213 "imaps", 214 #endif 215 #ifndef CURL_DISABLE_LDAP 216 "ldap", 217 #if !defined(CURL_DISABLE_LDAPS) && \ 218 ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ 219 (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) 220 "ldaps", 221 #endif 222 #endif 223 #ifndef CURL_DISABLE_POP3 224 "pop3", 225 #endif 226 #if defined(USE_SSL) && !defined(CURL_DISABLE_POP3) 227 "pop3s", 228 #endif 229 #ifdef USE_LIBRTMP 230 "rtmp", 231 #endif 232 #ifndef CURL_DISABLE_RTSP 233 "rtsp", 234 #endif 235 #ifdef USE_LIBSSH2 236 "scp", 237 #endif 238 #ifdef USE_LIBSSH2 239 "sftp", 240 #endif 241 #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ 242 (CURL_SIZEOF_CURL_OFF_T > 4) && \ 243 (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)) 244 "smb", 245 # ifdef USE_SSL 246 "smbs", 247 # endif 248 #endif 249 #ifndef CURL_DISABLE_SMTP 250 "smtp", 251 #endif 252 #if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP) 253 "smtps", 254 #endif 255 #ifndef CURL_DISABLE_TELNET 256 "telnet", 257 #endif 258 #ifndef CURL_DISABLE_TFTP 259 "tftp", 260 #endif 261 262 NULL 263 }; 264 265 static curl_version_info_data version_info = { 266 CURLVERSION_NOW, 267 LIBCURL_VERSION, 268 LIBCURL_VERSION_NUM, 269 OS, /* as found by configure or set by hand at build-time */ 270 0 /* features is 0 by default */ 271 #ifdef ENABLE_IPV6 272 | CURL_VERSION_IPV6 273 #endif 274 #ifdef USE_SSL 275 | CURL_VERSION_SSL 276 #endif 277 #ifdef USE_NTLM 278 | CURL_VERSION_NTLM 279 #endif 280 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ 281 defined(NTLM_WB_ENABLED) 282 | CURL_VERSION_NTLM_WB 283 #endif 284 #ifdef USE_SPNEGO 285 | CURL_VERSION_SPNEGO 286 #endif 287 #ifdef USE_KERBEROS5 288 | CURL_VERSION_KERBEROS5 289 #endif 290 #ifdef HAVE_GSSAPI 291 | CURL_VERSION_GSSAPI 292 #endif 293 #ifdef USE_WINDOWS_SSPI 294 | CURL_VERSION_SSPI 295 #endif 296 #ifdef HAVE_LIBZ 297 | CURL_VERSION_LIBZ 298 #endif 299 #ifdef DEBUGBUILD 300 | CURL_VERSION_DEBUG 301 #endif 302 #ifdef CURLDEBUG 303 | CURL_VERSION_CURLDEBUG 304 #endif 305 #ifdef CURLRES_ASYNCH 306 | CURL_VERSION_ASYNCHDNS 307 #endif 308 #if (CURL_SIZEOF_CURL_OFF_T > 4) && \ 309 ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) ) 310 | CURL_VERSION_LARGEFILE 311 #endif 312 #if defined(CURL_DOES_CONVERSIONS) 313 | CURL_VERSION_CONV 314 #endif 315 #if defined(USE_TLS_SRP) 316 | CURL_VERSION_TLSAUTH_SRP 317 #endif 318 #if defined(USE_NGHTTP2) 319 | CURL_VERSION_HTTP2 320 #endif 321 #if defined(USE_UNIX_SOCKETS) 322 | CURL_VERSION_UNIX_SOCKETS 323 #endif 324 #if defined(USE_LIBPSL) 325 | CURL_VERSION_PSL 326 #endif 327 , 328 NULL, /* ssl_version */ 329 0, /* ssl_version_num, this is kept at zero */ 330 NULL, /* zlib_version */ 331 protocols, 332 NULL, /* c-ares version */ 333 0, /* c-ares version numerical */ 334 NULL, /* libidn version */ 335 0, /* iconv version */ 336 NULL, /* ssh lib version */ 337 }; 338 339 curl_version_info_data *curl_version_info(CURLversion stamp) 340 { 341 static bool initialized; 342 #ifdef USE_LIBSSH2 343 static char ssh_buffer[80]; 344 #endif 345 #ifdef USE_SSL 346 static char ssl_buffer[80]; 347 #endif 348 349 if(initialized) 350 return &version_info; 351 352 #ifdef USE_SSL 353 Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer)); 354 version_info.ssl_version = ssl_buffer; 355 #endif 356 357 #ifdef HAVE_LIBZ 358 version_info.libz_version = zlibVersion(); 359 /* libz left NULL if non-existing */ 360 #endif 361 #ifdef USE_ARES 362 { 363 int aresnum; 364 version_info.ares = ares_version(&aresnum); 365 version_info.ares_num = aresnum; 366 } 367 #endif 368 #ifdef USE_LIBIDN2 369 /* This returns a version string if we use the given version or later, 370 otherwise it returns NULL */ 371 version_info.libidn = idn2_check_version(IDN2_VERSION); 372 if(version_info.libidn) 373 version_info.features |= CURL_VERSION_IDN; 374 #elif defined(USE_WIN32_IDN) 375 version_info.features |= CURL_VERSION_IDN; 376 #endif 377 378 #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) 379 #ifdef _LIBICONV_VERSION 380 version_info.iconv_ver_num = _LIBICONV_VERSION; 381 #else 382 /* version unknown */ 383 version_info.iconv_ver_num = -1; 384 #endif /* _LIBICONV_VERSION */ 385 #endif 386 387 #ifdef USE_LIBSSH2 388 snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION); 389 version_info.libssh_version = ssh_buffer; 390 #endif 391 392 (void)stamp; /* avoid compiler warnings, we don't use this */ 393 394 initialized = true; 395 return &version_info; 396 } 397