1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2007 Christian Grothoff 4 5 libmicrohttpd is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation; either version 2, or (at your 8 option) any later version. 9 10 libmicrohttpd is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with libmicrohttpd; see the file COPYING. If not, write to the 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Boston, MA 02111-1307, USA. 19 */ 20 21 /** 22 * @file curl_version_check.c 23 * @brief verify required cURL version is available to run tests 24 * @author Sagie Amir 25 */ 26 27 #include "MHD_config.h" 28 #include "platform.h" 29 #include <curl/curl.h> 30 31 #ifndef WINDOWS 32 #include <unistd.h> 33 #endif 34 35 static int 36 parse_version_number (const char **s) 37 { 38 int i = 0; 39 char num[17]; 40 41 while (i < 16 && ((**s >= '0') & (**s <= '9'))) 42 { 43 num[i] = **s; 44 (*s)++; 45 i++; 46 } 47 48 num[i] = '\0'; 49 50 return atoi (num); 51 } 52 53 const char * 54 parse_version_string (const char *s, int *major, int *minor, int *micro) 55 { 56 if (!s) 57 return NULL; 58 *major = parse_version_number (&s); 59 if (*s != '.') 60 return NULL; 61 s++; 62 *minor = parse_version_number (&s); 63 if (*s != '.') 64 return NULL; 65 s++; 66 *micro = parse_version_number (&s); 67 return s; 68 } 69 70 #if HTTPS_SUPPORT 71 int 72 curl_uses_nss_ssl() 73 { 74 return (strstr(curl_version(), " NSS/") != NULL) ? 0 : -1; 75 } 76 #endif 77 78 /* 79 * check local libcurl version matches required version 80 */ 81 int 82 curl_check_version (const char *req_version) 83 { 84 const char *ver; 85 const char *curl_ver; 86 #if HTTPS_SUPPORT 87 const char *ssl_ver; 88 const char *req_ssl_ver; 89 #endif 90 91 int loc_major, loc_minor, loc_micro; 92 int rq_major, rq_minor, rq_micro; 93 94 ver = curl_version (); 95 #if HAVE_MESSAGES 96 fprintf (stderr, "curl version: %s\n", ver); 97 #endif 98 /* 99 * this call relies on the cURL string to be of the exact following format : 100 * 'libcurl/7.16.4 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/0.6.5' OR 101 * 'libcurl/7.18.2 GnuTLS/2.4.0 zlib/1.2.3.3 libidn/0.6.5' 102 */ 103 curl_ver = strchr (ver, '/'); 104 if (curl_ver == NULL) 105 return -1; 106 curl_ver++; 107 /* Parse version numbers */ 108 if ( (NULL == parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro)) || 109 (NULL == parse_version_string (curl_ver, &loc_major, &loc_minor, &loc_micro)) ) 110 return -1; 111 112 /* Compare version numbers. */ 113 if ((loc_major > rq_major 114 || (loc_major == rq_major && loc_minor > rq_minor) 115 || (loc_major == rq_major && loc_minor == rq_minor 116 && loc_micro > rq_micro) || (loc_major == rq_major 117 && loc_minor == rq_minor 118 && loc_micro == rq_micro)) == 0) 119 { 120 fprintf (stderr, 121 "Error: running curl test depends on local libcurl version > %s\n", 122 req_version); 123 return -1; 124 } 125 126 /* 127 * enforce required gnutls/openssl version. 128 * TODO use curl version string to assert use of gnutls 129 */ 130 #if HTTPS_SUPPORT 131 ssl_ver = strchr (curl_ver, ' '); 132 if (ssl_ver == NULL) 133 return -1; 134 ssl_ver++; 135 if (strncmp ("GnuTLS", ssl_ver, strlen ("GNUtls")) == 0) 136 { 137 ssl_ver = strchr (ssl_ver, '/'); 138 req_ssl_ver = MHD_REQ_CURL_GNUTLS_VERSION; 139 } 140 else if (strncmp ("OpenSSL", ssl_ver, strlen ("OpenSSL")) == 0) 141 { 142 ssl_ver = strchr (ssl_ver, '/'); 143 req_ssl_ver = MHD_REQ_CURL_OPENSSL_VERSION; 144 } 145 else if (strncmp ("NSS", ssl_ver, strlen ("NSS")) == 0) 146 { 147 ssl_ver = strchr (ssl_ver, '/'); 148 req_ssl_ver = MHD_REQ_CURL_NSS_VERSION; 149 } 150 else 151 { 152 fprintf (stderr, "Error: unrecognized curl ssl library\n"); 153 return -1; 154 } 155 if (ssl_ver == NULL) 156 return -1; 157 ssl_ver++; 158 if ( (NULL == parse_version_string (req_ssl_ver, &rq_major, &rq_minor, &rq_micro)) || 159 (NULL == parse_version_string (ssl_ver, &loc_major, &loc_minor, &loc_micro)) ) 160 return -1; 161 162 if ((loc_major > rq_major 163 || (loc_major == rq_major && loc_minor > rq_minor) 164 || (loc_major == rq_major && loc_minor == rq_minor 165 && loc_micro > rq_micro) || (loc_major == rq_major 166 && loc_minor == rq_minor 167 && loc_micro == rq_micro)) == 0) 168 { 169 fprintf (stderr, 170 "Error: running curl test depends on local libcurl SSL version > %s\n", 171 req_ssl_ver); 172 return -1; 173 } 174 #endif 175 return 0; 176 } 177