Skip to content

Commit 313121a

Browse files
Use proper CURLOPT values for VERIFYHOST and VERIFYPEER
re: #1684 re: e-support VZL-904142 Two issues: 1. As of libcurl 7.66, the semantics of CURLOPT_SSL_VERIFYHOST changed so that the non-zero values affects certificate processing. 2. The current library was forcing the values of VERIFYPEER and VERIFYHOST to zero instead of leaving them to the default values. Solution was first to leave the defaults in place for VERIFYPEER and VERIFYHOST as long as they are not set in .ocrc/.dodsrc file. Second, the value of HTTP.SSL.VERIFYPEER or HTTP.SSL.VERIFYHOST as set in .ocrc/.dodrc is used to set the corresponding CURLOPT flags. So for example, adding > HTTP.SSL.VERIFYHOST=2 will set the value of CURLOPT_SSL_VERIFYHOST to 2, the default. Using > HTTP.SSL.VERIFYHOST=0 will set the value of CURLOPT_SSL_VERIFYHOST to 0, which disables it. Similarly for VERIFYPEER. Finally the semantics of HTTP.SSL.VALIDATE is now equivalent to > HTTP.SSL.VERIFYPEER=1 > HTTP.SSL.VERIFYHOST=2
1 parent 5a7cf26 commit 313121a

File tree

9 files changed

+91
-27
lines changed

9 files changed

+91
-27
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,13 @@ CHECK_C_SOURCE_COMPILES("
836836
#include <curl/curl.h>
837837
int main() {int x = CURLOPT_TCP_KEEPALIVE;}" HAVE_CURLOPT_KEEPALIVE)
838838

839+
# Check to see if we have libcurl 7.66 or later
840+
CHECK_C_SOURCE_COMPILES("
841+
#include <curl/curl.h>
842+
#if (LIBCURL_VERSION_MAJOR*1000 + LIBCURL_VERSION_MINOR >= 7066)
843+
choke me
844+
#endif" HAVE_LIBCURL_766)
845+
839846
# Option to Build DAP2+DAP4 Clients
840847
OPTION(ENABLE_DAP "Enable DAP2 and DAP4 Client." ON)
841848
IF(ENABLE_DAP)

NUG/DAP2.dox

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,17 @@ follows.
619619
Type: String representing directory
620620
Description: Path to a directory containing trusted certificates for validating server certificates.
621621
Related CURL Flags: CURLOPT_CAPATH
622+
1. HTTP.SSL.VERIFYPEER
623+
Type: integer
624+
Description: Set certificate checking on the server.
625+
Related CURL Flags: CURLOPT_SSL_VERIFYHOST
626+
1. HTTP.SSL.VERIFYPEER
627+
Type: integer
628+
Description: Set host validation for the server.
629+
Related CURL Flags: CURLOPT_SSL_VERIFYPEER
622630
1. HTTP.SSL.VALIDATE
623631
Type: boolean ("1"/"0")
624-
Description: Cause the client to verify the server's presented certificate.
632+
Description: Alias for VERIFYPEER=1 and VERIFYHOST=2
625633
Related CURL Flags: CURLOPT_SSL_VERIFYPEER, CURLOPT_SSL_VERIFYHOST
626634
1. HTTP.TIMEOUT
627635
Type: String ("dddddd")

NUG/DAP4.dox

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,16 @@ follows.
198198
Description: Path to a directory containing trusted certificates for validating server certificates.
199199
Related CURL Flags: CURLOPT_CAPATH
200200

201+
-# HTTP.SSL.VERIFYPEER
202+
Type: integer
203+
Description: Set certificate checking on the server.
204+
Related CURL Flags: CURLOPT_SSL_VERIFYHOST
205+
206+
-# HTTP.SSL.VERIFYPEER
207+
Type: integer
208+
Description: Set host validation for the server.
209+
Related CURL Flags: CURLOPT_SSL_VERIFYPEER
210+
201211
-# HTTP.SSL.VALIDATE
202212
Type: boolean ("1"/"0")
203213
Description: Cause the client to verify the server's presented certificate.

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This file contains a high-level description of this package's evolution. Release
77

88
## 4.8.0 - TBD
99

10+
* [Bug Fix] Use proper CURLOPT values for VERIFYHOST and VERIFYPEER; the semantics for VERIFYHOST in particular changed. Documented in NUG/DAP2.md. See [https://github.com/Unidata/netcdf-c/issues/1684].
1011
* [Bug Fix][cmake] Correct an issue with parallel filter test logic in CMake-based builds.
1112
* [Bug Fix] Now allow nc_inq_var_deflate()/nc_inq_var_szip() to be called for all formats, not just HDF5. Non-HDF5 files return NC_NOERR and report no compression in use. This reverts behavior that was changed in the 4.7.4 release. See [https://github.com/Unidata/netcdf-c/issues/1691].
1213
* [Bug Fix] Compiling on a big-endian machine exposes some missing forward delcarations in dfilter.c.

config.h.cmake.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ are set when opening a binary file on Windows. */
178178
/* Is CURLOPT_USERNAME defined */
179179
#cmakedefine HAVE_CURLOPT_USERNAME 1
180180

181+
/* Is LIBCURL version >= 7.66 */
182+
#cmakedefine HAVE_LIBCURL_766 1
183+
181184
/* Define to 1 if you have the declaration of `isfinite', and to 0 if you
182185
don't. */
183186
#cmakedefine HAVE_DECL_ISFINITE 1

configure.ac

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,20 @@ AC_MSG_RESULT([${havecurloption}])
750750
if test $havecurloption = yes; then
751751
AC_DEFINE([HAVE_CURLOPT_KEEPALIVE],[1],[Is CURLOPT_TCP_KEEPALIVE defined])
752752
fi
753+
# CURLOPT_VERIFYHOST semantics differ depending on version
754+
AC_MSG_CHECKING([whether libcurl is version 7.66 or later?])
755+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
756+
[#include "curl/curl.h"],
757+
[[
758+
#if LIBCURL_VERSION_NUM < 0x074200
759+
error "<7.66";
760+
#endif
761+
]])], [libcurl766=yes], [libcurl766=no])
762+
763+
AC_MSG_RESULT([$libcurl766])
764+
if test x$libcurl66 = xno; then
765+
AC_DEFINE([HAVE_LIBCURL_766],[1],[Is libcurl version 7.66 or later])
766+
fi
753767

754768
CFLAGS="$SAVECFLAGS"
755769

libdap4/d4curlfunctions.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,15 @@ set_curlflag(NCD4INFO* state, int flag)
133133
case CURLOPT_SSL_VERIFYPEER: case CURLOPT_SSL_VERIFYHOST:
134134
{
135135
struct ssl* ssl = &state->auth.ssl;
136-
CHECK(state, CURLOPT_SSL_VERIFYPEER, (OPTARG)(ssl->verifypeer?1L:0L));
137-
CHECK(state, CURLOPT_SSL_VERIFYHOST, (OPTARG)(ssl->verifyhost?1L:0L));
136+
/* VERIFYPEER == 0 => VERIFYHOST == 0 */
137+
/* We need to have 2 states: default and a set value */
138+
/* So -1 => default, >= 0 => use value; */
139+
if(ssl->verifypeer >= 0)
140+
CHECK(state, CURLOPT_SSL_VERIFYPEER, (OPTARG)(ssl->verifypeer));
141+
#ifdef HAVE_LIBCURL_766
142+
if(ssl->verifyhost >= 0)
143+
CHECK(state, CURLOPT_SSL_VERIFYHOST, (OPTARG)(ssl->verifyhost));
144+
#endif
138145
if(ssl->certificate)
139146
CHECK(state, CURLOPT_SSLCERT, ssl->certificate);
140147
if(ssl->key)

libdispatch/dauth.c

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ See COPYRIGHT for license information.
3030

3131
/* Define the curl flag defaults in envv style */
3232
static const char* AUTHDEFAULTS[] = {
33+
"HTTP.SSL.VERIFYPEER","-1", /* Use default */
34+
"HTTP.SSL.VERIFYHOST","-1", /* Use default */
3335
"HTTP.TIMEOUT","1800", /*seconds */ /* Long but not infinite */
3436
"HTTP.CONNECTTIMEOUT","50", /*seconds */ /* Long but not infinite */
3537
NULL
@@ -124,8 +126,6 @@ NC_authsetup(NCauth* auth, NCURI* uri)
124126
NC_rclookup("HTTP.PROXY.SERVER",uri_hostport));
125127
setauthfield(auth,"HTTP.PROXY_SERVER",
126128
NC_rclookup("HTTP.PROXY_SERVER",uri_hostport));
127-
setauthfield(auth,"HTTP.SSL.VALIDATE",
128-
NC_rclookup("HTTP.SSL.VALIDATE",uri_hostport));
129129
setauthfield(auth,"HTTP.SSL.CERTIFICATE",
130130
NC_rclookup("HTTP.SSL.CERTIFICATE",uri_hostport));
131131
setauthfield(auth,"HTTP.SSL.KEY",
@@ -138,6 +138,11 @@ NC_authsetup(NCauth* auth, NCURI* uri)
138138
NC_rclookup("HTTP.SSL.CAPATH",uri_hostport));
139139
setauthfield(auth,"HTTP.SSL.VERIFYPEER",
140140
NC_rclookup("HTTP.SSL.VERIFYPEER",uri_hostport));
141+
setauthfield(auth,"HTTP.SSL.VERIFYHOST",
142+
NC_rclookup("HTTP.SSL.VERIFYHOST",uri_hostport));
143+
/* Alias for VERIFYHOST + VERIFYPEER */
144+
setauthfield(auth,"HTTP.SSL.VALIDATE",
145+
NC_rclookup("HTTP.SSL.VALIDATE",uri_hostport));
141146
setauthfield(auth,"HTTP.NETRC",
142147
NC_rclookup("HTTP.NETRC",uri_hostport));
143148

@@ -255,13 +260,28 @@ setauthfield(NCauth* auth, const char* flag, const char* value)
255260
nclog(NCLOGNOTE,"HTTP.PROXY.SERVER: %s", value);
256261
#endif
257262
}
263+
if(strcmp(flag,"HTTP.SSL.VERIFYPEER")==0) {
264+
int v;
265+
if((v = atol(value))) {
266+
auth->ssl.verifypeer = v;
267+
#ifdef D4DEBUG
268+
nclog(NCLOGNOTE,"HTTP.SSL.VERIFYPEER: %d", v);
269+
#endif
270+
}
271+
}
272+
if(strcmp(flag,"HTTP.SSL.VERIFYHOST")==0) {
273+
int v;
274+
if((v = atol(value))) {
275+
auth->ssl.verifyhost = v;
276+
#ifdef D4DEBUG
277+
nclog(NCLOGNOTE,"HTTP.SSL.VERIFYHOST: %d", v);
278+
#endif
279+
}
280+
}
258281
if(strcmp(flag,"HTTP.SSL.VALIDATE")==0) {
259282
if(atoi(value)) {
260283
auth->ssl.verifypeer = 1;
261-
auth->ssl.verifyhost = 1;
262-
#ifdef D4DEBUG
263-
nclog(NCLOGNOTE,"HTTP.SSL.VALIDATE: %ld", 1);
264-
#endif
284+
auth->ssl.verifyhost = 2;
265285
}
266286
}
267287

@@ -309,22 +329,6 @@ setauthfield(NCauth* auth, const char* flag, const char* value)
309329
nclog(NCLOGNOTE,"HTTP.SSL.CAPATH: %s", auth->ssl.capath);
310330
#endif
311331
}
312-
313-
if(strcmp(flag,"HTTP.SSL.VERIFYPEER")==0) {
314-
const char* s = value;
315-
int tf = 0;
316-
if(s == NULL || strcmp(s,"0")==0 || strcasecmp(s,"false")==0)
317-
tf = 0;
318-
else if(strcmp(s,"1")==0 || strcasecmp(s,"true")==0)
319-
tf = 1;
320-
else
321-
tf = 1; /* default if not null */
322-
auth->ssl.verifypeer = tf;
323-
#ifdef D4DEBUG
324-
nclog(NCLOGNOTE,"HTTP.SSL.VERIFYPEER: %d", auth->ssl.verifypeer);
325-
#endif
326-
}
327-
328332
if(strcmp(flag,"HTTP.NETRC")==0) {
329333
nullfree(auth->curlflags.netrc);
330334
auth->curlflags.netrc = strdup(value);

oc2/occurlfunctions.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,17 @@ ocset_curlflag(OCstate* state, int flag)
131131
case CURLOPT_SSL_VERIFYPEER: case CURLOPT_SSL_VERIFYHOST:
132132
{
133133
struct ssl* ssl = &state->auth.ssl;
134-
CHECK(state, CURLOPT_SSL_VERIFYPEER, (OPTARG)(ssl->verifypeer?1L:0L));
135-
CHECK(state, CURLOPT_SSL_VERIFYHOST, (OPTARG)(ssl->verifyhost?1L:0L));
134+
/* VERIFYPEER == 0 => VERIFYHOST == 0 */
135+
/* We need to have 2 states: default and a set value */
136+
/* So -1 => default >= 0 => use value */
137+
if(ssl->verifypeer >= 0) {
138+
CHECK(state, CURLOPT_SSL_VERIFYPEER, (OPTARG)(ssl->verifypeer));
139+
}
140+
#ifdef HAVE_LIBCURL_766
141+
if(ssl->verifyhost >= 0) {
142+
CHECK(state, CURLOPT_SSL_VERIFYHOST, (OPTARG)(ssl->verifyhost));
143+
}
144+
#endif
136145
if(ssl->certificate)
137146
CHECK(state, CURLOPT_SSLCERT, ssl->certificate);
138147
if(ssl->key)
@@ -213,6 +222,7 @@ ocset_flags_perlink(OCstate* state)
213222
if(stat == NC_NOERR && state->curlkeepalive.active != 0)
214223
stat = ocset_curlflag(state, CURLOPT_TCP_KEEPALIVE);
215224
#endif
225+
216226
return stat;
217227
}
218228

0 commit comments

Comments
 (0)